Defining object methods in initialize

I’d like to define methods on initialize that are specific for the
created
object. However it seems that the few lines of code below is defining
them
somewhere else since they are ‘overwriting’ each other:

============
class Foo
def initialize(method_name, &block)
self.class.send(:define_method, method_name, &block)
end
end

aa = Foo.new(:whoareyou) { puts “I am aa” }
bb = Foo.new(:whoareyou) { puts “I am bb” }

aa.whoareyou

returns: “I am bb” - But I expect: “I am aa”

bb.whoareyou

returns: “I am bb”

Foo.whoareyou

undefined method ===> Good

============

Thanks!

martin

However it seems that the few lines of code below is defining them
somewhere else since they are ‘overwriting’ each other:

============
class Foo
def initialize(method_name, &block)
self.class.send(:define_method, method_name, &block)
end
end

You’re absoultely right about the methods being defined “somewhere
else”, they’re being defined in the class Foo, which both instances
share. If you want to define specific and different implementations
for the same method name you need to use singleton/instance
inheritance. Like this:

class Foo
def initialize(method_name, &block)
c = class << self; self; end
c.send(:define_method, method_name, &block)
end
end

That way each instance gets a private Class that they don’t share.

Take the above with a grain of salt, I don’t have an interpreter on
this computer, so I can test it to see if it works… This blog
article might be interesting if you care for a deeper explanation:

Thanks! Working!

On 04.03.2007 14:59, Martin B. wrote:

============
Note, you do not necessarily need instance methods in this case:

irb(main):001:0> Foo = Struct.new :whoareyou
=> Foo
irb(main):002:0> aa = Foo.new “I am aa”
=> #
irb(main):003:0> bb = Foo.new “A am bb”
=> #
irb(main):004:0> aa.whoareyou
=> “I am aa”
irb(main):005:0> bb.whoareyou
=> “A am bb”

Kind regards

robert