[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Defining object methods in initialize

Martin Boese

3/4/2007 1:59:00 PM

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

3 Answers

Tim Becker

3/4/2007 2:11:00 PM

0

> 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/singlet...




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

Martin Boese

3/4/2007 2:32:00 PM

0

Thanks! Working!

On Sunday 04 March 2007 14:11, Tim Becker wrote:
> > 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/singlet...
>
> > 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

Robert Klemme

3/4/2007 7:35:00 PM

0

On 04.03.2007 14:59, Martin Boese wrote:
> 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