强制在Ruby中调用Kernel::method_name
我想在Ruby的内核模块中添加一个强制在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.
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
在代码定义时没有被混入。这也会污染您的命名空间。它确实会在任何情况下污染命名空间,但它回答了我们提出的问题。