你可以通过包含一个模块来覆盖一个方法吗?

时间:2011-06-02 23:46:50

标签: ruby

  

可能重复:
  Overriding method by another defined in module

以下是一些代码:

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是否会阻止覆盖先前定义的方法?

3 个答案:

答案 0 :(得分:7)

我不太明白你的问题。你认为在这里“被阻止”的是什么,以及由谁来制造?

这正是应该如何运作的。 Module#include混合在模块中作为混合的任何类的直接超类。 MFoo的超类,因此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}},ObjectKernel然后调用BasicObject)。

就个人而言,我不介意在查看method_missing之前先查看M的能力。我听说有人说过要在Ruby 2.0中添加这样做的能力,但这对你现在没有帮助。

答案 2 :(得分:-1)

您的包含电话不符合您的想法...尝试Foo.send(:extend,M)