Class 关卡常量在 Ruby 2.3.4 中被破坏
Class level constant broken in Ruby 2.3.4
我有一些代码可以简化为以下内容。它适用于 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]
Ruby2.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>
如何修复
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, fixed in that commit。提交的消息明确指出它在处理 非模块对象 .
时改变了行为
符号为not converted to String
s anymore and dealed separately, :TEST
is not expanded on Dummy
level and the constant could not be resolved in different context。
为什么这不是错误
在单例上声明常量没有任何意义 类(检查您的旧代码):
Dummy.constants
#⇒ []
Dummy.singleton_class.constants
#⇒ [:TEST]
常数在遗留实现中成功解决,与乘以两个负数得到正结果完全相同:错误被否定。代码运行不正常,偶尔会以意想不到的方式失败两次,但会产生正确的结果。
我有一些代码可以简化为以下内容。它适用于 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]
Ruby2.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>
如何修复
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, fixed in that commit。提交的消息明确指出它在处理 非模块对象 .
时改变了行为符号为not converted to String
s anymore and dealed separately, :TEST
is not expanded on Dummy
level and the constant could not be resolved in different context。
为什么这不是错误
在单例上声明常量没有任何意义 类(检查您的旧代码):
Dummy.constants
#⇒ []
Dummy.singleton_class.constants
#⇒ [:TEST]
常数在遗留实现中成功解决,与乘以两个负数得到正结果完全相同:错误被否定。代码运行不正常,偶尔会以意想不到的方式失败两次,但会产生正确的结果。