ruby - 动态获取定义的常量
问题描述
根据 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 首先在 moduleA::B
中查找,没有找到,然后在A
找到它的 module 中搜索。
您的第三个代码片段还创建了一个嵌套模块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)
。Module#const_get的文档指出,“在 mod 中检查具有给定名称的常量。” 因此,如果它未能在作为其接收者的模块中找到常量,它会放弃而不检查给定模块嵌套的任何模块。
您的第二个代码片段与第三个代码片段相似,因为它无法找到 的值,FOO
因为const_get
.
推荐阅读
- python - 我无法弄清楚如何在 scrapinghub 部署中使用 csv 文件进行列表理解
- logging - Fortify SCA 扫描在读取环境变量时报告日志伪造问题
- debugging - UnicodeString::Length() 干扰调试器显示
- javascript - Vue中使用/deep/bug
- r - 将文本转换为数字?
- azure - Azure Site Recovery 保证 Azure 到 Azure 故障转移的恢复时间目标为两小时。对于任何类型的工作负载?
- jquery - 使用不带特殊字符 + 验证格式的日期输入创建一个 from
- python - 如果找到匹配,如何比较数据框中的两列并返回相应的记录?
- ios - 从 Swift 3 更新项目时的便利初始化错误
- azure-api-management - Azure API 管理在 API 终结点级别限制多个调用方 IP 地址 API