From: Kendall Gifford Date: 2013-06-04T05:37:17+09:00 Subject: Re: Cannot access constants from included modules in a submodule --047d7b10c94b1e801f04de45ee3d Content-Type: text/plain; charset=UTF-8 On Mon, Jun 3, 2013 at 9:38 AM, Bram S. wrote: > Hi there, > > 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. > 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? > "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. > > 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. > > Regards, > > Bram Senders > bupknar@gmail.com > > -- > Posted via http://www.ruby-forum.com/. > > -- Kendall Gifford zettabyte@gmail.com --047d7b10c94b1e801f04de45ee3d Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
On Mon, Jun 3, 2013 at 9:38 AM, Bram S. = <lists@ruby-fo= rum.com> wrote:
Hi there,

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 "namespace= d" or "nested" within a parent.
=C2=A0
but the constants only
seem accessible in the module that directly includes them, not in a
submodule. =C2=A0See this example:

=3D=3D=3D
module FooModule

=C2=A0 Foo =3D :foo

end

module BarModule

=C2=A0 include FooModule

=C2=A0 Bar =3D :bar

=C2=A0 p ancestors # =3D> [BarModule, FooModule]
=C2=A0 p Bar # works
=C2=A0 p Foo # works

=C2=A0 module SubBarModule

=C2=A0 =C2=A0 p ancestors # =3D> [BarModule::SubBarModule]
=C2=A0 =C2=A0 p Bar # works
=C2=A0 =C2=A0 p Foo # fails

=C2=A0 end

end
=3D=3D=3D

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 u= p in the lexical scope in which they were referenced." (Programming Ru= by 1.9, page 290)

Accessing the constant Bar works above = because the constant is available based on the lexical scope (it's defi= ned 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 al= ready defined in another, unrelated module that gets mixed into the outermo= st 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 spec= ifics of your circumstances.
=C2=A0

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.

Regards,

Bram Senders
bupknar@gmail.com

--
Posted via http://= www.ruby-forum.com/.




--
Kendall G= ifford
zettabyte@gmail.com
--047d7b10c94b1e801f04de45ee3d--