强制在Ruby中调用Kernel::method_name

强制在Ruby中调用Kernel::method_name,ruby,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.

我想在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
这是好的,而且有效。但是,如果我想在覆盖
foo
的其他对象中使用默认的
Kernel::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
公开。

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

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

在重新定义Kernel.foo之前,只需使用
alias
alias\u方法
,以保留对原始版本的引用。

有关比仅使用
super
更通用的解决方案(super并不总是有效),请参见以下线程:


是的,你完全正确。谢谢由于
Kernel
的模糊性而分心。我已经尝试过这个方法,但它不起作用,因为
Kernel::foo
在代码定义时没有被混入。这也会污染您的命名空间。它确实会在任何情况下污染命名空间,但它回答了我们提出的问题。