Почему синглтон-класс сам по себе является экземпляром? - PullRequest
2 голосов
/ 01 октября 2019

Вопрос довольно сложен в слове. Все объекты имеют одноэлементный класс (он же класс-призрак), который является классом, в котором мы можем определять методы только для этого объекта.

Но когда мы проверяем одноэлементный класс, мы видим, что это экземпляр класса, которыйоба они один и тот же объект.

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

1 Ответ

0 голосов
/ 01 октября 2019

Если вы получаете 47001622014720 из o.singleton_class.class.object_id, то же самое, что и 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]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...