Как проверить, имеет ли объект одноэлементный класс (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.

Литература: