Consider the following (correct) Ruby program:
class Outer
Inner = Struct.new(:dummy) do
CONST = \'abce\'
def fun
puts(dummy)
end
end
After a little digging I was able to figure this out. Here's a quote from a similar question:
Constants belong to classes, therefore constant resolution via the :: operator only works with class objects.
In your above example Inner
is a constant not a class, so Outer::Inner::CONST
won't work. If we redefine Inner
as a class we see the expected results.
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)
This happens because the constant is defined in the current namespace. The class
and module
keywords define namespaces, but Struct.new
(just like Class.new
) does not.
In order to define the constant under the Struct's scope, you have to use self::
class Outer
Inner = Struct.new(:dummy) do
self::CONST = 'abce'
end
end
Outer::Inner::CONST
#=> 'abce'
Outer::CONST
#=> NameError uninitialized constant Outer::CONST