以下是一些代码:
class Foo
def bar
puts "Original bar"
end
end
module M
def bar
puts "Called M::bar"
end
end
Foo.send(:include,M)
Foo.new.bar
# => Original bar
当“包含”同名方法时,ruby是否会阻止覆盖先前定义的方法?
答案 0 :(得分:7)
我不太明白你的问题。你认为在这里“被阻止”的是什么,以及由谁来制造?
这正是应该如何运作的。 Module#include
混合在模块中作为混合的任何类的直接超类。 M
是Foo
的超类,因此Foo#bar
会覆盖M#bar
,因为这是继承的工作原理:子类覆盖超类,而不是相反。此处没有“阻止”任何内容,当然您仍然可以覆盖Foo#bar
的子类中的Foo
。
你可以清楚地看到祖先:
class FooS; end
module M; end
class Foo < FooS; include M end
Foo.ancestors # => [Foo, M, FooS, Object, Kernel, BasicObject]
答案 1 :(得分:5)
改述@Jorg的回答:
如果你这样做
Foo.send(:include,M)
Foo.ancestors
你回来了
[Foo, M, Object, Kernel, BasicObject]
这意味着,当bar
被调用时,它会先查看是否存在Foo#bar
,并且只有当它不存在时才会尝试查看M#bar
(然后{ {1}},Object
,Kernel
然后调用BasicObject
)。
就个人而言,我不介意在查看method_missing
之前先查看M
的能力。我听说有人说过要在Ruby 2.0中添加这样做的能力,但这对你现在没有帮助。
答案 2 :(得分:-1)
您的包含电话不符合您的想法...尝试Foo.send(:extend,M)