繁体   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