假设我有一个类,比如:
class Person
module Health
GOOD = 10
SICK = 4
DEAD = 0
end
end
我可以参考这样的健康码:Person::Health::GOOD
。我想动态生成一个从数值映射回常量名称的哈希:
{ 10 => "GOOD",
4 => "SICK",
0 => "DEAD" }
为了动态地做到这一点,我提出了:
Person::Health.constants.inject({}) do |hsh, const|
hsh.merge!( eval("Person::Health::#{const}") => const.to_s )
end
这是可行的,但我想知道是否有更好/更安全的方法。它在Rails应用程序中,虽然它离任何用户输入都不远,但eval
仍然让我感到紧张。有更好的解决方案吗?
您可以为此使用constants
和const_get
。
ph = Person::Health # Shorthand
Hash[ph.constants(false).map { |c| [ph.const_get(c), c.to_s ] }]
# {10=>:GOOD, 4=>:SICK, 0=>:DEAD}
我将false
添加到.constants
中,以防止包含来自所包含模块的任何继承常量。例如,如果没有false
,以下场景也将包括5 => "X"
映射:
module A
X = 5
end
class Person
module Health
include A
# ...
end
end
Hash[ph.constants.map { |c| [ph.const_get(c), c.to_s ] }]
# {10=>"GOOD", 4=>"SICK", 0=>"DEAD", 5=>"X"}