1

我正在编写一个带有 method 的模块,它在接收者的类上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。不过,我找不到任何方法来执行此检查。

4

1 回答 1

5

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

嗯,实际上,这并不完全正确。立即值,即Integers、Symbols 和Floats不能有单例类。

所以,这三个永远不会有一个单例类,所有其他人总是有一个单例类。

于 2013-05-12T01:17:28.700 回答