检查对象是否具有单例类

时间:2013-05-11 20:17:45

标签: ruby singleton

我正在编写一个方法foo的模块,它在接收者的类上调用类方法bar。我目前的方法是使用self.class.bar,除非在实例类中定义类方法而不是“真实”类方法,否则它会正常工作:

module M
  def foo
    self.class.bar
  end
end

obj = Object.new
class << obj
  include M
  def self.bar
    42
  end
end

obj.foo # => NoMethodError: undefined method `bar' for Object:Class

这是有道理的,因为obj.class不返回单例类。我可以使用obj.singleton_class代替,一切都会顺利进行:

module M
  def foo
    self.singleton_class.bar
  end
end

obj = Object.new
class << obj
  include M
  def self.bar
    42
  end
end

obj.foo # => 42

仅当方法是在单例类上定义时出于与上述相同的原因。更糟糕的是,它为每个接收器创建了一个新的单例类,我想避免这些类,因为这些可能是相当多的对象。所以相反,我想要一些方法来检索一个对象的单例类当且仅当它已被定义时,即类型为obj.has_singleton_class ? obj.singleton_class : obj.class的东西。我找不到任何方法来执行这项检查。

1 个答案:

答案 0 :(得分:5)

每个对象在Ruby中总是有一个单例类。您使用的具体实现(MRI,YARV,Rubinius,JRuby,IronRuby,MacRuby,MagLev,MRuby等)可能会也可能不会通过不为未使用的单例类分配内存来优化内存使用,但这是私有的内部实现细节,一个不可见的透明编译器优化。每当你去寻找一个单身课时,它就会在那里。

嗯,实际上,那不是相当是真的。即时值,即Integer s,SymbolFloat s 不能具有单例类。

所以,这三个人从不有一个单独的类,其他所有总是都有一个单例类。