I've always thought that alias_method was a pretty silly way to solve the problem of defining a new method in terms of an existing method with the same name. alias_method is definitely "simpler", but I think the way it actually destructively creates a method in a class is a bit ugly. I don't know what "AbstractQueryFactoryFactories" are, but the name makes me want to stay pretty far away from them.
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.
Sorry, I'm not sure what you mean. What did I implement that already exists? The only method I added to UnboundMethod was origin, and I don't see a method on that page that does that.
I'm glad someone responded to the original post, after so many years of java, I can't really say I ever enjoyed factories they always seemed to solve a problem that was a weakness in the language itself.
I'm surprised anyone bothered; the original post was so very obviously troll bait. People who've been in the Ruby community as long as Yehuda should know better.
These monkey patches constitute my solution to the problem:
You use this as follows: 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.