gpt4 book ai didi

ruby - Ruby 中 const_get 的混淆行为?

转载 作者:数据小太阳 更新时间:2023-10-29 06:31:10 28 4
gpt4 key购买 nike

根据文档 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 只是查找在接收器或其父类(super class)下定义的常量。但是在上面的代码中,Object 不是 M 的父类(super class),那么为什么可以查找 Array 呢?

谢谢

最佳答案

你的困惑是正确的......文档没有说明 Ruby 在 Modules 中为查找常量做了一个特例并且已经被修改了 to state this explicitly .如果在正常层次结构中未找到该常量,Ruby 会从 Object 重新开始查找,可以是 found in the source。 .

常量查找本身可能有点令人困惑。举个例子:

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,那么只有 LookHereOnly 和它包含的模块将被搜索。如果未指定作用域(如上例中的 Foo),Ruby 将查看打开的模块定义以查找常量 Foo:M::N,然后是 M,最后是 Object。最顶层打开的模块定义始终是 Object

所以当打开的类只有M::NObject,就像我示例的最后一部分。

我希望我做对了,因为我自己仍然对不断的查找感到困惑 :-)

关于ruby - Ruby 中 const_get 的混淆行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3165449/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com