我有一些代码可以简化为以下内容。它适用于Ruby 2.3.3并在2.3.4上打破。这有点奇怪,我欢迎有关如何重写它的建议以及解释为什么它会破坏。
require 'forwardable'
class Dummy
class << self
TEST = {
a: Dummy.new,
b: Dummy.new
}
extend Forwardable
def_delegators :TEST, :[]
private :new
end
end
puts Dummy[:a]
Ruby 2.3.3
#<Dummy:0x007fbd6d162380>
Ruby 2.3.4
NameError: uninitialized constant TEST
目标是仅初始化TEST
一次,并将.new
设为私有。在@test
方法中记住[]
变量并不起作用,因为new
在创建哈希时是私有的。
修改
从等式中删除Forwardable可修复问题,但我仍然对如何改进它的原因和想法感到好奇。
class Dummy
class << self
TEST = {
a: Dummy.new,
b: Dummy.new
}
def [](key)
TEST[key]
end
private :new
end
end
puts Dummy[:a]
Ruby 2.3.3和2.3.4
#<Dummy:0x007fbd6d162380>
答案 0 :(得分:2)
require 'forwardable'
class Dummy
Test = {
a: Dummy.new,
b: Dummy.new
}
class << self
extend Forwardable
def_delegators :"::Dummy::Test", :[]
private :new
end
end
puts Dummy[:a]
Ruby是开源的。在bug #12478中修复了that commit。提交的消息明确指出它在处理非模块对象时会改变行为。
符号分别为not converted到String
并单独处理,:TEST
未在Dummy
级别和could not be resolved in different context上展开。
在单例类上声明常量没有任何意义(请查看旧代码):
Dummy.constants
#⇒ []
Dummy.singleton_class.constants
#⇒ [:TEST]
在遗留实现中成功解决了常量,与乘以两个负数得到肯定结果完全相同:错误被否定。代码无法正常工作,它偶尔会以意想不到的方式失败两次,但会产生正确的结果。