Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

dynamically assigning instance variables

3 views
Skip to first unread message

Berger, Daniel

unread,
May 3, 2002, 5:48:26 PM5/3/02
to
Hi all,

Yep, still trying to unwrap my brain from Perl and re-wrap it in Ruby...

Is there a way to dynamically assign instance variables?

class SomeClass
def initialize(hash)
hash.each do |key,val|
@#{key} = val # Doesn't work
end
end
end

Is there a better way to do this?

Thanks in advance.

Regards,

Dan

wco...@yagni.com

unread,
May 3, 2002, 6:06:46 PM5/3/02
to
This way, which is probably not the best way, seems to do something:

wconrad@pluto:~/lab/foo1$ cat foo.rb
#!/usr/bin/ruby

class Foo

def initialize(hash)
for key, value in hash do
eval "@#{key}=#{value.inspect}"
end
end

end

p Foo.new({"i"=>1, "s"=>"blah"})

wconrad@pluto:~/lab/foo1$ ./foo.rb
#<Foo:0x402568ec @s="blah", @i=1>

Wayne Conrad

Harry Ohlsen

unread,
May 4, 2002, 12:22:42 AM5/4/02
to
wco...@yagni.com wrote in message news:<20020503220050.GA443@pluto>...

> This way, which is probably not the best way, seems to do something:
>
> wconrad@pluto:~/lab/foo1$ cat foo.rb
> #!/usr/bin/ruby
>
> class Foo
>
> def initialize(hash)
> for key, value in hash do
> eval "@#{key}=#{value.inspect}"
> end
> end
>
> end
>
> p Foo.new({"i"=>1, "s"=>"blah"})


Someone else will probably give you a better solution, but here's
something I wrote that avoids a problem I see with the 'value.inspect'
method. The issue is that often the string version of an object cannot
be used to assign to a variable and end up with the same type as the
original.

With the inspect version, I don't think, for example, that assigning
a time value would work. Anyway, have a play with this one if you're
interested. It also has the advantage that it uses method_missing to
provide setters and getters for all the instance variables.

class HashStruct

def initialize(hash)
hash.each_pair do |key, value|
instance_eval "@#{key} = value"
end
end

def method_missing(name, *args)
if name.to_s =~ /(.*)=/
self.instance_eval "@#{$1} = args[0]"
else
self.instance_eval "@#{name}"
end
end

end

hs = HashStruct.new({"text" => "hello", "time" => Time.now})

$stderr.puts hs.text
$stderr.puts hs.time

sleep 2

hs.time = Time.now

$stderr.puts hs.time

Jean-Hugues ROBERT

unread,
May 4, 2002, 7:17:46 AM5/4/02
to
Hello,

At 13:30 04/05/2002 +0900, you wrote:
>Anyway, have a play with this one if you're
>interested. It also has the advantage that it uses method_missing to
>provide setters and getters for all the instance variables.
>
>class HashStruct
>
> def initialize(hash)
> hash.each_pair do |key, value|
> instance_eval "@#{key} = value"
> end
> end
>
> def method_missing(name, *args)
> if name.to_s =~ /(.*)=/
> self.instance_eval "@#{$1} = args[0]"
> else
> self.instance_eval "@#{name}"
> end
> end
>

>end Harry Ohlsen

This nice piece of code is solving an issue I was dealing with, about "copy
constructors". This is a C++ idiom and I suspect there could be a
better/different one in Ruby. However, for those interested, here is the code:

# value.rb
# Module that helps handling 'Value' objects and C++ style Copy Constructors
#
# 02/05/04, JHR, Creation

# Typical synopsis:
# class MyClassWithCopyConstructor
# include CanValue
# def initialize( some_stuff )
# return self if initValue( some_stuff)
# ... init somehow differently here ...
# end
# ...
# end
# The module basically makes it easy to write copy constructors. Nota: the new
# object is not a deep copy of the original, its instance variables have the
# values of the original object's ones.
module CanValue

class Value < Hash
def toValue() self end
end

def initValue( a_value )
return nil unless a_value.respond_to? :toValue
a_value.toValue().each_pair do | var_name, value |
instance_eval "#{var_name}= value"
# p "Setting #{var_name} instance variable"
end
self
end

def toValue()
a_value = Value.new
instance_variables().each do | var_name |
a_value[var_name.intern()] = instance_eval( var_name)
end
a_value
end

end # CanValue

# An example, using the CanValue module.
class MyClass
include CanValue
attr_accessor :myVar
def initialize( a_value = nil )
return self if initValue( a_value)
@myVar = "Hello"
end
def print() p @myVar; end
end
a = MyClass.new
b = MyClass.new( a)
c = a.clone()
a.print; b.print; c.print
a.myVar = "I am a"; b.myVar = "I am b"; c.myVar = "I am c"
a.print; b.print; c.print

# Apparently .clone() does a similar job: making a "copy" of a object.
# However it does not work well with .new(), as can be seen here:
class MyClass2
attr_accessor :myVar
def initialize( some_stuff = nil )
return some_stuff.clone() if some_stuff.kind_of? self.class()
@myVar = "Hello"
end
def print() p @myVar; end
end
a = MyClass2.new
b = MyClass2.new( a) # Does not work
c = a.clone()
a.print; b.print; c.print
a.myVar = "I am a"; b.myVar = "I am b"; c.myVar = "I am c"
a.print; b.print; c.print

# A solution is to use a MyClass.create instead of MyClass.new. This could be
# another example for those who believe in "'new' considered harmful"...
class MyClass3
attr_accessor :myVar
def initialize()
@myVar = "Hello"
end
def self.create( some_stuff = nil )
return some_stuff.clone() if some_stuff.kind_of? self
new
end
def print() p @myVar; end
end
a = MyClass3.create
b = MyClass3.create( a)
c = a.clone()
a.print; b.print; c.print
a.myVar = "I am a"; b.myVar = "I am b"; c.myVar = "I am c"
a.print; b.print; c.print

Question: What the preferred idiom for creating objects in Ruby ?
The C++ idioms ('new' & overloading) seems rather unpractical to me, due
to the inability to overload new (or any other method, for that matter)
based on the parameters.

Yours,

Jean-Hugues

-------------------------------------------------------------------------
Web: http://hdl.handle.net/1030.37/1.1
Phone: +33 (0) 4 92 27 74 17

Holden Glova

unread,
May 4, 2002, 7:22:58 AM5/4/02
to
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

I'll add something to pile, here is something I used as a mixin where ever i
needed to this.

#
# Builds object attributes from a supplied Hash
#
module HashAttrBuilder

#
# Builds the object attributes from the supplied Hash.
#
# attributes: A Hash with each key being a Symbol
#
def build_instance_vars(attributes)
attributes.each do |k, v|
name = k.id2name
value = v.type == String ? "'" + v + "'" : v
instance_eval(<<-EOS)
class << self
attr_accessor :#{name}
end
EOS

send("#{name}=", v)
end
end

end

- --
Signed,
Holden Glova
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iD8DBQE808X1+mF116Lw2cQRAk7+AKCETHtHfNCnj5/T+xrPF2w9Of63pgCfTRmE
Ovta6egpqYRQFresjVRZPIQ=
=kBeb
-----END PGP SIGNATURE-----

Jean-Hugues ROBERT

unread,
May 4, 2002, 7:33:23 AM5/4/02
to

Hello,

Modules are very convenient to add "instance methods" to a class. Is there
a way a Module can also add "class methods" ?

Something like:
module MyModule
def self.foo() # not sure of what this does, but not what I want
print "foo"
end
end
class MyClass
include MyModule
end
MyClass.foo() # Does not work, foo is not defined for MyClass

Thanks,

Jean-Hugues

ts

unread,
May 4, 2002, 7:33:23 AM5/4/02
to
>>>>> "J" == Jean-Hugues ROBERT <jean_hugu...@yahoo.com> writes:

J> module MyModule
J> def self.foo() # not sure of what this does, but not what I want
J> print "foo"
J> end
J> end
J> class MyClass
J> include MyModule
J> end
J> MyClass.foo() # Does not work, foo is not defined for MyClass

module MyModule
def foo()


print "foo"
end
end
class MyClass

extend MyModule
end
MyClass.foo() # work :-)


Guy Decoux

David Alan Black

unread,
May 4, 2002, 7:38:35 AM5/4/02
to
Hello --

On Sat, 4 May 2002, Jean-Hugues ROBERT wrote:

> Question: What the preferred idiom for creating objects in Ruby ?
> The C++ idioms ('new' & overloading) seems rather unpractical to me, due
> to the inability to overload new (or any other method, for that matter)
> based on the parameters.

I'm not sure what you mean. Isn't new() the usual way to create
objects?


David

--
David Alan Black
home: dbl...@candle.superlink.net
work: blac...@shu.edu
Web: http://pirate.shu.edu/~blackdav

ts

unread,
May 4, 2002, 7:59:27 AM5/4/02
to
>>>>> "H" == Holden Glova <dsa...@xtra.co.nz> writes:

H> instance_eval(<<-EOS)
[...]
H> send("#{name}=", v)

eval is evil, and it's still exist a stupid way to write it :-)

pigeon% cat b.rb
#!/usr/bin/ruby
module Hab
module Tmp
def defin(a)
attr_accessor a
end
end

def self.append_features(c)
super
c.extend Tmp
end

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

end

class A
include Hab
end

a = A.new
a.biv("aaa" => [1, 2], :bbb => [3, 4])
p a.aaa
p a.bbb
pigeon%

pigeon% b.rb
[1, 2]
[3, 4]
pigeon%


Guy Decoux

ts

unread,
May 4, 2002, 9:32:56 AM5/4/02
to
>>>>> "J" == Jean-Hugues ROBERT <jean_hugu...@yahoo.com> writes:

J> The C++ idioms ('new' & overloading) seems rather unpractical to me, due

It's normal, ruby is not C++ :-)))


Guy Decoux


Jean-Hugues ROBERT

unread,
May 4, 2002, 10:14:28 AM5/4/02
to
At 20:35 04/05/2002 +0900, David Alan Black wrote:
>Hello --
>
>On Sat, 4 May 2002, Jean-Hugues ROBERT wrote:
>
> > Question: What the preferred idiom for creating objects in Ruby ?
> > The C++ idioms ('new' & overloading) seems rather unpractical to me, due
> > to the inability to overload new (or any other method, for that matter)
> > based on the parameters.
>
>I'm not sure what you mean. Isn't new() the usual way to create
>objects?
>
>
>David

Let me clarify. The way you create objects using MyClass.new() is similar
to the way you do it in C++. With one major limitation: There can be only
one initialize() method. Whereas in C++ you can have multiple ones. The
difference being what type/number of parameters each one gets (in C++ the
"initialize()" method is not called "initialize()", it is called after the
name of the class).

So, in C++, based on what parameters you create a new object, you define
multiple "constructors".

The way to do it in Ruby is not natural/direct. Because you have only one
initialize() method, you need to determine yourself what the caller
intention was, based on the supplied parameters.

def initialize( param = nil )
case param
when nil
# no parameter constructor
...
when self.class
# Copy constructor
when xxx
# Whatever other constructor
end

Some other languages will create objects based on prototypes:

def initialize()
proto = @@proto
proto.instance_variables.each do | var |
instance_eval( "#{var} = #{proto.instance_eval( #{var})}")
end
end

Some other languages will have no "constructor" or "initialize()" specific,
language defined, construct:
def MyClass.create()
obj = Object.new()
obj.class = MyClass # Not ruby: Smalltalk's style .becomes() missing
obj.body = { :@myVar1 => "Hello", :@myVar2 => "world" } # Not ruby
end


Some other languages just create objects, without having the method that
create objects beeing named in any specific way:

def MyClass.createFromInt( ii )
obj = MyClass.new()
obj.foo = ii
return obj
end
def doubleIt()
obj = MyClass.new()
obj.foo = self.foo * 2
end

. an so on ..

The basic OO equation is: an_object is a_id + a_value + a_behaviour.

There are many idioms to create objects. Appararently the Ruby one is to
use SomeClass.new( some_param) that leads to: A) the creation of the object
ii with no initial value and the behaviour of its class, followed by B) a
call to ii.initialize( some_param).

Hope this is clearer.

Jean-Hugues ROBERT

unread,
May 4, 2002, 10:14:27 AM5/4/02
to

Thanks. However I would like to *include* the module, not extending it.

JHR

ts

unread,
May 4, 2002, 10:19:41 AM5/4/02
to
>>>>> "J" == Jean-Hugues ROBERT <jean_hugu...@yahoo.com> writes:

J> Thanks. However I would like to *include* the module, not extending it.

See [ruby-talk:39574], normally the method #biv can be written

def biv(attributes)
attributes.each do |k, v|

type.send(:attr_accessor, k)


send(k.to_s + "=", v)
end
end

I've just used a complex scheme to give you an example how to add class
methods and instance methods with a module


Guy Decoux

Kent Dahl

unread,
May 4, 2002, 4:21:37 PM5/4/02
to
Jean-Hugues ROBERT wrote:
>
> At 20:31 04/05/2002 +0900, you wrote:
> > module MyModule
> > def foo()
> > print "foo"
> > end
> > end
> > class MyClass
> > extend MyModule
> > end
> > MyClass.foo() # work :-)
> >
> >
> >Guy Decoux
>
> Thanks. However I would like to *include* the module, not extending it.

You aren't extending the Module.
You are extending MyClass with the contents of the module.

Sounds like you need to split up your module in a part you want to
include (instance methods) and a part you want to extend your class with
(class methods).

--
(\[ Kent Dahl ]/)_ _~_ __[ http://www.stud.ntnu.no/~kentda/ ]___/~
))\_student_/(( \__d L b__/ NTNU - graduate engineering - 4. year )
( \__\_鮸鮛/__/ ) _)Industrial economics and technological management(
\____/_鯻\____/ (____engineering.discipline_=_Computer::Technology___)

ts

unread,
May 4, 2002, 10:30:06 AM5/4/02
to
>>>>> "J" == Jean-Hugues ROBERT <jean_hugu...@yahoo.com> writes:

J> So, in C++, based on what parameters you create a new object, you define
J> multiple "constructors".

J> The way to do it in Ruby is not natural/direct.

ruby is not C++, don't try to mimic C++ with ruby (it's perhaps best to
forget it).

J> There are many idioms to create objects. Appararently the Ruby one is to
J> use SomeClass.new( some_param) that leads to: A) the creation of the object
J> ii with no initial value and the behaviour of its class, followed by B) a
J> call to ii.initialize( some_param).

No. What you describe is the new scheme allocate/initialize


Guy decoux

Niklas Frykholm

unread,
May 4, 2002, 11:06:00 AM5/4/02
to
>> class MyClass
>> extend MyModule
>> end

> Thanks. However I would like to *include* the module, not extending it.

See the recepie at

http://www.rubycookbook.org/showrecipe.rb?recipeID=166

// Niklas

Jean-Hugues ROBERT

unread,
May 4, 2002, 11:32:30 AM5/4/02
to
At 23:31 04/05/2002 +0900, you wrote:
>Jean-Hugues ROBERT wrote:
> >
> > At 20:31 04/05/2002 +0900, you wrote:
> > > module MyModule
> > > def foo()
> > > print "foo"
> > > end
> > > end
> > > class MyClass
> > > extend MyModule
> > > end
> > > MyClass.foo() # work :-)
> > >
> > >
> > >Guy Decoux
> >
> > Thanks. However I would like to *include* the module, not extending it.
>
>You aren't extending the Module.
>You are extending MyClass with the contents of the module.

True, sorry for the confusion.

>Sounds like you need to split up your module in a part you want to
>include (instance methods) and a part you want to extend your class with
>(class methods).

Yes, that would do the job. Maybe there is a way to get by with a single
module. I was wondering if some "included()" hook existed (similar to
inherited() for classes), and I found that "append_features()" is the hook
called when a module is included.

So: What I intend (to include class methods defined in a module)
module MyModule
def MyModule.foo()
end
end
class MyClass
include MyModule # I want to include both class & instance methods
end
MyClass.foo() # Calls foo() class method defined in module, broken.

Could be written:
module MyModule
def append_features( includer )
super( includer)
includer.instance_eval( "
# Here comes the definitions of included class methods
def foo() end
")


end
end
class MyClass
include MyModule
end
MyClass.foo()

However this does not work either... apparently append_features() is not
called. Additionnal 1) the construct is ugly, relies on eval and 2) there
is no way to later on introspect MyClass and know that foo() class method
was defined in MyModule.

Any hints ?

Jean-Hugues

Jean-Hugues ROBERT

unread,
May 4, 2002, 11:42:58 AM5/4/02
to
Oops, I think Guy's sample is helpful here. I need to redefine
self.append_feature() (instead of append_feature()) and then extend the
includer with some nested module:

module MyModule
module ClassMethods
def foo()
end
end
def self.append_features( includer )
super( includer)
includer.extend ClassMethods


end
end
class MyClass
include MyModule
end
MyClass.foo()

Not as direct as:
module MyModule
def self.foo()


end
class MyClass
include MyModule
end
MyClass.foo()

..But much better than my ugly .instance_eval() stuff. Thanks.

Jean-Hugues

Jean-Hugues ROBERT

unread,
May 4, 2002, 12:19:20 PM5/4/02
to
Hello,

Thanks. I am using it in my CanValue module. When that module is included
by YourClass, YourClass.create( an_obj ) will create a new object using
an_obj's instance variables (or .clone() when appropriate). This is the
equivalent of C++'s Copy Constructor (a Constructor that create an object
whose "value" is the same as the original).

Yours,

Jean-Hugues

# Typical synopsis:
# class MyClassWithCopyConstructor
# include CanValue
# def initialize( some_stuff )
# return self if initValue( some_stuff)
# ... init somehow differently here ...
# end
# ...
# end
# The module basically makes it easy to write copy constructors. Nota: the new
# object is not a deep copy of the original, its instance variables have the
# values of the original object's ones.

# The module also defines a class.create() method that behaves like the
# class's .new() method but will act as a copy constructor if called with
# a parameter that is of the same class (or of a class derived from self).
#
# Bugs: The copy gets the instance variables of the source, including the ones
# the ones that were added by derived class. The .create() does not handle
# blocks the way .new() does.

module CanValue

class Value < Hash
def toValue() self end
end

def initValue( a_value )
return nil unless a_value.respond_to? :toValue
a_value.toValue().each_pair do | var_name, value |
instance_eval "#{var_name}= value"
# p "Setting #{var_name} instance variable"
end
self
end

def toValue()
a_value = Value.new
instance_variables().each do | var_name |
a_value[var_name.intern()] = instance_eval( var_name)
end
a_value
end

# Defines a create() class method that will act as a copy constructor if
# called with a parameter that is of the same kind.
module ClassMethods
def create( *param )
# p "self #{self} is a #{self.class()}"
if param.length != 1 then
self.new( *param)
else
if (src = param[1]).kind_of? self then
# Use faster .clone() if source object's class is the good one
return src.clone() if src.class() == self
obj = self.new()
src.toValue().each_pair do | var_name, value |
obj.instance_eval "#{var_name}= value"
end
obj
else
self.new( param[1])
end
end


end
end
def self.append_features( includer )
super( includer)
includer.extend ClassMethods
end

end # CanValue

ts

unread,
May 4, 2002, 12:29:43 PM5/4/02
to
>>>>> "J" == Jean-Hugues ROBERT <jean_hugu...@yahoo.com> writes:

J> def create( *param )
J> # p "self #{self} is a #{self.class()}"
J> if param.length != 1 then
J> self.new( *param)
J> else
J> if (src = param[1]).kind_of? self then


pigeon% cat b.rb
#!/usr/bin/ruby
def create(*param)
if param.length == 1
puts param[1]
end
end

create(12)
pigeon%

pigeon% b.rb
nil
pigeon%


Guy Decoux

Jean-Hugues ROBERT

unread,
May 4, 2002, 1:16:31 PM5/4/02
to
Hello,

Very true. Should have been be src = param[0], not src = param[1]. Thanks.
I get to look at this eXtreme stuff and all their unit tests I guess.

BTW: Any idea for optimizing this code so that build a copy of an object ?
I guess something faster would be using .clone() but then the class of the
object need to be fixed and I am yet to find what is the Ruby's equivalent
to Smalltalk's "become" (that will change the class of an object).

Yours,

JHR

Holden Glova

unread,
May 4, 2002, 7:35:51 PM5/4/02
to
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

I definately have a long way to go with Ruby - solutions like this do not
come naturally to me and only make sense after much examination. *drifts off
into a dream job of useing Ruby*.

Thanks for the tip.

- --
Signed,
Holden Glova
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iD8DBQE81G5N+mF116Lw2cQRAhBoAJ9uqAkq4GcvJvUV6ozrYwtyFdlvwQCgjD0B
Q+l7R/Y9kEVfrkf7CS4WOzE=
=lEFw
-----END PGP SIGNATURE-----

Holden Glova

unread,
May 4, 2002, 7:35:52 PM5/4/02
to
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Thanks Niklas, that has further helped me understand Guy Decoux's example.

- --
Signed,
Holden Glova
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iD8DBQE81G58+mF116Lw2cQRAqfHAJ9t22y8wz4OR8koJZqCWPGQIcQm6gCdHtPx
qgQ5jjpxcBuZSJ9O9Vn2uc8=
=WUXU
-----END PGP SIGNATURE-----

Daniel Berger

unread,
May 4, 2002, 11:57:11 PM5/4/02
to

Interesting. I dare say solutions like this don't come naturally to
most people doing Ruby (yet). In fact, I still don't completely
understand it, though I get parts of it. :(

If you're like me, it takes time to wrap your brain around a language.

Oh, and thanks Guy. Perhaps a cookbook entry?

Regards,

Dan

ts

unread,
May 5, 2002, 5:23:09 AM5/5/02
to
>>>>> "D" == Daniel Berger <djbe...@attbi.com> writes:

D> Oh, and thanks Guy. Perhaps a cookbook entry?

Not a cookbook entry but I'll say you why in this case eval is evil

Imagine that you have this module

pigeon% cat hab.rb
module Hab


def biv(attributes)
attributes.each do |k, v|

name = k.id2name


instance_eval(<<-EOS)
class << self
attr_accessor :#{name}
end
EOS

send("#{name}=", v)
end
end

end
pigeon%

because you find it usefull, you always use it and one day you'll write

pigeon% cat b.rb
#!/usr/bin/ruby
require 'hab'


class A
include Hab
end

Thread.new do
$SAFE = 3
a = A.new
a.biv(:aaa => 12)
p a.aaa
end.join
pigeon%

pigeon% b.rb
./hab.rb:5:in `instance_eval': Insecure operation - instance_eval (SecurityError)
from ./b.rb:7:in `join'
from ./b.rb:7
pigeon%

You have an usefull module, but this module is just useless because it
can't be used with $SAFE = 3.

Now rewrite it

pigeon% cat hab.rb
module Hab


def biv(attributes)
attributes.each do |k, v|

type.send(:attr_accessor, k)
send("#{k}=", v)
end
end

end
pigeon%

pigeon% cat b.rb
#!/usr/bin/ruby
require 'hab'


class A
include Hab
end

Thread.new do
$SAFE = 3
a = A.new
a.biv(:aaa => 12)
p a.aaa
end.join
pigeon%

pigeon% b.rb
12
pigeon%

This module do the same thing and it still work with $SAFE = 3. Each time
that you use #eval means that you'll not be able to use your module with
$SAFE = 3

Guy Decoux

Martin DeMello

unread,
May 5, 2002, 4:40:00 PM5/5/02
to
ts <dec...@moulon.inra.fr> wrote:

> pigeon% cat hab.rb
> module Hab
> def biv(attributes)
> attributes.each do |k, v|
> type.send(:attr_accessor, k)
> send("#{k}=", v)
> end
> end

Ah! It suddenly clicked into place what type.send was doing. Very neat.

--
Martin DeMello

Berger, Daniel

unread,
May 6, 2002, 8:51:24 AM5/6/02
to
> -----Original Message-----
> From: ts [mailto:dec...@moulon.inra.fr]
> Sent: Sunday, May 05, 2002 4:19 AM
> To: ruby...@ruby-lang.org
> Cc: ruby...@ruby-lang.org
> Subject: Re: dynamically assigning instance variables

> pigeon% cat hab.rb
> module Hab
> def biv(attributes)
> attributes.each do |k, v|
> type.send(:attr_accessor, k)
> send("#{k}=", v)
> end
> end
>
> end
>
> Guy Decoux

I think this idiom ought to be added to Hal's "Ruby for Perl Programmers"
talk. Named arguments are one of those things that Perl hackers have come
to get used to, and are extremely handy in certain situations (e.g. Tk/GUI
programming). Until this thread, I had thought it required an anonymous
hash.

I'm glad I asked. :)

Regards,

Dan

0 new messages