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.
>
> class Foo
>   
>  
>  
> end
>
> class Bar
>   
>   >
>  >   >   >  
>  
>  
>  >  
>
>   >   >  
> end
>
>
> 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"
>
>
> Is it possible to do this?
>
> cr
>
>

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.

Jesus.