如何获取常量

时间:2016-06-22 02:14:07

标签: ruby

module Colors
  Red = 0
  Blue = 1
  Green = 2
end

当我获得对模块Colors的引用时,我可以通过"Colors"获取该模块Colors.name的名称。

当我引用常量"Colors::Red"时,是否可以获取常量Colors::Red的字符串表示形式?

4 个答案:

答案 0 :(得分:5)

是的,前提是只有一个常量的值等于给定引用的值。

def ref_to_str(color)
  k = Colors.constants.find { |k| Colors.const_get(k) == color }
  return nil unless k
  "Colors::#{k}"
end

ref_to_str(Colors::Red)
  #=> "Colors::Red" 
ref_to_str(Colors::Blue)
  #=> "Colors::Blue" 
ref_to_str(Colors::Green)
  #=> "Colors::Green" 

答案 1 :(得分:1)

不,由于Colors::Red会引用模块Red中定义的常量Colors的值,因此无法获取字符串表示。

        Colors::Red => 0                     

但是,您可以使用Colors.constants

获取模块的常量列表
        Colors.constants => [:Red, :Blue, :Green]

答案 2 :(得分:1)

'Colors' 常量Colors的名称,它是已分配给常量Module的{​​{1}}的名称}。变量之间存在基本差异(我在此包含常量,连同局部变量,实例变量,类变量,全局变量,线程局部伪全局,方法局部伪全局,和特殊变量)和对象,其中最重要的是对象,对象(duh!)和变量不是对象!你不能将它们存储在变量中,你不能在它们上调用方法,你只能分配它们(至少其中一些)并取消引用它们。

因为在面向对象的语言中,方法调用几乎就是你能做的所有事情,并且你不能调用变量上的方法因为它们不是对象,所以你无法提出变量问题,比如“什么”是你的名字“。

您可以向Colors询问其名称,因为Module类具有name实例方法,该方法返回Module的名称。 Integer没有Module方法,因此您无法向name询问其名称。

请注意,Integer的名称有些“神奇”。默认情况下为Module,但是第一次将nil分配给常量时,名称将变为某些表示所述常量的路径(基本上是{{ 1}}封闭模块+ Module +常量名称)。但是,如果将模块分配给不同的常量,即使remove_const为常量,名称仍将保持不变。

这是一段很好的代码片段,它表明name确实返回了::的名称,而不是用于引用它的变量的名称:

Module#name

因此,简而言之:不,你无法从该常量引用的对象中获取常量(或任何变量)的名称,即使只是因为该对象可以被多个变量引用,然后你会回到什么名字?

答案 3 :(得分:0)

尝试使用constants

Colors.constants

所以

  • Colors.constants[0].id2nameRed
  • Colors.constants[1].id2nameBlue
  • Colors.constants[2].id2nameGreen