为什么重新打开嵌套模块会根据使用的语法给出不同的结果?例如,这很好用:
module A
module E
end
end
module A
module E
def E.e
end
end
end
但是这个:
module A
module E
end
end
module A::E
def E.e
end
end
给出错误:
reopen.rb:6:in `<module:E>': uninitialized constant A::E::E (NameError)
from reopen.rb:5:in `<main>'
(在有人指出这一点之前,解决方法是在定义E.e时使用self
而不是模块名称,但这不是本帖的重点。)
答案 0 :(得分:4)
module
关键字设置命名空间上下文,检查其是否对模块的现有名称的引用。然后从内到外搜索这些名称空间以解析对模块(和类)名称的引用。
在您的第一个示例中,看起来就像您可能需要在E.e
块中定义module E
,但事实上您不需要:
module A
module E
end
end
module A
def E.e
end
end
在您的示例中,Ruby会查看当前的命名空间,并尝试<namespace>::E
作为模块名称。因此,在这两个示例中,它检查的第一件事实际上是A::E::E
,它不存在。然后它回到下一个上下文。这是示例的不同之处:在第一个示例中,A::E
是有效的,在第二个示例中,它只是E
而不是。它抛出的错误与它检查的第一个名称有关。