Enhancing a Ruby method
There's a method in a library out of my control that uses a block to do wonderful things. Now, I'd like to create some overloads to make my life even easier, but can't figure out how to get it to work like I want to.
Here's what I have so far:
class ClassNotDefinedByMe
def enhanced_awesome_method(&block)
if block.arity < 2
awesome_method(&block)
else
# Doing my own extensions here.
# This part is not the issue.
end
end
end
The ClassNotDefinedByMe
is in the lib and so is the awesome_method
. The awesome_method
takes a block and does meaningful things with 0 or 1 parameter for that block. Any other number of arguments causes exceptions to be raised. I've written the above to add the possibility to use 2 or 3 parameters in the block and everything is working fine, except that now I have to call enhanced_awesome_method
instead of awesome_method
.
Examples for more clarification (x is an instance of the ClassNotDefinedByMe
):
# These two comes from the library:
x.awesome_method{ puts "works" }
x.awesome_method{ |i| puts "also works, the argument is #{i}" }
# Now I can do this:
x.enhanced_awesome_method{ |i,j| puts "oh, two arguments! cool." }
x.enhanced_awesome_method{ |i,j,k| puts "three arguments, how bold!" }
# But I want to be able to do this:
x.awesome_method{ puts "still works" }
x.awesome_method{ |i| puts "still works" }
x.awesome_method{ |i,j| puts "still works" }
x.awesome_method{ |i,j,k| puts "still works" }
One 开发者_StackOverflow社区could argue that it's a good thing that I have to use a new name for my enhanced method, so that it becomes apparent that it's a different method, but I would really like to replace awesome_method
with my own altogether. It won't break any existing code, since the behaviour is identical for the 0 and 1 parameter cases and those were the only legal ones up til now.
So, the problem I'm running into is that if I name my method awesome_method
and pass it a block with 0 or 1 parameter, it will call itself forever. If this was a case of inheritance I'd solve it by calling super.awesome_method
, but what can I do in this case when I've simply altered the class itself?
use the alias
keyword to make an alias of the original function, then you can override the method making a call to the aliased method.
eg:
class ClassNotDefinedByMe
alias :old_awesome_method :awesome_method
def awesome_method(&block)
if block.arity < 2
old_awesome_method(&block)
else
# Awesome stuff here
end
end
end
What you are trying to do is called method aliasing, but it does replace the original method.
精彩评论