Feature #8563

Instance variable arguments

Added by Tsuyoshi Sawada 10 months ago. Updated 10 months ago.

[ruby-core:55596]
Status:Assigned
Priority:Normal
Assignee:Yukihiro Matsumoto
Category:syntax
Target version:Next Major

Description

=begin
Often times, people want to assign given arguments to instance variables, especially inside the method initialize:

def initialize foo, bar, buz
  @foo, @bar, @buz = foo, bar, buz
  ...
end

I propose to let method definition take instance variables as arguments so that:

def initialize @foo, @bar, @buz
  ...
end

would be equivalent as above.
=end


Related issues

Duplicates ruby-trunk - Feature #5825: Sweet instance var assignment in the object initializer Assigned

History

#1 Updated by Nobuyoshi Nakada 10 months ago

  • Category set to syntax
  • Status changed from Open to Assigned
  • Assignee set to Yukihiro Matsumoto
  • Target version set to Next Major

#2 Updated by Matthew Kerwin 10 months ago

=begin
Question: would this be valid?

def foo(@foo=@foo) end

Asking here, because #5825 as written only talks about initialize method, and the above construct wouldn't make sense there.
=end

#3 Updated by Yukihiro Matsumoto 10 months ago

From my POV:

def initialize(@foo, @bar)
end

does not express intention of instance variable initialization. I'd rather add a method like

defineattrinitialize(:foo, :bar)

to define a method of

def initialize(foo, bar)
@foo = foo
@bar = bar
end

Matz.

#4 Updated by Tsuyoshi Sawada 10 months ago

It could also be used besides initialize:

def update_something foo
   do_update_something(@foo = foo)
   ...
end

would become

def update_something @foo
   do_update_something(@foo)
   ...
end

#5 Updated by Nobuyoshi Nakada 10 months ago

=begin
: phluid61 (Matthew Kerwin) wrote:
Question: would this be valid?

def foo(@foo=@foo) end

In generic,

foo = foo

is valid always.
=end

#6 Updated by Charles Nutter 10 months ago

Worth pointing out that blocks used to support this:

1.times { |@foo| ... }

Basically, it supported anything you can have on the LHS of a normal assignment:

foo.bar { |a, @b, @@c, D, e.val, f[0]| ... }

I believe it was taken out in 1.9 because it made argument processing a lot more complicated, but then 1.9 added the ability to do multiple-assignment grouping, default values, and other masgn features to all argument lists anyway. It doesn't seem like it would be too terribly complicated to add this back in, but I wonder about the OTHER reasons that non-local variable assignment was removed from argument lists in the first place.

As for the utility of the feature, I'd like it but I can live without it. It does seem rather un-Ruby to have to declare locals and do the assignment when all you want is to set an instance variable...especially when you have a lot of instance variables.

Note also that for a trivial initialize, where the only line is a multiple-assignment to set instance variables, every initialize call pays the cost of creating an Array for the masgn (see my rejected request in https://bugs.ruby-lang.org/issues/6668).

def initialize(a, b, c, d, e)
@a, @b, @c, @d, @e = a, b, c, d, e # creates transient array every time
end

#7 Updated by Boris Stitnicky 10 months ago

@Matz: If define_attr_initialize is an option, then there is a question of named / ordered qualifier, either as:

define_attr_initialize :foo, :bar, as: :named
define_attr_initialize :baz, :quux, as: :ordered

or as (and I like this second option better):

attr_init_named foo: nil, bar: nil
attr_init_ordered :baz, :quux

Both of these would obviously stand for (using @sawa's notation):

def initialize( @baz, @quux, @foo: nil, @bar: nil )
  ...

Besides that, I feel that attr_reader, attr_writer, attr_accessor could use:

attr_reader :foo, :bar, init: :named
attr_reader :baz, :quux, init: :ordered

Which also brings to my mind, that now that we have named args firmly in place, following
syntactic flavors of Module#attr_... beg to exist:

attr_reader foo: 42, bar: 43  # specifying starting values explicitly

#8 Updated by Matthew Kerwin 10 months ago

boris_stitnicky (Boris Stitnicky) wrote:

Which also brings to my mind, that now that we have named args firmly in place, following
syntactic flavors of Module#attr_... beg to exist:

attr_reader foo: 42, bar: 43  # specifying starting values explicitly

If you propose this as a feature, I will +1 it. Also I have some questions about it which probably should not pollute the current feature request.

#9 Updated by Boris Stitnicky 10 months ago

If you propose this as a feature, I will +1 it. Also I have some questions about it which probably should not pollute the current feature request.

I have proposed is as #8564.

Also available in: Atom PDF