From: Chuck Remes Date: 2010-08-13T03:18:07+09:00 Subject: Re: injecting an instance method into another class' class method --Boundary_(ID_vDhjaQW4AuHy5pCqExPKGA) Content-type: text/plain; charset=iso-8859-1 Content-transfer-encoding: quoted-printable On Aug 11, 2010, at 11:11 AM, Jes=FAs Gabriel y Gal=E1n wrote: > On Wed, Aug 11, 2010 at 5:32 PM, Chuck Remes = wrote: >> I'd like to reopen a class Foo and redefine one of its methods to use = an instance method from class Bar. I can't seem to figure out how to do = it or even if it is possible. >>=20 >> I tried lots of different techniques and none have worked, so here I = am asking for a bit of help. An example of one of the techniques I tried = is included below. >> [snip] >> I would like Foo.now to return Time.now.to_i for the normal case. = However, after an instance of Bar is created, I would like the Bar = instance to redefine Foo.now to call the #now instance method of Bar. >>=20 >> This is what the output should look like: >>=20 >> ruby-1.9.1-p378 > Foo.now >> =3D> 1281540640 >> ruby-1.9.1-p378 > Bar.new >> bar now >> =3D> #> >> ruby-1.9.1-p378 > Foo.now >> =3D> "bar now called" >=20 > I've managed to do it with a local variable, instead of an instance = variable: >=20 > class Foo > def self.now > "Foo's now" > end > end >=20 > class Bar > def initialize > bar =3D proc {now} > class << Foo; self; end.class_eval do > define_method(:now) do > bar.call > end > end > end >=20 > def now > "Bar's now" > end > end >=20 > puts Foo.now > puts Bar.new.now > puts Foo.now >=20 > $ ruby redefine.rb > Foo's now > Bar's now > Bar's now >=20 > The problem with an instance variable is that you need to have self as > Bar's instance in order for it to work. So if you can use a local > variable and use closures, it will work, as shown above. Ah, excellent! I was trying to figure out how to use a closure for this = purpose, but my mind got all turned inside out. I'm somewhat familiar with getting the singleton class of a class using = the "class << self;self;end" syntax, but I'm not sure what is happening = here: class << Foo self # what is self here? Foo? Bar? instance of Bar? end My inline questions lay it out. I'd really like to understand how that part of it is working. I = understand the mechanics of the remaining code. cr --Boundary_(ID_vDhjaQW4AuHy5pCqExPKGA)--