2012-03-22 67 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