Ruby:将常量转换为字符串

时间:2016-03-02 22:08:06

标签: ruby

我想将常量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

2 个答案:

答案 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