Defining object methods in initialize

M

Martin Boese

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
 
T

Tim Becker

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:

http://ola-bini.blogspot.com/search/label/singleton class
 
M

Martin Boese

Thanks! Working!

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:

http://ola-bini.blogspot.com/search/label/singleton class
 
R

Robert Klemme

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
============

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"
=> #<struct Foo whoareyou="I am aa">
irb(main):003:0> bb = Foo.new "A am bb"
=> #<struct Foo whoareyou="A am bb">
irb(main):004:0> aa.whoareyou
=> "I am aa"
irb(main):005:0> bb.whoareyou
=> "A am bb"

Kind regards

robert
 

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

Forum statistics

Threads
473,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top