Ruby Class Singleton常量存储在哪里?

时间:2014-01-11 00:37:29

标签: ruby singleton constants

我们假设我们有这个Ruby类:

class MyClass
  class << self
    MC_CONST = 30
  end
end 

然后,让我们实例化MyClass并向对象的元类添加另一个常量:

m = MyClass.new
class << m
  OBJ_MC_CONST = 50
end

对象单例常量没有问题:

m.singleton_class::OBJ_MC_CONST # => 50 <-- [OK]
m.singleton_class.constants.include? :OBJ_MC_CONST # => true <- [OK]

但不完全是我对类单例常量的期望:

MyClass.singleton_class::MC_CONST # => 30 <-- [OK]
MyClass.singleton_class.const_get :MC_CONST # => 30 <-- [OK]
MyClass.singleton_class.constants.include? :MC_CONST # => false <-- [Why???]

为什么在.constants类的元类上由MyClass方法返回的数组不包含:MC_CONST?我在这里缺少什么?

谢谢。


编辑1:毕竟这似乎是MRI 2.x中的一个错误。我已经向Ruby核心团队提出了一个新问题:https://bugs.ruby-lang.org/issues/9413来解决这个问题。

编辑2: https://bugs.ruby-lang.org/projects/ruby-trunk/repository/revisions/44628/diff/

中明显修复了此错误

1 个答案:

答案 0 :(得分:5)

我已就这个问题进行了一些探讨,我认为这是由于MRI的错误/不一致/特质造成的。

在MRI 2.1.0上,此代码:

class MyClass
  class << self
    MC_CONST = 30
  end
end 

p MyClass.singleton_class.const_defined? :ABBA_CONST, false
p MyClass.singleton_class.const_defined? :MC_CONST, false
p MyClass.singleton_class.constants(false)

产量

false
true
[]

因此定义了MC_CONST常量,但它不能作为类的局部常量(我将false传递给各种方法以禁用常量分辨率并将其保持为局部值它应该是确实的。如果我们查看Module#constants的文档,则说:

  

返回mod中可访问的常量名称数组。这个   包括任何包含的模块中的常量名称(例如,   除非all参数设置为false。

     

另见 Module :: const_defined?

因此它告诉我们检查const_defined?以更好地理解constants的行为,但这两种方法会产生不同的结果!


此外,在其他Ruby实现上,此代码按预期工作。

在JRuby 1.7.9上,它产生:

false
true
[:MC_CONST]

在Rubinius 2.2.1上,它产生:

false
true
[:MC_CONST]

预期的行为是什么:)