Re-opened nested module anomaly in Ruby

自闭症网瘾萝莉.ら 提交于 2019-12-04 12:28:46

问题


Why does re-opening a nested module give different results depending on the syntax used? For example, this works fine:

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

But this:

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

gives the error:

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

(Before someone points this out, a workaround is to use self instead of the module name when defining E.e, but that's not really the point of this post.)


回答1:


The module keyword sets a namespace context that is checked for references to existing names of Modules. These namespaces are then searched inner-to-outer to resolve references to Module (and Class) names.

In your first example, it looks like you may need to define E.e inside module E block, but in fact you don't:

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

What happens in both your examples is that Ruby looks at the current namespace, and tries <namespace>::E as a module name. So in both examples, the first thing it checks is in fact A::E::E which does not exist. Then it falls back to the next context. Which is where the examples differ: In the first example it is A::E which is valid, in the second example, it is just E which is not. The error that it then throws relates to the first name it checked.



来源:https://stackoverflow.com/questions/17589997/re-opened-nested-module-anomaly-in-ruby

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!