Ruby:在Struct中定义常量的语法

时间:2018-12-11 14:01:34

标签: ruby

考虑以下(正确的)Ruby程序:

class Outer

  Inner = Struct.new(:dummy) do
    CONST = 'abce'
    def fun
      puts(dummy)
    end
  end

end

obj = Outer::Inner.new(15)
obj.fun
puts(Outer::CONST)

为什么我必须写Outer::CONST而不是Outer::Inner::CONST

我对传递给Struct::new的块的理解是,self已绑定到Outer::Inner,实际上,我们可以看到方法(fun)已附加到内部阶级;但是CONST显然不是。

2 个答案:

答案 0 :(得分:6)

之所以会这样,是因为常量是在当前的命名空间中定义的。 classmodule关键字定义了名称空间,但Struct.new(就像Class.new一样)没有定义。

要在Struct的作用域内定义常量,必须使用self::

class Outer
  Inner = Struct.new(:dummy) do
    self::CONST = 'abce'
  end
end

Outer::Inner::CONST
#=> 'abce'

Outer::CONST
#=> NameError uninitialized constant Outer::CONST

答案 1 :(得分:1)

经过一番挖掘,我得以弄清楚。这是来自similar question的引文:

  

常量属于类,因此通过::进行常量解析   运算符仅适用于类对象。

在上面的示例中,Inner是常量而不是类,因此Outer::Inner::CONST将不起作用。如果将Inner重新定义为一个类,则会看到预期的结果。

class Outer

  class Inner
    CONST = 'abce'
    Deeper = Struct.new(:dummy) do
      def fun
        puts(dummy)
      end
    end
  end

end

obj = Outer::Inner::Deeper.new(15)
obj.fun
puts(Outer::Inner::CONST)