I am trying to include a bunch of constants into a module and all its
“submodules” (by this I mean modules that are defined within the scope
of the first module; is there a word for that?), but the constants only
seem accessible in the module that directly includes them, not in a
submodule. See this example:
===
module FooModule
Foo = :foo
end
module BarModule
include FooModule
Bar = :bar
p ancestors # => [BarModule, FooModule]
p Bar # works
p Foo # works
module SubBarModule
p ancestors # => [BarModule::SubBarModule]
p Bar # works
p Foo # fails
end
end
Now if the SubBarModule’s ancestors do not include FooModule, I can
understand that it cannot access Foo, but on the other hand,
SubBarModule’s ancestors do not include BarModule either, so why can it
acces Bar?
Tested in Ruby 1.8.7, 1.9.3p0 and 2.0.0p195, just to be sure that the
semantics have not changed – it seems to be they haven’t.
Now if the SubBarModule’s ancestors do not include FooModule, I can
understand that it cannot access Foo, but on the other hand,
SubBarModule’s ancestors do not include BarModule either, so why can it
acces Bar?
“Constants are looked up in the lexical scope in which they were
referenced.” (Programming Ruby 1.9, page 290)
Accessing the constant Bar works above because the constant is available
based on the lexical scope (it’s defined in an enclosing module
definition). So, its availability has nothing to do with inheritance. If
you really want a set of constants to be available to a module and all
modules nested/namespaced within it, just define said constant in the
outermost module that needs access.
I am trying to include a bunch of constants into a module and all its
“submodules” (by this I mean modules that are defined within the scope
of the first module; is there a word for that?),
I would just say that your “submodules” are “namespaced” or “nested”
within
a parent.
module SubBarModule
Now if the SubBarModule’s ancestors do not include FooModule, I can
understand that it cannot access Foo, but on the other hand,
SubBarModule’s ancestors do not include BarModule either, so why can it
acces Bar?
“Constants are looked up in the lexical scope in which they were
referenced.” (Programming Ruby 1.9, page 290)
Accessing the constant Bar works above because the constant is available
based on the lexical scope (it’s defined in an enclosing module
definition). So, its availability has nothing to do with inheritance. If
you really want a set of constants to be available to a module and all
modules nested/namespaced within it, just define said constant in the
outermost module that needs access. If the constants are already defined
in
another, unrelated module that gets mixed into the outermost module,
like
you’re doing by including FooModule into BarModule, and if moving the
constants directly into FooModule isn’t an option, then there are
several
other options; which is best really depends upon the specifics of your
circumstances.
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.