2014-02-09 118 views
1

我繼續關於Ruby的研究,並且發生了另一個問題。我知道當我們在一個類上定義一個類方法時,它創建了一個單例類來獲得該方法的定義,並且從那以後,該方法是該單例類的一個實例方法(我從測試中得到了這個結論,但我可能是錯的,所以請隨時糾正我)。一個類如何調用一個在單例類中定義的類方法?

我的問題是,如果方法是作爲該類的實例方法在單例類上定義的,我如何使用X.classMethod調用類X上的類方法(我不問我該如何去做。這是發生了什麼。)。它讓我更加困惑,因爲我注意到(運行一些測試)一個類的單例類與它所來自的類甚至沒有層次關係,因此,如何將類方法調用解析爲單例類?更確切地說,該類如何在沒有任何實例的實例方法的單例類上調用一個方法。

我希望我不會混淆你。

再次感謝您。

回答

2

我將與下面的例子開始:

class Foo 
    def self.bar 
    puts 12 
    end 
end 

Foo.singleton_methods # => [:bar] 
Foo.ancestors # => [Foo, Object, Kernel, BasicObject] 

在Ruby類(多個)也是對象。現在這裏#barFoo的單例方法。當你做Foo.bar時,Foo首先在它的單例類中搜索到,然後向上溯源鏈單例類單身類屬於鬼類,因此它在祖先鏈中是不可見的,但它在那裏。語言設計者故意隱藏輸出Foo.ancestors單身方法由對象(此處爲FOO)直接調用,其上創建了單例(每個對象基類)類。 您無法創建單例類的實例。

這裏就是一個證明:

Foo.singleton_class.new # can't create instance of singleton class (TypeError) 

千萬記住還有的一類特殊方法在這裏說Bar,也提供給它的子類(這裏Foo)。因爲元類的Bar變成的超類的元類Foo,當你編寫class Foo < Bar..

class Bar 
    def self.biz 
    puts 11 
    end 
end 

class Foo < Bar 
    def self.bar 
    puts 12 
    end 
end 

Bar.singleton_class # => #<Class:Bar> 
Foo.singleton_class.superclass # => #<Class:Bar> 
+0

的確如此,但是,如果#bar是Foo的單例類的實例方法,如果沒有單例類的實例需要調用它怎麼會被調用? – BrunoMCBraga

+0

@returnFromException你明白了嗎? –

+0

退貨,需要證明? 'Foo.singleton_class.new#=> TypeError:無法創建單例類的實例' –

1

第一個問題,假設X類是含有以下的東西:的X.singleton_class

class X 
    def self.class_method 
    end 
end 

然後class_method是一個實例方法,你可以看到,通過運行

​​

爲了瞭解singleton類如何與類層次結構相關,我發現這樣的圖表很有用(eigenclass是單例類的另一個名稱):

enter image description here

該圖後,我認爲這是一個有點複雜,但使用的邏輯,似乎更有必要,假設如下假設成立:

  1. 一切都是對象
  2. 每對象有一個類
  3. 類可以有其他類沒有的方法

從1開始,我們可以推出類是對象,從2開始,我們可以推導出類必須有類。但爲了滿足3,我們需要在XClass之間的一些類,以便類可以擁有其他類無法訪問的方法。單身人士課程是這三個假設的必然結果。

相關問題