Auto assign arguments?


#1

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


#2

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

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

def initialize(@thing, @other)
end

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 W.


#3

David C. schrieb:

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


#4

On Fri, 19 Jan 2007, Pit C. wrote:

def initialize(@thing, @other)
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>

-a


#5

From: “David C.” removed_email_address@domain.invalid

#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


#6

Hi,

In message “Re: auto assign arguments?”
on Sat, 20 Jan 2007 01:58:06 +0900, “David C.”
removed_email_address@domain.invalid writes:

|Would you mind providing a brief explanation of your objection? There
|is no Reason for rejection with the old RCR
|(http://oldrcrs.rubypal.com/rejected.html#rcr3) and it would be
|helpful to me (and I’m sure others) to understand why you think this
|is a bad idea.

I thought (and I still think) it is a good idea to separate method
argument and assignment in general. It’s convention supported by most
languages, and mixing parameters and assignments gives me impression
of toy-language.

Besides that, I think formal arguments of a method (including their
names) can be seen as part of class API. Allowing instance variables
as formal arguments seems like disclosing the internal issues.

Finally, I admit that the code like this

def initialize(@length)
end

is longer than

def initialize(length)
@length = length
end

but I feel the intention of the latter code is far clearer than the
former.

          matz.

#7

On 1/20/07, David C. removed_email_address@domain.invalid wrote:

just would be a willful disclosure a little bit like
attr_writer :length

Thinking about this some more - I wasn’t proposing this become part of
the API. Nor would I want to see this anywhere besides the
initializer. The proposal is that for initializers (only) you could

Ah I see here we are really diverging. Are you aware that you propose
different formal parameter symantics based on
the method name?
OTOH #initialize is a special method of course. But I am against it,
would
make the language more complicated.

define (not reference pre-existing) instance variables:

def initialize(@length)
end

If this were allowed, there would be no need to expose the @ in RDoc.
RDoc could be tweaked to hide that, so you’d still just see:

Again I fail to agree :(.
If you exposed an instance variable like that would it not be desired
for
RDoc to document this?

new(length)

Note that RDoc is already hiding initialize (as an instance method)
and showing you new (as a class method), so this would just be an
addition to that transformation.

So the proposed sugar would only be exposed to the intialize method
and anybody (human or machine) reading the class definition.

David

Robert


#8

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

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.

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 G. II


#9

On 1/18/07, Gregory B. removed_email_address@domain.invalid wrote:

On 1/18/07, David C. removed_email_address@domain.invalid 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.

This syntactic sugar would confuse me.


#10

On 1/20/07, Robert D. removed_email_address@domain.invalid wrote:

Besides that, I think formal arguments of a method (including their

Thinking about this some more - I wasn’t proposing this become part of
the API. Nor would I want to see this anywhere besides the
initializer. The proposal is that for initializers (only) you could
define (not reference pre-existing) instance variables:

def initialize(@length)
end

If this were allowed, there would be no need to expose the @ in RDoc.
RDoc could be tweaked to hide that, so you’d still just see:

new(length)

Note that RDoc is already hiding initialize (as an instance method)
and showing you new (as a class method), so this would just be an
addition to that transformation.

So the proposed sugar would only be exposed to the intialize method
and anybody (human or machine) reading the class definition.

David


#11

On 1/18/07, David C. removed_email_address@domain.invalid 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.


#12

On 1/19/07, Yukihiro M. removed_email_address@domain.invalid wrote:

|I feel that this is worth another shot, maybe Matz could tell us to stop
|working on this if he really does not like it.
|It seems reasonable to assume that the reasons he had to reject the RCR do
|not exist anymore or that he has changed his mind, no?

I haven’t changed my mind (yet). And I even disallowed above code in
1.9. Block parameters should only be local variables (and they are
effective only inside the block).

Matz,

Thank you for weighing in on this discussion (and, this being the
first time I’ve addressed you directly, thanks for this beautiful
language).

Would you mind providing a brief explanation of your objection? There
is no Reason for rejection with the old RCR
(http://oldrcrs.rubypal.com/rejected.html#rcr3) and it would be
helpful to me (and I’m sure others) to understand why you think this
is a bad idea.

Cheers,
David


#13

On 1/20/07, Robert D. removed_email_address@domain.invalid wrote:

Sorry for replying to myself, but this stroke me too funny to resist:

Ah I see here we are really diverging. Are you aware that you propose

different formal parameter symantics based on
the method name?

Of course symantics was a stupid typo but actually it is the “correct”
word,
syntax and semantics would be different, amazing.

> Robert

#14

On 1/20/07, Yukihiro M. removed_email_address@domain.invalid wrote:

in Ruby, but too much implicit behavior makes our programs into
puzzles. It’s matter of balance.

Hear, hear!!!

I respectfully withdraw the suggestion.

Cheers,
David


#15

On Jan 18, 2007, at 3:35 PM, Daniel B. 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.

James Edward G. II


#16

removed_email_address@domain.invalid wrote:

created and initialized with the submitted value. So:
http://oldrcrs.rubypal.com/rejected.html#rcr3
Hm, no reason given, but one of the things I don’t like about it is the
change in syntax it required. With the advent of keyword parameters
(right?), and the ability to get the parameter names from within a
method, this should be trivial to implement on our own in 1.9 if Matz
doesn’t want it as the default behavior.

Dan


#17

James Edward G. II wrote:

On Jan 18, 2007, at 3:35 PM, Daniel B. 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


#18

Ok, this isn’t quite an answer, but why not using editor macros?

Just a thought, don’t flame me.

Paulo Jorge Duarte
Köremoved_email_address@domain.invalid


#19

Yukihiro M. wrote:

I thought (and I still think) it is a good idea to separate method
argument and assignment in general. It’s convention supported by most
languages, and mixing parameters and assignments gives me impression
of toy-language.

That’s interesting. Would you mind sharing your insight on why these
should be
separated? To me they seem similar enough to be “merged”. I think the
only
reason to separate them is because, at the machine-language level,
function
arguments are PUSHed onto the stack while assignments are MOVed to
memory. So
historically they come from different mechanisms. But if we agree that
computer
languages should be designed for humans, not computers, it seems more
natural to
view parameters as a specialized case of assignment.

Besides that, I think formal arguments of a method (including their
names) can be seen as part of class API. Allowing instance variables
as formal arguments seems like disclosing the internal issues.

I can see the number of arguments (and in other languages, their type)
as part
of the class API, but not their names since those variables’ names are
local to
the method. True, rdoc exposes those internals in the documentation, but
then it
also exposes the instance variables & methods used for default values.
For
consistency I think instance variables should be allowed as parameters
since
they are allowed as default values. But I acknowledge that consistency
may not
be the most important factor to consider here.

I dunno, forbidding instance variables may be the more “correct”
approach but I
think allowing them would be more useful. One of the reasons I like ruby
is
because it favors usefulness over strict “correctness” (e.g. you can
still get
to private methods if you really need it)

just my 2円

Daniel


#20

David C. wrote:

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 B. 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