Forum: Ruby Defining object methods in initialize

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Martin B. (Guest)
on 2007-03-04 15:59
(Received via mailing list)
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
Tim B. (Guest)
on 2007-03-04 16:12
(Received via mailing list)
> 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%20class
Martin B. (Guest)
on 2007-03-04 16:32
(Received via mailing list)
Thanks! Working!
Robert K. (Guest)
on 2007-03-04 21:35
(Received via mailing list)
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"
=> #<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
This topic is locked and can not be replied to.