为什么单例类是自身的实例?

  • 本文关键字:实例 单例类 ruby
  • 更新时间 :
  • 英文 :


这个问题很难说出来。所有对象都有一个单例类(又名 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_evalinstance_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]

最新更新