Pit Capitain
7/22/2007 7:20:00 PM
2007/7/22, Jesse Merriman <jesse.d.merriman@gmail.com>:
> (...) The solution that came to my mind
> was to create a delegating class that counts how many times #puts has been
> called, and restarts the process by killing the old wrapper object and creating
> a new one (...)
Thanks for the explanation. In this case you could try something like this:
require 'delegate'
class A
def foo
bar
end
def bar
'original'
end
end
class B < SimpleDelegator
def initialize
restart_delegate
end
def restart_delegate
delegate = A.new
__setobj__ delegate
controller = self
counter = 0
class << delegate; self; end.class_eval do
define_method :bar do
counter += 1
controller.restart_delegate if counter > 2
"overridden in #{self}, original was #{super}"
end
end
end
end
b = B.new
4.times do
puts b.foo
puts b.bar
end
The output:
overridden in #<A:0x2e0b42c>, original was original
overridden in #<A:0x2e0b42c>, original was original
overridden in #<A:0x2e0b42c>, original was original
overridden in #<A:0x2e0ab94>, original was original
overridden in #<A:0x2e0ab94>, original was original
overridden in #<A:0x2e0ab94>, original was original
overridden in #<A:0x2e0a900>, original was original
overridden in #<A:0x2e0a900>, original was original
Note how the A instance changes every three calls. The counter
increases both for internal and external calls. You can call the
original method with "super".
HTH
Regards,
Pit