在Ruby中重新打开嵌套模块异常

时间:2013-07-11 09:37:09

标签: ruby module nested

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

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而不是模块名称,但这不是本帖的重点。)

1 个答案:

答案 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而不是。它抛出的错误与它检查的第一个名称有关。