增强Ruby方法

时间:2010-12-13 13:09:20

标签: ruby metaprogramming

我的控制库中有一个方法,它使用一个块来做很棒的事情。现在,我想创建一些重载,让我的生活更轻松,但无法弄清楚如何让它像我想的那样工作。

这是我到目前为止所拥有的:

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

ClassNotDefinedByMe位于lib中,awesome_method也是如此。 awesome_method接受一个块并使用该块的0或1参数执行有意义的操作。任何其他数量的参数都会导致引发异常。我已经写了上面的内容,增加了在块中使用2或3个参数的可能性,一切正常,但现在我必须调用enhanced_awesome_method而不是awesome_method

更多说明的示例(x是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" }

有人可能会说,我必须为我的增强方法使用新名称是一件好事,因此很明显它是一种不同的方法,但我真的想用自己的方法替换awesome_method共。它不会破坏任何现有代码,因为0和1参数情况的行为是相同的,并且这些是迄今为止唯一的合法代码。

所以,我遇到的问题是,如果我将方法命名为awesome_method并将其传递给具有0或1参数的块,它将永远调用自身。如果这是继承的情况,我会通过调用super.awesome_method来解决它,但在这种情况下,当我简单地改变类本身时,我该怎么办?

2 个答案:

答案 0 :(得分:3)

使用alias关键字创建原始函数的alias,然后您可以覆盖调用别名方法的方法。

例如:

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

答案 1 :(得分:0)

您尝试执行的操作称为method aliasing,但它确实取代了原始方法。