动态获取定义的常量



根据Rubyconst_get的文档,此方法返回常量的值。

因此,要重现以下行为:

module A
FOO = 42
module B
def self.call
FOO
end
end
end
A::B.call # => 42

我写了这段代码:

A = Module.new
A.const_set(:FOO, 42)
A.const_set(:B, Module.new do
def self.call
const_get(:FOO)
end
end)

但是当我调用该方法时,我有一个NameError异常:

A::B.call # => exception
# NameError (uninitialized constant A::B::FOO)
# Did you mean?  A::FOO

看起来FOOconst_get(:FOO)并不完全相同。

有没有另一种方法可以在父模块中找到递归查找FOO常量?

编辑:

我在直接做const_get时也有这个麻烦:

module A
FOO = 42
module B
def self.a_method
const_get(:FOO)
end
end
end
A::B.a_method # => exception
# NameError (uninitialized constant A::B::FOO)
# Did you mean?  A::FOO

我们可以使用 Module::nesting 方法来更好地理解这里发生了什么。

module A
FOO = 42
module B
puts "Module.nesting = #{Module.nesting}"
def self.call
FOO
end
end
end

显示

Module.nesting = [A::B, A]

这告诉我们,在执行A::B.call时,在搜索FOO的值时,Ruby 首先在模块A::B中查找,没有找到它,然后在模块A中搜索她找到它的位置。

您的第三个代码片段还会创建一个嵌套模块A::B

module A
FOO = 42
module B
puts "Module.nesting = #{Module.nesting}"
def self.a_method
const_get(:FOO)
end
end
end

显示

Module.nesting = [A::B, A]

A::B.a_method执行A::B.const_get(:FOO).模块 #const_get 的文档指出,"检查 mod 中具有给定名称的常量。因此,如果它未能在作为其接收器的模块中找到常量,它将放弃而不检查给定模块嵌套的任何模块。

您的第二个代码片段与第三个代码片段相似,因为它由于const_get的行为而无法找到FOO的值。

最新更新