根据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
看起来FOO
和const_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
的值。