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 unbinding 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)
endAnd 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)
endUnfortunately I can't currently see any way of making them the same!