Cannot access constants from included modules in a submodule

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?), 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.

Regards,

Bram Senders
bupknar@gmail.com

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

can you put the actual code in a gist or something to make it easier to
read.

Thanks,
Brad

···

On Mon, Jun 3, 2013 at 11:38 AM, Bram S. <lists@ruby-forum.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?), 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.

Regards,

Bram Senders
bupknar@gmail.com

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

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.

···

On Mon, Jun 3, 2013 at 9:38 AM, Bram S. <lists@ruby-forum.com> wrote:

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

Kendall Gifford wrote in post #1111199:

···

On Mon, Jun 3, 2013 at 9:38 AM, Bram S. <lists@ruby-forum.com> wrote:

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.

Okay, I see how this works now.

Thanks for your clarifications!

Bram Senders
bupknar@gmail.com

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