我自己进行了扩展Kernel
,在实例方法的定义中Kernel#abort
,我称为单例方法Kernel.abort
:
module Kernel
extend self
def abort
puts "Press ENTER to exit..."
gets
Kernel.abort
end
end
abort
当我调用时Kernel#abort
,Kernel.abort
方法定义内的调用似乎引用了原始对象Kernel#abort
(扩展为Kernel.abort
)。
Ruby如何知道我写的Kernel.abort
是原始abort
方法,而不是我刚刚创建的方法?如何递归调用abort
刚创建的新方法?
Kernel.abort
首先定义一个实例方法Kernel#abort
,然后再使它成为单例方法来定义它module_function
。(在Rubinius中肯定是这种情况;我在MRI源中找不到它,但请参阅下文。)module_function
制作了该方法的一个副本。重新abort
定义时,您将重新定义实例方法,而不是单例副本。
Object
包含Kernel
,因此当您说abort
得到重新定义的实例方法时,但是当您说Kernel.abort
没有得到重新定义的单例方法时。
如果您确实想在中使用递归abort
,或者只是为了证明此解释是正确的,请module_function :abort
在重新定义方法后调用。单例方法将更新为与实例方法相同,并且两个方法都将递归。
请注意,您无需extend self
重新定义的实例版本abort
。由于Kernel
已包含在中Object
,因此您只需为所有对象重新定义实例方法即可查看重新定义的版本。另一方面,如果一开始Kernel
曾经使用extend self
过曝光#abort
,我们可以重新定义它而没有任何复杂性。
以下内容证明了用户定义的纯Ruby方法缺乏递归,即module_function
负责任的和本机方法不是:
$ cat foo.rb
module Foo
def bar
puts "old version"
end
module_function :bar
end
module Foo
def bar
puts "new version"
Foo.bar
end
end
Object.include Foo
bar
$ ruby foo.rb
new version
old version
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句