Вопрос довольно сложен в слове. Все объекты имеют одноэлементный класс (он же класс-призрак), который является классом, в котором мы можем определять методы только для этого объекта.
Но когда мы проверяем одноэлементный класс, мы видим, что это экземпляр класса, которыйоба они один и тот же объект.
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