2011-03-14 64 views
8

定義const_missingclass << self定義中的其他類方法時,Ruby的行爲與使用def self.foo語法相反,我非常困惑。「class << self」定義中缺少常量和「const_missing」

我試圖做這樣的事情:

class Foo 
    class << self 
    def foo 
     puts MISSING 
    end 

    def const_missing(name) 
     puts "#{name} missing" 
    end 
    end 
end 

Foo.foo 

我大多使用的class << self語法來定義類的方法。但是,它沒有按預期工作。永遠不會調用const_missing。上面的結果是一個NameError。

定義兩種方法這樣按預期工作:

def self.foo 
    puts MISSING 
end 

def self.const_missing(name) 
    puts "#{name} missing" 
end 

我認爲class << self語法只是另一種方式來定義類的方法,但完全等同於def self.foo?我已經用MRI 1.8.7,1.9.2和JRuby 1.5.6測試了上述內容。很顯然,我在這裏錯過了一些東西?

任何提示是非常感謝。

謝謝,馬丁

回答

12

class << self不是一個快捷方式來定義類的方法。這個語法(我不知道確切的命名)從一個對象(在你的案例中,一個類)中打開了本徵類。有了這個,你可以定義方法的對象(不是實例方法)。但是當你將一個常量調用到本徵類時,就是從本徵類中調用一個常量,而不是從類中調用常量。在這種情況下,你必須定義在eigenclass類方法的const_missing,兩種方式做到這一點:

class Test 
    class << self 
    def foo 
     p MISSING 
    end 

    # First way: (syntax sugar for the second way) 
    def self.const_missing(name) 
     name 
    end 

    # Second way: 
    class << self # eigenclass of the eigenclass of the class 
     def const_missing(name) 
     name 
     end 
    end 

    end 
end 

Test.foo #=> :MISSING 
+0

非常感謝,LBG。我知道'class << self'打開了一個類的特徵類。但是因爲類方法只是本徵類的實例方法,所以我認爲它會以這種方式工作。然而,從特徵類引用的常量與從類本身引用的常量不同,這是非常有意義的。有時這整件事讓我的頭旋轉:) – martido

相關問題