簡體   English   中英

Ruby eigenclass意外行為

[英]Ruby eigenclass unexpected behaviour

首先,讓我們添加一個方法來檢索“從此博客帖子中復制”的特征類

class Object 
  def eigenclass 
    class << self
      self
    end 
  end 
end

然后創建一個簡單的類

class A
end

puts A.new.eigenclass.superclass      # => A
puts Class.new.eigenclass.superclass  # => #<Class:Object>

我期待第二次投入輸出Class

任何線索為什么會這樣?

通過puts A.new.eigenclass.superclass ,您#eigenclass在類A的實例上調用#eigenclass 。我將從后台開始解釋eigenclass實際上是如何工作的,然后將繼續告訴代碼中發生了什么。

背景故事:

EigenClass是一個隱藏類,它包含僅適用於該特定對象的單例方法。

所以對於obj = Foo.new ,類層次結構實際上看起來像:

obj --eigenclass - >#> - (超類) - > A.

代替:

obj - (類) - > A.

使用#eigenclass劫持自我后,可以生成隱藏的類。

現在,在Ruby中, Class是一個對象。 這也意味着#eigenclass應該顯示A的隱藏本征類(其中保留了A的sigleton方法)。

A - (本征類) - ># - (超類) - >#

現在它之所以顯示而不是A是因為Ruby以非常漂亮的模式組織了類,超類和特征類。 這可以用示例顯示,而不是用令人困惑的詞語引用它:

A.superclass #=> Object   
A.eigenclass #=> #<Class: A>   
A.eigenclass.superclass #=> #<Class: Object> => Eigenclass of Object   
A.eigenclass.superclass == Object.eigenclass #=> true   

類的本征 的超類是原始的超類的本征

現在, Class.new.eigenclass.superclass你的情況: Class.new.eigenclass.superclass ,現在這是不言自明的。 Class.new對應一個新的匿名類,比如B ,你實際上是在調用eigenclass.superclass 由於B的超類是Object,B的本征類的超類是B的超類的本征類。

我盡力用例子來解釋。 請在下面的評論中進一步澄清; 將相應更新答案。 補充(來自Pragmatic MR): 從語用MR中拍攝

在上圖中, D繼承自C 所以D.eigenclass.superclass是(D的超類)[它是C]的eigneclass。 現在C的超類是Object ..所以是相同的邏輯。

問候

從該博文中,您可以構建一個類似的圖表:

                        +------------------+               +-------------------+
                        |      Object      |- eigenclass ->| Object eigenclass |
                        +------------------+               +-------------------+
                                 ^                                   ^             
                                 | superclass             superclass |                                                     
                        +------------------+               +-------------------+
                        |        A         |- eigenclass ->|    A eigenclass   |
                        +------------------+               +-------------------+
                                 ^
                                 | superclass
+-------+               +------------------+                                   
| A.new |- eigenclass ->| A.new.eigenclass |                                   
+-------+               +------------------+    

試圖找到A實例的本征類的超類表明它指向A類。

A.new.eigenclass.superclass      # => A                               

Class.new返回Class對象的實例,即一個新類。 這是一個類,就像A類一樣。

Class.new.class # => Class
A.class         # => Class

A的超類和Class.new的超類都是隱式的Object

Class.new.superclass # => Object
A.superclass         # => Object

因為A的超類是Object ,A的本征類的超類是Object的特征類。

Object.eigenclass                            # => #<Class:Object>
A.eigenclass.superclass                      # => #<Class:Object>
A.eigenclass.superclass == Object.eigenclass # => true

同樣的,找到的eigenclass的超Class.new產生對象的eigenclass

Class.new.eigenclass.superclass              # => #<Class:Object>

之間的區別Class.newA.newClass.new本身就是一類,因此可以構建新的對象,而A.new不能。

Class.new.new # => #<#<Class:0x007f86b50d8f70>:0x007f86b50d8f20>
A.new.new     # => NoMethodError: undefined method `new' for #<A:0x007f86b50cbf50>

類的本征類具有整個類的本體類的陰影層次,用於類的祖先,它們都在本征類和類之間。 這是因為期望類繼承其祖先的類方法。 例如,如果你確定def Numeric.kind_of_number?() true end ,你會期望Fixnum.kind_of_number? 是真實的。 所以你需要將Numeric的本征類作為Fixnum的本征類的祖先。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM