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

saw*_*awa 2 ruby methods metaprogramming method-missing

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

def method_missing m
  puts "#{m} is missing"
end
Run Code Online (Sandbox Code Playgroud)

当我编写一个未定义的方法,例如foo在它之后,它被捕获method_missing:

foo # => foo is missing
Run Code Online (Sandbox Code Playgroud)

但是当我写一个未定义的方法,例如Foo,它没有被捕获method_missing:

Foo # => NameError: Uninitialized constant Foo
Run Code Online (Sandbox Code Playgroud)

看起来如果它是从常量消除歧义,那么它被捕获:

self.Foo # => Foo is missing
Foo() # => Foo is missing
Run Code Online (Sandbox Code Playgroud)

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

Chu*_*uck 7

事情是,这实际上并不含糊 - 它只是不直观.在Ruby的语法中,以大写字母开头但后面没有参数列表的标识符始终被解析为常量查找.

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