2012-03-22 59 views
11

我刚刚面对这种行为,我真的不明白。Ruby mixin覆盖方法说明

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?我很确定这个方法应该被模块中的方法覆盖。另一件事,与super更换"class_foo"使得C.new.foo回报`“module_foo”

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

回答

14

编程红宝石部上的混入:

事实上,混合式模块有效地表现 如超类。

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

因此,在C类的富方法覆盖在模块M中的富方法

+0

嘿,这么明显。谢谢!! – 2012-03-22 18:13:06

3

下面是红宝石如何做方法查找:

  1. 接收机的单例类;
  2. 接收者类;
  3. 任何包含的模块方法;
  4. 在接收者的超类中重复查找;
  5. 如果根本找不到方法,method_missing调用;

你可以在这里找到更多的细节:http://ruby-metaprogramming.rubylearning.com/html/ruby_metaprogramming_2.html

因此,找到一种方法,红宝石云在接收器的类,并从那里爬上祖先链,直到找到方法。 此行为也被称为“向右一步,然后向上” 规则:向右步进入接收者的类,然后向上连接到祖先链,直到找到该方法。当您将一个 模块包含在一个类中(或者甚至包含在另一个模块中)时,Ruby将创建一个包装该模块的匿名类,并将匿名类 插入到链中的匿名类,就在包含类本身之上。

+1

直到走完所有的祖先之后,才会检查method_missing – dbenhur 2012-03-22 19:13:14

+0

感谢您注意到,只是修复了它! – andersonvom 2012-03-22 21:52:06

+1

0.接收者的单例类; – 2012-03-23 02:40:37