Ruby mixin覆盖方法澄清

时间:2012-03-22 17:53:17

标签: ruby module mixins

我刚刚面对这种我不太懂的行为。

module M
  def foo
    "module_foo"
  end
end

class C
  def foo
    "class_foo"
  end
  include M
end

puts C.new.foo

为什么C.new.foo实际返回class_foo?我非常确定该方法应该被模块中的方法覆盖。另一件事,用"class_foo"替换super会使C.new.foo返回“”module_foo“

实际上看起来模块在定义类实例方法之前以某种方式包含在内。你能澄清一下吗?

2 个答案:

答案 0 :(得分:14)

来自mixins的 Programming Ruby 部分:

  

事实上,混合模块有效地表现出来   作为超级班。

所以你经历的是正常的。 你的模块M是你的C类的超类

因此,C类中的foo方法会覆盖模块M中的foo方法

答案 1 :(得分:3)

以下是ruby方法查找的方法:

  1. 接收者的单身人士班级;
  2. 接收者的班级;
  3. 任何包含的模块方法;
  4. 在接收者的超类中重复查找;
  5. 如果根本找不到任何方法,method_missing call;
  6. 您可以在此处找到更多详细信息:http://ruby-metaprogramming.rubylearning.com/html/ruby_metaprogramming_2.html

      

    因此,为了找到一个方法,Ruby会进入接收者的类,并从那里爬上祖先的链,直到找到方法。   这种行为也被称为“向右一步,然后向上”   规则:向右一步进入接收者的课程,然后向上   祖先链,直到找到方法。当你包括一个   在类(或甚至在另一个模块中)的模块中,Ruby创建了一个   包装模块的匿名类,并插入匿名类   在链中,就在包含类本身之上。