开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜