根据文档mod.const_get(sym)
“返回 mod 中指定常量的值。”
我也知道const_get
默认情况下可以查找接收者的继承链。所以以下工作:
class A; HELLO = :hello; end
class B < A; end
B.const_get(:HELLO) #=> :hello
我也知道 Ruby 子类中的类Object
,这样你就可以使用const_get
即使接收者是普通类,也要查找“全局”常量:
class C; end
C.const_get(:Array) #=> Array
然而,这就是我感到困惑的地方——模块不会子类化Object
。那么为什么我仍然可以使用以下命令从模块中查找“全局”常量const_get
?为什么下面的方法有效?
module M; end
M.const_get(:Array) #=> Array
如果文档正确 -const_get
只需查找接收者或其超类下定义的常量即可。但在上面的代码中,Object
不是一个超类M
,那么为什么可以查找Array
?
Thanks
你感到困惑是正确的......该文档没有说明 Ruby 为查找常量提供了特殊情况Modules
并已修改明确说明这一点 http://ruby-doc.org/core-1.9.3/Module.html#const_get-method。如果在正常层次结构中没有找到该常量,Ruby 会从以下位置重新开始查找:Object
,可以是在源码中找到 http://github.com/ruby/ruby/blob/v1_9_2_preview3/variable.c#L1594.
持续查找本身可能会有点令人困惑。举个例子:
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
不过,在这两个地方都可以访问Object
电平常数如Array
很好(感谢上帝!)。发生的事情是 Ruby 维护了一个“打开的模块定义”列表。如果常量有明确的作用域,比如LookHereOnly::Foo
, then only LookHereOnly
及其包含的模块将被搜索。如果没有指定范围(例如Foo
在上面的示例中),Ruby 将查找打开的模块定义以查找常量Foo
: M::N
, then M
最后Object
。最顶层打开的模块定义始终是Object
.
So M::N.const_get :Foo
相当于访问Foo
当开设的课程只有M::N
and Object
,就像我示例的最后一部分一样。
我希望我做对了,因为我自己仍然对不断的查找感到困惑:-)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)