强制在Ruby中调用Kernel :: method_name

时间:2010-05-25 01:04:58

标签: ruby

我想在Ruby的内核模块中添加foo方法,因此我可以在任何地方编写foo(obj)并让它对obj执行某些操作。有时我想要一个类来覆盖foo,所以我这样做:

module Kernel
  private  # important; this is what Ruby does for commands like 'puts', etc.
  def foo x
    if x.respond_to? :foo
      x.foo  # use overwritten method.
    else
      # do something to x.
    end
  end
end

这很好,而且很有效。但是,如果我想在覆盖Kernel::foo的其他对象中使用默认的foo,该怎么办?由于我有一个实例方法foo,我已经失去了对Kernel::foo的原始绑定。

class Bar
  def foo  # override behaviour of Kernel::foo for Bar objects.
    foo(3) # calls Bar::foo, not the desired call of Kernel::foo.
    Kernel::foo(3)  # can't call Kernel::foo because it's private.
    # question: how do I call Kernel::foo on 3?
  end
end

有没有干净的方法来解决这个问题?我宁愿没有两个不同的名字,我绝对不想让Kernel::foo公开。

3 个答案:

答案 0 :(得分:3)

您可以使用super关键字从重写方法调用超类的实现。

class Bar
  def foo  # override behaviour of Kernel::foo for Bar objects.
    super
    # do something else here
  end
end

答案 1 :(得分:3)

对于更通用的解决方案,而不仅仅是super(超级不会一直工作),也请看这个帖子:

How to access a shadowed global function in Ruby?

答案 2 :(得分:0)

在之前使用aliasalias_method 重新定义Kernel.foo以保留对原始版本的引用。