这个问题很难说出来。所有对象都有一个单例类(又名 ghost 类(,这是一个我们可以在该类上为该对象定义方法的类。
但是当我们检查单例类时,我们看到它是一个类的实例,两者都是同一个对象。
o = Object.new
o.singleton_class.instance_eval { self.object_id } # => 47082984969880
o.singleton_class.class_eval { self.object_id } # => 47082984969880
这是因为单例类是匿名类。
o.singleton_class # => #<Class:#<Object:0x0000557ed623d8b8>>
o.singleton_class.name # => nil
匿名类是类型Class
的类
o.singleton_class.class # => Class
Class
的等级是Class
:
Class.class # => Class
Class.new.class == Class # => true
Class
本身就是一个实例。
因此我们可以看到单例类是一个类型的匿名类Class
,它们是Class
的相同实例
Class.object_id # => 47001622014720
o.singleton_class.class.object_id # => 47001622014720
但是为什么使用class_eval
和instance_eval
我们得到相同的对象,但查看没有 eval 的实例和类,我们却没有呢?
o.singleton_class.instance_eval { self.object_id } # => 47082984969880
o.singleton_class.class_eval { self.object_id } # => 47082984969880
o.singleton_class.object_id # => 47082984969880
o.singleton_class.class.object_id # => 47001622014720
你从 o.singleton_class.class.object_id 获取47001622014720的位置实际上与Class.object_id相同,这也应该产生47001622014720。
更进一步,尝试祖先而不是object_id,看看你是否能对正在发生的事情有更多的了解。
o.singleton_class.instance_eval { self.ancestors } # => [#<Class:#<Object:0x00007f9b3c0465d0>>, Object, Kernel, BasicObject]
o.singleton_class.class_eval { self.ancestors } # => [#<Class:#<Object:0x00007f9b3c0465d0>>, Object, Kernel, BasicObject]
o.singleton_class.ancestors # => [#<Class:#<Object:0x00007f9b3c0465d0>>, Object, Kernel, BasicObject]
o.singleton_class.class.ancestors # => [Class, Module, Object, Kernel, BasicObject]