1

我有一些可以简化为以下的代码。它适用于 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]

红宝石 2.3.3

#<Dummy:0x007fbd6d162380>

红宝石 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]

红宝石 2.3.3 和 2.3.4

#<Dummy:0x007fbd6d162380>
4

1 回答 1

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 是开源的。有一个错误 #12478,已在该提交中修复。提交的消息明确指出它在处理非模块对象时会更改行为。

符号不再转换Strings 并单独处理,:TEST不在Dummy级别上扩展,并且常量无法在不同的上下文中解析

为什么它不是错误

在单例类上声明常量没有任何意义(检查你的旧代码):

Dummy.constants
#⇒ []
Dummy.singleton_class.constants
#⇒ [:TEST]

常量在遗留实现中被成功解析,就像将两个负数相乘得到一个正数结果:错误被否定。该代码无法正常工作,它偶尔会以意想不到的方式失败两次,但值得赞赏的方式,产生了正确的结果。

于 2017-05-18T07:53:38.033 回答