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

时间:2016-10-12 15:48:32

标签: ruby

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

Check if an object has a singleton class中所述之外,并非每个对象都有一个单例类(参见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
    

    这非常慢,可能无法在jRuby下工作,因为ObjectSpace可能不会 可用。

  3. obj.singleton_methods仅在单例类至少有效时才有效 一种方法。

2 个答案:

答案 0 :(得分:0)

ancestors方法返回与方法查找序列对应的类和模块的有序列表。下面的例子,。的实例 在调用A#method_missing之前,类CheckKlass将在CheckKlass,Object,Kernel和BasicObject中搜索方法。

class CheckKlass; end
CheckKlass.ancestors # => [CheckKlass, Object, Kernel, BasicObject]

如果包含Singleton,这将如下所示

class CheckKlass
  include Singleton
end

这可以给你=&gt;

[CheckKlass, Singleton, ActiveSupport::ToJsonWithActiveSupportEncoder, Object, PP::ObjectMixin, ActiveSupport::Dependencies::Loadable, JSON::Ext::Generator::GeneratorMethods::Object, ActiveSupport::Tryable, Kernel, BasicObject]

答案 1 :(得分:0)

我发现一个简单的方法是尝试:

Marshal.dump obj

如果 obj 有一个单例类(没有自定义序列化策略),我们将得到一个 TypeError

TypeError: singleton can't be dumped