阅读关于Rails命名空间和模块查找的这篇非常好的文章。 Here
我不明白这意味着什么:
如果仅在第一次遇到常量时才加载常量 运行时,然后必要时它们的加载顺序取决于个人 执行路径。
什么是individual execution path
?
我认为不理解导致我不明白这一点:
一旦遇到已经加载的常量Baz,Rails就知道了 这不是它正在寻找的Baz,算法提出了一个 NameError。
或更重要的是:
与以前一样,第一次归结于嵌套信息的丢失。 Rails不知道Foo :: Qux不是我们追求的,所以一旦它 意识到Foo :: Bar :: Qux不存在,它很乐意加载它。
然而,第二次,Foo :: Qux已经加载。所以我们的引用不可能是那个常量,否则Ruby会有 解决了它,并且永远不会调用自动加载。所以 查找以NameError终止,即使我们的引用可以 (并且应该)已经解决了尚未卸载的:: Qux。
为什么rails不使用已经加载的常量?另外为什么跑:
Foo::Bar.print_qux
两次导致两种不同的结果?
答案 0 :(得分:1)
“执行路径”是指代码运行的方式。如果在X::Y
块中有一个类if
的引用未执行,则表示您的执行路径绕过它,因此未加载。
这与在解析时强制加载代码中引用的所有类不同。当且仅当执行了给定的代码行时,它们才被简单地加载。
自动加载器有一个策略,尝试从最具体的名称开始加载模块,然后查找越来越全局的名称。 Qux
针对当前模块上下文进行测试,然后根据该模块进行测试,依此类推。这就是解决符号的方法。
在该示例中,自动加载版本实际上在优先级方面将Foo::Qux
定义推到::Qux
之前。那是那里的重大变化。