2014-01-11 61 views
7

假設我們有這樣的Ruby類:存儲Ruby Class Singleton常量的位置?

class MyClass 
    class << self 
    MC_CONST = 30 
    end 
end 

那麼,讓我們來實例化MyClass和另一個常量添加到對象的元類:

m = MyClass.new 
class << m 
    OBJ_MC_CONST = 50 
end 

有與對象的單身常數沒有任何問題:

m.singleton_class::OBJ_MC_CONST # => 50 <-- [OK] 
m.singleton_class.constants.include? :OBJ_MC_CONST # => true <- [OK] 

但並不完全是我期望與班級單身常數:

MyClass.singleton_class::MC_CONST # => 30 <-- [OK] 
MyClass.singleton_class.const_get :MC_CONST # => 30 <-- [OK] 
MyClass.singleton_class.constants.include? :MC_CONST # => false <-- [Why???] 

爲什麼地球上的.constants方法在元類MyClass上返回的類不包含:MC_CONST?我在這裏錯過了什麼?

謝謝。


編輯1:但這似乎是在MRI 2.x中的錯誤畢竟。我已經向Ruby核心團隊提出了一個新問題:https://bugs.ruby-lang.org/issues/9413來解決這個問題。

編輯2:這個bug顯然已經固定在https://bugs.ruby-lang.org/projects/ruby-trunk/repository/revisions/44628/diff/

回答

5

我探討這個問題一點,我認爲它是由MRI的錯誤/不一致/特質造成的。

在MRI 2.1.0,此代碼:

class MyClass 
    class << self 
    MC_CONST = 30 
    end 
end 

p MyClass.singleton_class.const_defined? :ABBA_CONST, false 
p MyClass.singleton_class.const_defined? :MC_CONST, false 
p MyClass.singleton_class.constants(false) 

產生

false 
true 
[] 

所以MC_CONST常量的定義,但它不能作爲一個類的局部常量(I」 m將false傳遞給各種方法來禁用常量解析,並將其保留在該類的本地),這應該是真的。如果我們查看Module#constants的文檔,它會顯示:

返回mod中可訪問常量的名稱數組。該 包括任何包含模塊中的常量名稱(例如,在 節開始處),除非all參數設置爲false。

另請參閱Module :: const_defined?

因此它告訴我們檢查const_defined?以更好地理解constants的行爲,但這兩種方法會給出不同的結果!


此外,在其他Ruby實現中,此代碼按預期工作。

在JRuby上1.7。9,它產生:

false 
true 
[:MC_CONST] 

從事Rubinius 2.2.1,它產生:

false 
true 
[:MC_CONST] 

這是預期的行爲:)

+0

感謝您的輸入。我確實似乎是當前MRI的一個缺陷。我已經向Ruby核心團隊提出了一個新問題。我將用問題URL更新描述。 – demisx