[英]Ruby eigenclass unexpected behaviour
First, let's add a method to retrieve eigenclass "copied from this blog post " 首先,让我们添加一个方法来检索“从此博客帖子中复制”的特征类
class Object
def eigenclass
class << self
self
end
end
end
Then create a simple class 然后创建一个简单的类
class A
end
puts A.new.eigenclass.superclass # => A
puts Class.new.eigenclass.superclass # => #<Class:Object>
I was expecting the second puts to output Class 我期待第二次投入输出Class
Any clue why this happened? 任何线索为什么会这样?
By puts A.new.eigenclass.superclass
, you are effectively calling #eigenclass
on the instance of class A. I will begin with backstory to explain how eigenclass actually works, and will then proceed to tell what is happening in your code. 通过
puts A.new.eigenclass.superclass
,您#eigenclass
在类A的实例上调用#eigenclass
。我将从后台开始解释eigenclass实际上是如何工作的,然后将继续告诉代码中发生了什么。
BackStory: 背景故事:
EigenClass is a hidden class which contains the singleton methods available for that specific object only. EigenClass是一个隐藏类,它包含仅适用于该特定对象的单例方法。
So for obj = Foo.new
, the class hierarchy actually looks like: 所以对于
obj = Foo.new
,类层次结构实际上看起来像:
obj --eigenclass--> #> --(superclass)--> A
obj --eigenclass - >#> - (超类) - > A.
instead of: 代替:
obj --(class)--> A
obj - (类) - > A.
A hidden class can be produced after you hijacked the self with #eigenclass
. 使用
#eigenclass
劫持自我后,可以生成隐藏的类。
Now, in Ruby, Class is an object. 现在,在Ruby中, Class是一个对象。 This also means that
#eigenclass
should show the the hidden eigenclass of A
too (where A's sigleton methods are kept). 这也意味着
#eigenclass
应该显示A
的隐藏本征类(其中保留了A的sigleton方法)。
A --(eigenclass)--> # --(superclass)--> #
A - (本征类) - ># - (超类) - >#
Now the reason why it shows # instead of A
is because Ruby organizes the classes, superclasses and eigenclasses in a very beautiful pattern. 现在它之所以显示#而不是
A
是因为Ruby以非常漂亮的模式组织了类,超类和特征类。 This can be shown with example instead of quoting it in confusing words: 这可以用示例显示,而不是用令人困惑的词语引用它:
A.superclass #=> Object
A.eigenclass #=> #<Class: A>
A.eigenclass.superclass #=> #<Class: Object> => Eigenclass of Object
A.eigenclass.superclass == Object.eigenclass #=> true
The superclass of an eigenclass of a class is the eigenclass of the superclass of the original class . 类的本征 类的超类是原始类的超类的本征类 。
Now, coming to your case: Class.new.eigenclass.superclass
, this is self-explanatory now. 现在,
Class.new.eigenclass.superclass
你的情况: Class.new.eigenclass.superclass
,现在这是不言自明的。 Class.new
corresponds to a new anonymous class, say B
, and you are effectively calling eigenclass.superclass
on it. Class.new
对应一个新的匿名类,比如B
,你实际上是在调用eigenclass.superclass
。 Since the superclass of B
is Object, the superclass of eigenclass of B is the eigenclass of superclass of B
. 由于
B
的超类是Object,B的本征类的超类是B
的超类的本征类。
Tried my best to explain with examples. 我尽力用例子来解释。 Please feel free to clarify it further in comments below;
请在下面的评论中进一步澄清; will update the answer accordingly.
将相应更新答案。 Complementary(from Pragmatic MR):
补充(来自Pragmatic MR):
.
。
In the figure shown above, D
inherits from C
. 在上图中,
D
继承自C
So D.eigenclass.superclass
is the eigneclass of (superclass of D)[which is C]. 所以
D.eigenclass.superclass
是(D的超类)[它是C]的eigneclass。 Now C's superclass is Object.. and so is the same logic. 现在C的超类是Object ..所以是相同的逻辑。
Regards 问候
From that blogpost, you can construct a similar diagram: 从该博文中,您可以构建一个类似的图表:
+------------------+ +-------------------+
| Object |- eigenclass ->| Object eigenclass |
+------------------+ +-------------------+
^ ^
| superclass superclass |
+------------------+ +-------------------+
| A |- eigenclass ->| A eigenclass |
+------------------+ +-------------------+
^
| superclass
+-------+ +------------------+
| A.new |- eigenclass ->| A.new.eigenclass |
+-------+ +------------------+
Trying to find the superclass of the eigenclass of an instance of A shows that it points to the A
class. 试图找到A实例的本征类的超类表明它指向
A
类。
A.new.eigenclass.superclass # => A
Class.new
returns an instance of a Class object, ie a new class. Class.new
返回Class对象的实例,即一个新类。 It is a class, just like the A
class. 这是一个类,就像
A
类一样。
Class.new.class # => Class
A.class # => Class
A's superclass and Class.new's superclass are both implicitly Object
. A的超类和Class.new的超类都是隐式的
Object
。
Class.new.superclass # => Object
A.superclass # => Object
Because A's superclass is Object
, A's eigenclass's superclass is Object's eigenclass. 因为A的超类是
Object
,A的本征类的超类是Object的特征类。
Object.eigenclass # => #<Class:Object>
A.eigenclass.superclass # => #<Class:Object>
A.eigenclass.superclass == Object.eigenclass # => true
Similarly, finding the superclass of the eigenclass of Class.new
yields Object's eigenclass 同样的,找到的eigenclass的超
Class.new
产生对象的eigenclass
Class.new.eigenclass.superclass # => #<Class:Object>
The difference between Class.new
and A.new
is that Class.new
is itself a class and so can construct new objects, while A.new
cannot. 之间的区别
Class.new
和A.new
是Class.new
本身就是一类,因此可以构建新的对象,而A.new
不能。
Class.new.new # => #<#<Class:0x007f86b50d8f70>:0x007f86b50d8f20>
A.new.new # => NoMethodError: undefined method `new' for #<A:0x007f86b50cbf50>
A class's eigenclass has a whole shadow hierarchy of eigenclasses for the class's ancestors that all go between the eigenclass and Class. 类的本征类具有整个类的本体类的阴影层次,用于类的祖先,它们都在本征类和类之间。 This is because classes are expected to inherit their ancestors' class methods.
这是因为期望类继承其祖先的类方法。 For example, if you did
def Numeric.kind_of_number?() true end
, you would expect Fixnum.kind_of_number?
例如,如果你确定
def Numeric.kind_of_number?() true end
,你会期望Fixnum.kind_of_number?
to be true. 是真实的。 So you need to have Numeric's eigenclass as an ancestor of Fixnum's eigenclass.
所以你需要将Numeric的本征类作为Fixnum的本征类的祖先。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.