auto assign arguments?

D

David Chelimsky

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
 
K

Kalman Noel

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, :eek:ther)
class Klass

# more

end

Kalman
 
G

gwtmp01

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 Wright
 
J

James Edward Gray II

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.

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)
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
 
P

Pit Capitain

David said:
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
 
A

ara.t.howard

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>


-a
 
D

Daniel Berger

David said:
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
 
D

David Chelimsky

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>

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 ;) 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
 
J

James Edward Gray II

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

Gregory Brown

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.

+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.
 
D

Daniel Berger

James said:
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.
:)

Regards,

Dan
 
G

gwtmp01

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.

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
 
D

David Chelimsky

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
 
B

Bill Kelly

From: "David Chelimsky said:
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
 
D

Daniel DeLorme

Gregory said:
-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
 
R

Robert Klemme

David Chelimsky:

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, :eek:ther)
class Klass

# more

end

You can even do

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

which I find pretty nice. :)

robert
 
D

dblack

Hi --

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

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)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top