--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 Gabriel y Gal wrote:

> On Wed, Aug 11, 2010 at 5:32 PM, Chuck Remes <cremes.devlist / mac.com> 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.
>> 
>> 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.
>> 
>> This is what the output should look like:
>> 
>> ruby-1.9.1-p378 > Foo.now
>>  => 1281540640
>> ruby-1.9.1-p378 > Bar.new
>> bar now
>>  => #<Bar:0x00000101216268 @bar=#<Proc:0x000001012161c0@(irb):41>>
>> ruby-1.9.1-p378 > Foo.now
>>  => "bar now called"
> 
> I've managed to do it with a local variable, instead of an instance variable:
> 
> class Foo
> 	def self.now
> 		"Foo's now"
> 	end
> end
> 
> class Bar
> 	def initialize
> 		bar = proc {now}
> 		class << Foo; self; end.class_eval do
> 			define_method(:now) do
> 				bar.call
> 			end
> 		end
> 	end
> 
> 	def now
> 		"Bar's now"
> 	end
> end
> 
> puts Foo.now
> puts Bar.new.now
> puts Foo.now
> 
> $ ruby redefine.rb
> Foo's now
> Bar's now
> Bar's now
> 
> 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)--