为什么`method_missing`没有捕获一些未定义的方法(例如Foo)?

时间:2014-05-07 00:28:47

标签: ruby methods metaprogramming method-missing

我尝试通过以下定义捕获未定义的方法:

def method_missing m
  puts "#{m} is missing"
end

当我在其后面写一个未定义的方法,例如foo时,它会被method_missing捕获:

foo # => foo is missing

但是当我编写一个未定义的方法,例如Foo时,method_missing不会捕获它:

Foo # => NameError: Uninitialized constant Foo

如果它从常量中消除歧义,那么它就会被捕获:

self.Foo # => Foo is missing
Foo() # => Foo is missing

为什么在第一种情况下未捕获Foo?当一个方法在局部变量之间不明确时,它是一个特征,它由method_missing捕获,但不是在一个常量之间是不明确的吗?如果是这样,有关于此的文件吗?或者,这是一个错误吗?

1 个答案:

答案 0 :(得分:7)

事实上,这实际上并不含糊 - 它只是不直观。在Ruby的语法中,以大写字母开头并且后跟参数列表的标识符总是解析为常量查找。

即使您定义了def Foo "You won't see this" end之类的方法,也会得到相同的错误。遇到Foo时,它仍会尝试查找常量Foo,并在找不到该名称的常量时抛出NameError。为了调用以大写字母开头的方法,您必须包含显式接收器(例如self.Foo)或参数列表(如果只是空的)。