obj.send(attr) = value

R

ryanslists

Hello,

I would like to do something very simple -- assign a value to an object
attribute that has been accessed dynamically.

In Perl, this would be

my %hash = (foo => 90890, bar =>34243);
$obj->$_($hash{$_}) foreach keys %hash;

In Ruby I tried

obj.send(attr) = foo.attr

but it exploded with an error.

I found a very complicated four year old thread on comp.lang.ruby
called "dynamically assigning instance variables:"

http://groups.google.com/group/comp...name+attribute+assign&rnum=1#bebbab29a34c759e

It is 27 posts long and contains baroque syntax like

def biv(attributes)
attributes.each do |k, v|
type.send:)defin, k)
send(k.to_s + "=", v)
end
end

This can't be the only way to do such a simple thing in Ruby ... or is
it? Also, if so, where can I learn more about why the equals sign is
considered part of the method name?

Thanks for any help!
Ryan Tate
 
R

ryanslists

Thanks Tim, the attr_* docs did explain well the whole methodname=
thing. It sounds like I do have to use the relatively baroque syntax,
which I guess is fine.

It just seems inelegant by ruby standards -- it would be cool if there
was a method called __attr_write__ or somesuch --
obj.__attr_write__(methodname, value). I'm also not sure why
obj.__send__(methodname, value) doesn't just work --- I guess there is
difference between method arguments and assigned values --
obj.foo(a,b,c) = value is valid maybe? As you can see I am new to the
language.

Also, the .__send__ over .send is hugely lame, but whatever Done
decision apparently And I can keep using for now ;->

Do appreciate your help.

Best regards,
RT
 
R

Robert Klemme

Thanks Tim, the attr_* docs did explain well the whole methodname=
thing. It sounds like I do have to use the relatively baroque syntax,
which I guess is fine.

It just seems inelegant by ruby standards -- it would be cool if there
was a method called __attr_write__ or somesuch --
obj.__attr_write__(methodname, value). I'm also not sure why
obj.__send__(methodname, value) doesn't just work --- I guess there is
difference between method arguments and assigned values --
obj.foo(a,b,c) = value is valid maybe? As you can see I am new to the
language.

Also, the .__send__ over .send is hugely lame, but whatever Done
decision apparently And I can keep using for now ;->

Do appreciate your help.

Best regards,
RT

You need to do

obj.send("#{attr_name}=", val)

and not

obj.send(attr_name) = val

Kind regards

robert
 
D

Dave Burt

Robert said:
You need to do

obj.send("#{attr_name}=", val)

and not

obj.send(attr_name) = val

Alternatively, you can define an attribute accessor that accepts an
optional setter parameter:

class Foo
def bar(*args)
@bar = *args unless args.empty?
@bar
end
end

and use it like this:

obj.send("bar", new_value)

The Traits library on RubyForge adds default values and inheritability
as well as this ("trait 'bar'" will define a method like the above) --
you might want to check that out, too.

Cheers,
Dave
 

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,982
Messages
2,570,185
Members
46,736
Latest member
AdolphBig6

Latest Threads

Top