[英]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): 。
在上圖中, 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.new
和A.new
是Class.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.