如何在不创建对象的情况下检查对象是否具有单例类(本征类)

Rem*_*emo 18 ruby

有没有办法检查一个对象是否有一个单独的类而不创建一个?

除了检查对象是否具有单例类之外,每个对象都不具有单例类(参见https://repl.it/DuVJ/2下的证明).

我想到了以下方法,但不起作用:

  1. obj.singleton_class

    如果不存在,则会自动创建一个新的单例类(请参阅 https://ruby-doc.org/core-1.9.2/Object.html#method-i-singleton_class).

  2. 使用ObjectSpace:

    has_singleton_class = ObjectSpace.each_object(Class).any? do |klass|
      klass < self.class && klass.singleton_class? && self.is_a?(klass)
    end
    
    Run Code Online (Sandbox Code Playgroud)

    这非常慢,可能无法在jRuby下工作,因为ObjectSpace可能无法使用.

  3. obj.singleton_methods 仅当单例类至少有一个方法时才有效.

小智 2

您可以使用该ancestors方法。因为您想要检查一个类(而不是对象)是否是单例,所以您可以获取该类中混合的所有模块并验证其中是否有任何一个是单例类。

class Klass
  include Singleton
end

Klass.ancestors.include? Singleton # true
Run Code Online (Sandbox Code Playgroud)

在 ruby​​ 中,为了创建单例,您应该包含一个Singleton模块。因此,如果您检查该模块,则意味着该类是单例。Ruby 的基类继承了模块类,这意味着您可以访问使用该ancestors方法。

参考:

  1. https://ruby-doc.org/core-2.1.0/Module.html#method-i-ancestors
  2. https://ruby-doc.org/core-2.2.0/Class.html
  3. https://ruby-doc.org/stdlib-2.1.0/libdoc/singleton/rdoc/Singleton.html#module-Singleton-label-Usage