在Ruby中重新打开嵌套模块exception

为什么重新打开嵌套模块会根据使用的语法给出不同的结果? 例如,这很好用:

module A module E end end module A module E def Ee end end end 

但是这个:

 module A module E end end module A::E def Ee end end 

给出错误:

 reopen.rb:6:in `': uninitialized constant A::E::E (NameError) from reopen.rb:5:in `' 

(在有人指出这一点之前,解决方法是在定义Ee时使用self而不是模块名称,但这不是这篇文章的重点。)

module关键字设置一个名称空间上下文,该名称空间上下文被检查以引用模块的现有名 然后从内到外搜索这些名称空间以解析对模块(和类)名称的引用。

在您的第一个示例中, 看起来您可能需要在module E块中定义Ee ,但事实上您不需要:

 module A module E end end module A def Ee end end 

在您的示例中发生的是Ruby查看当前名称空间,并尝试::E作为模块名称。 所以在这两个例子中,它检查的第一件事实际上是A::E::E ,它不存在。 然后它回到下一个上下文。 这是示例不同的地方:在第一个示例中, A::E是有效的,在第二个示例中,它只是E而不是。 它抛出的错误与它检查的第一个名称有关。