2012-07-30 19 views
1

我有這樣的代碼:常量在單班

class A 
    def print 
    puts CONSTANT 
    end 
end 

module B 
    CONSTANT = "Don't Panic!" 
end 

假設a是A類的一個實例

所以,我需要的CONSTANT應該能夠定義被發現,使a.print可用。

我認爲包括模塊Ba的單例類,如:

a.singleton_class.send :include, B 

a.print # error: CONSTANT isn't found 

我以爲這應該沒問題,現在要調用的方法,但實際上不是。

常量應成功導入爲下面的代碼工作的期望:

a.singleton_class.constants # => [.., :CONSTANT, ..] 

然而,包括恆進的類,而不是單例類,它的工作原理:

a.class.send :include, B 

a.print # prints: Don't Panic! 

我覺得很奇怪,我不能引用在單例類中定義的常量。如果這是合理的,我想知道爲什麼。

在此先感謝。

回答

2

singleton_class返回的類是從對象a的類繼承的匿名類。

所以a.classa.singleton_class指的是不同的對象。

puts a.class.object_id   # => 79495930 
puts a.singleton_class.object_id # => 79495830 

以及不同類別:a.singleton_class是一個子類的A

a.singleton_class.superclass # => A 

a.singleton_class.ancestors # => [B, A, Object, Kernel, BasicObject] 
a.class.ancestors   # => [A, Object, Kernel, BasicObject] 

因爲這個而,a.singleton_class不同意自己的常量於母公司就像任何其他子類來完成。

puts a.class.constants    # => [] 
puts a.singleton_class.constants # => [:CONSTANT] 
+0

謝謝你。我知道這一點,但它仍然很奇怪,因爲Ruby並沒有將在其單例類中定義的常量視爲可訪問的類,而只是將其定義爲類。這是一個錯誤還是某種功能? – 2012-07-31 00:52:18

+0

謝謝你,有趣的問題。老實說,我認爲沒關係。 Singleton類應該是繼承的匿名類,這就是繼承的工作方式 - 在子類中定義的常量(或方法)不應出現在父類中。如果我們違反了這條規則,那麼我們就失去了繼承的想法,恐怕它可能導致糟糕的設計。 – 2012-08-01 15:22:13