Auto assign arguments?

I see where to put bugs and patches, but this is a feature request. Is
this the right place to submit these?

In any case, here's a feature request:

I find that I do a lot of this:

def initialize(thing, other)
  @thing = thing
  @other = other
end

One thing I'd love to see in a future version of ruby is this;

def initialize(@thing, @other)
end

... and have that automagically initialize @thing and @other with the
submitted values.

Thanks,
David

Well, you can get pretty close...

def initialize(*a)
   @thing, @other = *a
end

You don't get method arity checking that way but...

def initialize(a,b)
   @thing, @other = a,b
end

isn't too bad either.

As for as official change requests see: http://rcrchive.net/

Gary Wright

···

On Jan 18, 2007, at 3:13 PM, David Chelimsky wrote:

One thing I'd love to see in a future version of ruby is this;

def initialize(@thing, @other)
end

David Chelimsky:

One thing I'd love to see in a future version of ruby is this;

def initialize(@thing, @other)
end

Try the following. Note that it does not actually set @thing and @other
- they are only accessible methodically - but gives you an appropriate
#initialize.

Klass = Struct.new(:thing, :other)
class Klass

  # more

end

Kalman

Some thinking-out-loud:

#!/usr/bin/env ruby -w

class Module
   def constructor(*attrs)
     define_method(:initialize) do |*passed|
       raise ArgumentError, "Wrong number of arguments" \
         unless attrs.size == passed.size

       attrs.each_with_index do |att, i|
         instance_variable_set("@#{att}", passed[i])
       end

       after_initialize if respond_to? :after_initialize
     end
   end
end

class ABC
   constructor :a, :b, :c

   def after_initialize
     p instance_variables.map { |var| [var, instance_variable_get(var)] }.sort
   end
end

ABC.new(1, :two, "three")
ABC.new(*%w[testing my code])
# >> [["@a", 1], ["@b", :two], ["@c", "three"]]
# >> [["@a", "testing"], ["@b", "my"], ["@c", "code"]]

__END__

James Edward Gray II

···

On Jan 18, 2007, at 2:13 PM, David Chelimsky wrote:

I see where to put bugs and patches, but this is a feature request. Is
this the right place to submit these?

In any case, here's a feature request:

I find that I do a lot of this:

def initialize(thing, other)
@thing = thing
@other = other
end

One thing I'd love to see in a future version of ruby is this;

def initialize(@thing, @other)
end

... and have that automagically initialize @thing and @other with the
submitted values.

David Chelimsky schrieb:

I find that I do a lot of this:

def initialize(thing, other)
@thing = thing
@other = other
end

One thing I'd love to see in a future version of ruby is this;

def initialize(@thing, @other)
end

Not that I would do it, but:

   class C
     define_method :initialize do |@x, @y|
     end
   end

   c = C.new 1, 2
   p c # => #<C:0x2aeabd0 @y=2, @x=1>

I think Matz is planning to deprecate this feature.

Regards,
Pit

David Chelimsky wrote:

I see where to put bugs and patches, but this is a feature request. Is
this the right place to submit these?

In any case, here's a feature request:

I find that I do a lot of this:

def initialize(thing, other)
  @thing = thing
  @other = other
end

One thing I'd love to see in a future version of ruby is this;

def initialize(@thing, @other)
end

.. and have that automagically initialize @thing and @other with the
submitted values.

I could have sworn Paul Brannan did this as part of RubyTreasures, but
I don't see any such thing mentioned in the docs. I know it's been
done somewhere as a language hack.

Personally, I think it ought to be the default behavior, since it's
what you want about 80% of the time in practice I think. At worst,
you've got a couple of useless instance variables that people would
have to go to pains to get at via instance_variable_get. Heck, why not
take this a step further and create automatic getters and setters? You
can always undef or redefine them.

Regards,

Dan

harp:~ > cat a.rb
   require 'rubygems'
   require 'attributes'

   class C
     attributes %w( a b c )

     def initialize *argv
       self.class.attributes.zip(argv){|a,v| send a, v}
     end
   end

   p(C.new(0,1,2))

   harp:~ > ruby a.rb
#<C:0xb74c1b44 @c=2, @b=1, @a=0>

-a

···

On Fri, 19 Jan 2007, Pit Capitain wrote:

David Chelimsky schrieb:

I find that I do a lot of this:

def initialize(thing, other)
@thing = thing
@other = other
end

One thing I'd love to see in a future version of ruby is this;

def initialize(@thing, @other)
end

Not that I would do it, but:

class C
   define_method :initialize do |@x, @y|
   end
end

c = C.new 1, 2
p c # => #<C:0x2aeabd0 @y=2, @x=1>

I think Matz is planning to deprecate this feature.

Regards,
Pit

--
in the practice of tolerance, one's enemy is the best teacher.
- the dalai lama

I would really be against that. If you do that, there's no point in how Ruby currently has all instance data as private. It blows encapsulation wide open and being very against the spirit of OO just doesn't feel Rubyish to me.

James Edward Gray II

···

On Jan 18, 2007, at 3:35 PM, Daniel Berger wrote:

Heck, why not
take this a step further and create automatic getters and setters? You
can always undef or redefine them.

You can even do

Klass = Struct.new :foo, :bar do
   def some_method
   end
end

which I find pretty nice. :slight_smile:

  robert

···

On 18.01.2007 21:25, Kalman Noel wrote:

David Chelimsky:

One thing I'd love to see in a future version of ruby is this;

def initialize(@thing, @other)
end

Try the following. Note that it does not actually set @thing and @other
- they are only accessible methodically - but gives you an appropriate
#initialize.

Klass = Struct.new(:thing, :other)
class Klass

  # more

end

Thanks for all the responses, but I'm really looking for something
that feels simple and explicit (these suggestions all feel a little
magical and confusing).

Do any of you think this would be a good or bad thing to add to the
language? I'd like to post an RCR, but the RCRchive warns against
poorly researched requests - so I'd like to do some research :wink: My
feeling is that my proposal would add a very simple and explicit means
of assigning those args that you wish to assign. What's yours?

Thanks,
David

···

On 1/18/07, ara.t.howard@noaa.gov <ara.t.howard@noaa.gov> wrote:

On Fri, 19 Jan 2007, Pit Capitain wrote:

> David Chelimsky schrieb:
>> I find that I do a lot of this:
>>
>> def initialize(thing, other)
>> @thing = thing
>> @other = other
>> end
>>
>> One thing I'd love to see in a future version of ruby is this;
>>
>> def initialize(@thing, @other)
>> end
>
> Not that I would do it, but:
>
> class C
> define_method :initialize do |@x, @y|
> end
> end
>
> c = C.new 1, 2
> p c # => #<C:0x2aeabd0 @y=2, @x=1>
>
> I think Matz is planning to deprecate this feature.
>
> Regards,
> Pit

   harp:~ > cat a.rb
   require 'rubygems'
   require 'attributes'

   class C
     attributes %w( a b c )

     def initialize *argv
       self.class.attributes.zip(argv){|a,v| send a, v}
     end
   end

   p(C.new(0,1,2))

   harp:~ > ruby a.rb
#<C:0xb74c1b44 @c=2, @b=1, @a=0>

+1,

BUT... it's be okay if you could build this as a module, I think.
Then you could just include it in a class to get the behavior when it
is appropriate.

···

On 1/18/07, James Edward Gray II <james@grayproductions.net> wrote:

I would really be against that. If you do that, there's no point in
how Ruby currently has all instance data as private. It blows
encapsulation wide open and being very against the spirit of OO just
doesn't feel Rubyish to me.

James Edward Gray II wrote:

> Heck, why not
> take this a step further and create automatic getters and setters? You
> can always undef or redefine them.

I would really be against that. If you do that, there's no point in
how Ruby currently has all instance data as private. It blows
encapsulation wide open and being very against the spirit of OO just
doesn't feel Rubyish to me.

Hm, you're probably right.

I suppose it would require some fundamental changes to the language,
i.e. not allowing instance data to be set directly outside of the
constructor (forcing you to use the actual getter and setter methods
outside of the constructor). This is what Fortress does, and I think
it's what Perl 6 will do as well.

I'm not sure what the downside of that change would be, other than a
forced method lookup. I don't know enough about Ruby internals to know
if "@foo = 1" is cheaper than "foo = 1", but I'm guessing that it is.

Forgive me, for I have been tainted by the Fortress language recently.
:slight_smile:

Regards,

Dan

···

On Jan 18, 2007, at 3:35 PM, Daniel Berger wrote:

The code below uses instance_exec from ruby 1.9. It will still work
under ruby 1.8 as long as you don't give a block to the #init method.

Gary Wright

module Init
   def init(*syms, &iproc)
     define_method(:initialize) {|*x|
       raise ArgumentError, "wrong number of arguments: #{x.size} for #{syms.size}" if x.size != syms.size
       syms.zip(x).each { |sym, val|
         instance_variable_set("@#{sym}", val)
       }
       instance_exec(*x, &iproc) if iproc
     }
   end
end

class A
   extend Init
   init :a, :b, :c, :d
end

a = A.new(1,2,3,4)
p a.instance_variables # ["@b", "@a", "@c", "@d"]
a.instance_variables.each { |n|
   puts "#{n} = #{a.instance_variable_get(n)}"
}

class Object
   extend Init
end

class B
   attr :attr1, :attr2
   init :attr1, :attr2
end

b = B.new('foo', 'bar')
p b.attr1 # 'foo'
p b.attr2 # 'bar'

class C
   init :c, :d do
     puts "@c is #{@c}"
     puts "@d is #{@d}"
   end
end

C.new(3,4) # @c is 3
                   # @d is 4
begin
   C.new(5) # argument error
rescue
   p $!
end

···

On Jan 18, 2007, at 5:06 PM, Gregory Brown wrote:

BUT... it's be okay if you could build this as a module, I think.
Then you could just include it in a class to get the behavior when it
is appropriate.

Wow. You guys are all coming up w/ great alternatives, but would
somebody please just answer my question? I am not asking for ways to
do what I want. I'm asking if you think the following proposed syntax
addition would be useful:

Any parameter preceded by a @ results in an instance variable being
created and initialized with the submitted value. So:

class MyClass
  def initialize(@a)
  end
end

instance = MyClass.new(5)
#results in an instance variable @a with a value of 5

This would apply to any parameter in the list, including those with
default values.

MyClass
  def initialize(@a, @b=3)
  end
end

instance = MyClass.new(5)
#results in an instance @a = 5 and @b = 3

instance = MyClass.new(5, 4)
#results in an instance @a = 5 and @b = 4

Does this seem like a good thing to propose?

Thank you,
David

-1. I see @a and @b to be part of the classe's instance variables, so
this syntactic sugar.

···

On 1/18/07, David Chelimsky <dchelimsky@gmail.com> wrote:

Does this seem like a good thing to propose?

Any parameter preceded by a @ results in an instance variable being
created and initialized with the submitted value. So:

class MyClass
def initialize(@a)
end
end

instance = MyClass.new(5)
#results in an instance variable @a with a value of 5

As I recall, this was proposed on this list several years ago.

I think it generated a bit of discussion, with possibly even
some comments by Matz.

Sorry, I don't have a link to the thread in the archives,
though...

Regards,

Bill

···

From: "David Chelimsky" <dchelimsky@gmail.com>

Wow. You guys are all coming up w/ great alternatives, but would
somebody please just answer my question? I am not asking for ways to
do what I want. I'm asking if you think the following proposed syntax
addition would be useful:

Your idea is intriguing
you can already do

    proc{ |@a| }.call(42)

so why not allow instance methods as formal parameters for methods?
By no means such a construct should be reduced to #initialize it should be
legal for every method of course.
Now I am not qualified to talk about impacts or implementation details.
Given that so many people have already implemented this it seems a desired
features.
I would vote "in favour" maybe even "strongly in favour" for such a RCR. I
will listen to wiser guys before voting though.

Cheers
Robert

Any parameter preceded by a @ results in an instance variable being

created and initialized with the submitted value. So:

class MyClass
  def initialize(@a)
  end
end

instance = MyClass.new(5)
#results in an instance variable @a with a value of 5

This would apply to any parameter in the list, including those with
default values.

MyClass
  def initialize(@a, @b=3)
  end
end

instance = MyClass.new(5)
#results in an instance @a = 5 and @b = 3

instance = MyClass.new(5, 4)
#results in an instance @a = 5 and @b = 4

Does this seem like a good thing to propose?

See above for *any* method of course.

Thank you,

David

Cheers
Robert

···

On 1/19/07, David Chelimsky <dchelimsky@gmail.com> wrote:

--
"The best way to predict the future is to invent it."
- Alan Kay

Hi --

···

On Fri, 19 Jan 2007, David Chelimsky wrote:

Wow. You guys are all coming up w/ great alternatives, but would
somebody please just answer my question? I am not asking for ways to
do what I want. I'm asking if you think the following proposed syntax
addition would be useful:

Any parameter preceded by a @ results in an instance variable being
created and initialized with the submitted value. So:

class MyClass
def initialize(@a)
end

instance = MyClass.new(5)
#results in an instance variable @a with a value of 5

That was proposed as an RCR and rejected; see
http://oldrcrs.rubypal.com/rejected.html#rcr3

David

--
Q. What is THE Ruby book for Rails developers?
A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black\)
    (See what readers are saying! http://www.rubypal.com/r4rrevs.pdf\)
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)

<whoops>

This syntactic sugar would confuse me.

···

On 1/18/07, Gregory Brown <gregory.t.brown@gmail.com> wrote:

On 1/18/07, David Chelimsky <dchelimsky@gmail.com> wrote:

> Does this seem like a good thing to propose?

-1. I see @a and @b to be part of the classe's instance variables, so
this syntactic sugar.

Gregory Brown wrote:

Does this seem like a good thing to propose?

-1. I see @a and @b to be part of the classe's instance variables, so

Why the class' instance variables? That doesn't fit with the current pattern:

  class C
    def initialize(v = nil)
      @default = v
    end
    def otherdefault
      42
    end
    def ultimate(v = @default || otherdefault)
      v
    end
  end
  C.new.ultimate #=> 42
  C.new(54).ultimate #=> 54

If an object's instance variables (and even methods) can be used as default values, it would be coherent to also allow them in the argument list. This feels 100% instinctive to me.

+1

-dd

···

On 1/18/07, David Chelimsky <dchelimsky@gmail.com> wrote: