Ruby:将常量转换为字符串
我想将常量Ruby:将常量转换为字符串,ruby,Ruby,我想将常量FOO::BAR转换为字符串“BAR” 这与实际的模块引用相反,并且非常类似,只是我希望使用字符串而不是实际的模块引用 我想我可以让我自己的助手来做这件事,但我无法得到FOO::BAR的“字符串化”版本 理想情况下,我希望避免任何第三方宝石 例如: class FOO BAR = {} end # this works FOO #=> FOO FOO.name #=> "FOO" # this doesn't FOO::BA
FOO::BAR
转换为字符串“BAR”
这与实际的模块引用相反,并且非常类似,只是我希望使用字符串而不是实际的模块引用
我想我可以让我自己的助手来做这件事,但我无法得到FOO::BAR
的“字符串化”版本
理想情况下,我希望避免任何第三方宝石
例如:
class FOO
BAR = {}
end
# this works
FOO #=> FOO
FOO.name #=> "FOO"
# this doesn't
FOO::BAR #=> {}
FOO::BAR.name #=> NoMethodError: undefined method `name' for {}:Hash
请注意,该方法“返回表示此模块或类的字符串。对于基本类和模块,这是名称”。可以用来代替
to_s
不能传递常数,只能传递对象。如果将FOO::BAR
传递给方法,则传递的不是常量,而是已分配给FOO::BAR
的对象,即散列
为了从对象本身检索对象已分配给的常量名称,对象必须以某种方式存储名称
模块确实存储了分配给它们的常量名称(当模块第一次分配给常量时,Ruby会设置名称)。因为FOO
是一个模块(类是模块),所以可以调用FOO.name
并返回“FOO”
。但这仅仅是因为对象“知道”它的名称
从内置对象中,只有模块
(因此类
)有一个这样工作的方法
您可以将name
方法添加到所引用的哈希实例FOO::BAR
,尽管这可能不是您想要的:
def (FOO::BAR).name
'FOO::BAR'
end
FOO::BAR.name #=> "FOO::BAR"
另一种方法是将常量(实际上是对象)及其模块传递给方法:
def find_const(mod, obj)
mod.constants.find { |c| mod.const_get(c).equal?(obj) }
end
find_const(FOO, FOO::BAR) #=> :BAR
该方法遍历模块的常量并返回引用所传递对象的(第一个)常量。您想做的事情没有意义。为什么要获取常量名称的“名称”?这个用例是什么?常量名称也是我正在实现的服务的一个值。它使我不必再做
BAR={name:'BAR',other_字段:other_value}
。如果我能用屈折法把const的名字串起来,我就不会说了。你的问题不清楚:在你的标题中,你说你想要一个模块的名字,在第一段中,你说你想要一个模块或类的名字,但在你的代码示例中,你实际上有一个散列(显然没有名字)。这不会像它对常量值而不是常量名称本身调用.to\u s
那样起作用。我不理解您的评论。您不想要一个以嵌套类(例如,FOO::BAR
)为参数并以字符串形式返回最内层类(此处为“BAR”)的方法吗?我想将对类constFOO::BAR
的引用传递给一个方法,该方法将const nameBAR
转换并返回到字符串“BAR”
。您的方法返回FOO::BAR
的值,并对常量值而不是常量名称本身调用.to\u s
。我仍然不理解您的观点,但我添加了一些可能会澄清的内容。这也可能有帮助:VAL=6;VAL.to#s=>“6”
,而FOO.to#s=>“FOO”
。VAL
和FOO
都是常量,但是FOO
也是一个类名。问题是BAR
不是类,而是class FOO
上的常量。看看这会如何改变你的答案。
def find_const(mod, obj)
mod.constants.find { |c| mod.const_get(c).equal?(obj) }
end
find_const(FOO, FOO::BAR) #=> :BAR