7

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

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>'

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

4

1 回答 1

4

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

在您的第一个示例中,您可能需要定义内部块,但实际上您不需要:E.emodule E

module A
  module E
  end
end
module A
  def E.e
  end
end

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

于 2013-07-11T10:50:08.083 回答