rubyconst_missing方法之谜

ruby const_missing method mystery

我在玩这段代码,纯粹是为了研究ruby对象模型和常量查找。

class TestClass

  def self.const_missing(name)
    binding.pry
    super const_missing(name)
  end

  def self.do
    self.class_eval "puts 800; UNKOWNCONST"
  end

end

TestClass.do

由于 class_eval 是在 class 内部完成的,因此 'UNKOWNCONST' 将触发上面定义的 const_missing,它位于 TestClass 的单例 class 中对象,因为它是一个 class 方法。

所以我打算将它委托给普通的 const_missing 方法,但是我最终得到一个错误,说堆栈太深。 binding.pry 表明它进入了我为 class 定义的 const_missing 方法的无限循环,而不是正常的 const_missing 方法。

我想知道为什么?提前致谢。

问题出在下面一行:

super const_missing(name)

这里有两个语句:

  • super期望调用super中定义的方法class与当前方法同名
  • const_missing(name) 调用 const_missing

调用父级的正确方法是调用 super,不带参数或传递显式参数。相反,在您的示例中,您还调用了 const_missing(name) 并且将会发生的是 super 永远不会被调用,因为您将进入一个递归循环,其中 const_missing 不断调用自身。

正确的代码是

  def self.const_missing(name)
    binding.pry
    super(name)
  end

这实际上会按预期触发错误

$ ruby test.rb
800
test.rb:9:in `class_eval': uninitialized constant TestClass::UNKOWNCONST (NameError)