Как проверить, имеет ли объект одноэлементный класс (eigenclass) без создания одного
Есть ли способ проверить, имеет ли объект одноэлементный класс без создания?
Кроме того, что указано в Проверить, имеет ли объект одноэлементный класс, неверно, что каждый объект имеет одноэлементный класс (см. доказательство в https://repl.it/DuVJ/2).
В моем сознании появились следующие подходы, но не работают:
-
obj.singleton_class
Это автоматически создает новый одноэлементный класс, если он не существует (см.
https://ruby-doc.org/core-1.9.2/Object.html#method-i-singleton_class).
-
Использование ObjectSpace
:
has_singleton_class = ObjectSpace.each_object(Class).any? do |klass|
klass < self.class && klass.singleton_class? && self.is_a?(klass)
end
Это очень медленно и может не работать под jRuby, поскольку ObjectSpace
может не работать
быть доступным.
-
obj.singleton_methods
работает только в том случае, если класс singleton имеет как минимум
один метод.
Ответы
Ответ 1
Вы можете использовать метод ancestors
. Поскольку вы хотите проверить, является ли класс (а не объект) одиночным, вы можете получить все модули, смешанные внутри класса, и проверить, является ли какой-либо из них одноэлементным классом.
class Klass
include Singleton
end
Klass.ancestors.include? Singleton # true
В рубине для создания синглета вы должны включить модуль Singleton
. Поэтому, если вы проверяете этот модуль, это означает, что этот класс является одноэлементным. Наследование базового класса Ruby класса модуля означает, что у вас есть доступ к методу ancestors
.
Литература: