根据文档mod.const_get(sym)"返回mod中命名常量的值".
我也知道const_get默认情况下可以查找接收器的继承链.以下是有效的:
class A; HELLO = :hello; end
class B < A; end
B.const_get(:HELLO) #=> :hello
Run Code Online (Sandbox Code Playgroud)
我也知道Ruby子类中的类Object,因此const_get即使接收器是普通类,您也可以使用查找"全局"常量:
class C; end
C.const_get(:Array) #=> Array
Run Code Online (Sandbox Code Playgroud)
然而,这是我困惑的地方 - 模块不是子类Object.那么为什么我仍然可以使用模块查找"全局"常量const_get?为什么以下工作?
module M; end
M.const_get(:Array) #=> Array
Run Code Online (Sandbox Code Playgroud)
如果文档是正确的 - const_get只需查找接收器或其超类下定义的常量.但是在上面的代码中,Object不是超类M,为什么有可能查找Array?
谢谢
Mar*_*une 11
你是混淆的正确...文档没有声明Ruby为查找常量Modules而特殊情况,并且已被修改为明确说明.如果在常规层次结构中未找到常量,则Ruby将重新启动查找Object,如源中所示.
常量查找本身可能有点令人困惑.请看以下示例:
module M
Foo = :bar
module N
# Accessing Foo here is fine:
p Foo # => bar
end
end
module M::N
# Accessing Foo here isn't
p Foo # => uninitialized constant M::N::Foo
end
p M::N.const_get :Foo # => uninitialized constant M::N::Foo
Run Code Online (Sandbox Code Playgroud)
但是,在这两个地方,访问Object级别常量Array都很好(感谢上帝!).发生的事情是Ruby维护着一个"打开的模块定义"列表.如果常量具有明确的范围,LookHereOnly::Foo那么只会 LookHereOnly搜索其包含的模块.如果没有指定范围(Foo如上例所示),Ruby将查看打开的模块定义以查找常量Foo:M::N,然后M和最后Object.始终是最顶层打开的模块定义Object.
所以M::N.const_get :Foo相当于访问Foo时打开类仅M::N和Object,就像在我的例子的最后一部分.
我希望我能做到这一点,因为我仍然对自己不断的查询感到困惑:-)
| 归档时间: |
|
| 查看次数: |
9526 次 |
| 最近记录: |