我想将常量FOO::BAR
转换为字符串"BAR"
。
这与constantize
的作用相反,与demodulize
非常相似,除了我期望的是字符串而不是实际的模块引用。
我以为我可以自己做帮助,但是我无法获得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
答案 0 :(得分:4)
您无法传递常量,只能传递对象。如果您将FOO::BAR
传递给方法,则不会传递常量,而是传递已分配给FOO::BAR
的对象,即哈希值。
为了检索常量的名称,已经从对象本身分配了一个对象,该对象必须以某种方式存储该名称。
模块确实存储了已分配的常量名称(Ruby在第一次将模块分配给常量时设置名称)。由于FOO
是一个模块(类是模块),因此您可以调用FOO.name
并返回"FOO"
。但这只会起作用,因为对象"知道"它的名字。
从内置对象中,只有Module
(因此Class
)才有name
方法以此方式工作。
您可以向哈希实例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
该方法遍历模块的常量并返回引用传递对象的(第一个)常量。
答案 1 :(得分:0)
class FOO
class BAR
end
end
FOO::BAR.to_s.split('::').last
#=> "BAR"
请注意方法Module#to_s"返回表示此模块或类的字符串。对于基本类和模块,这是名称"。可以使用Module#name代替to_s
。