ruby const_missing方法之谜

时间:2015-09-20 20:26:02

标签: ruby metaprogramming

我正在使用这段代码,纯粹是为了研究ruby对象模型和const查找。

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是在类中完成的,因此'UNKOWNCONST'将触发上面定义的const_missing,它存在于TestClass对象的单例类中,因为它是一个类方法。

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

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

1 个答案:

答案 0 :(得分:1)

问题在于以下几行:

super const_missing(name)

这里有两个陈述:

  • super应该使用与当前方法相同的名称调用超类中定义的方法
  • const_missing(name)调用const_missing

调用父对象的正确方法就是调用super,无需args或传递显式args。在你的例子中,你也可以调用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)