AbstractQueryFactoryFactories and alias_method_chain: The Ruby Way
yehudakatz.com
yehudakatz.com
These monkey patches constitute my solution to the problem:
class UnboundMethod
def origin
owner.instance_method(name)
end
end
class Proc
def to_method(object, method)
me = self
object.class.class_eval do
current = instance_method(method).origin rescue nil
mine = current.owner == self rescue false
define_method(method, &me)
result = instance_method(method)
mine ? define_method(method, current) : remove_method(method)
result
end.bind(object)
end
end
class Module
def redefine(method, &code)
original = instance_method(method).origin
define_method(method) do |*args, &block|
code.to_method(self, method).(original.bind(self), *args, &block)
end
end
end
You use this as follows: Fixnum.redefine(:+) do |old_plus, other|
if self == 2 and other == 2
5
else
old_plus.(other)
end
end
>> 2 + 2
=> 5
>> 2 + 3
=> 5
>> 2 + 1
=> 3
I'll admit that its implementation is pretty horrible, but I think the interface is much nicer: you pass in a function which specifies your new function in terms of the old one, which is always passed as the first argument.