I'm trying to synchronise the implementations of ClassMethod#restore_original_method
and AnyInstanceMethod#restore_original_method
in the hope that I can then remove the duplication.
In ClassMethod
the @original_method
is a Method
(i.e. it's bound). In AnyInstanceMethod
the @original_method
is an UnboundMethod
. I presume it's not possible to get hold of a bound method in AnyInstanceMethod
as the class hasn't been instantiated at the point we get hold of it.
The define_method
method accepts either a Method
or UnboundMethod
as the second argument. Although I can't use this form in Ruby 1.8.7 because of the "singleton method bound for a different object" problem (see https://gist.github.com/chrisroos/fc62b8e0ce30288abba6a3762b2cb1ee).
Given that I don't think I can get a bound Method
in AnyInstanceMethod
that means unbind
ing the method I have in ClassMethod
.
I end up with the following code in ClassMethod#restore_original_method
:
original_method = @original_method
receiver = stubbee
stubbee.__metaclass__.send(:define_method, method) do |*args, &block|
original_method.bind(receiver).call(*args, &block)
end
And I end up with this code in AnyInstanceMethod#record_original_method
:
original_method = @original_method
stubbee.send(:define_method, method) do |*args, &block|
original_method.bind(self).call(*args, &block)
end
Unfortunately I can't currently see any way of making them the same!