这个问题很难说出来。所有对象都有一个singleton类(又名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
是它本身的一个实例。
因此,我们可以看到singleton类是类型为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
答案 0 :(得分:0)
从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]