From: Xavier Noria Date: 2012-08-07T23:14:01+09:00 Subject: Re: Nesting and constants --047d7b10cdf98478b104c6ad98e8 Content-Type: text/plain; charset=UTF-8 On Tue, Aug 7, 2012 at 4:02 PM, Thomas Thomassen wrote: module TT_Test > > module Foo > CHEESE = 'I am Foo!' > module Bar > def self.prod > puts CHEESE > end > def self.q > p Module.nesting > end > end # Bar > def self.q > p Module.nesting > end > end # Foo > > > module Foo::Biz > def self.prod > puts CHEESE > end > def self.q > p Module.nesting > end > end # Foo > > end # TT_Test > > > TT_Test::Foo.q > # => [TT_Test::Foo, TT_Test] > > TT_Test::Foo::Bar.q > # => [TT_Test::Foo::Bar, TT_Test::Foo, TT_Test] > > TT_Test::Foo::Bar.q > # => [TT_Test::Foo::Bar, TT_Test] > > TT_Test::Foo.constants > # => ["Biz", "Bar", "CHEESE"] > > My question is: Why is the constant scope different between Bar and Biz > - despite that they both exist under TT_Test::Foo ? I mean, if TT_Test > got a constant named "Foo::Biz" I would have understood the constant > lookup. > The module keyword pushes to the nesting the module it has opened (either just created or reopened). Therefore, in module M module N p Module.nesting # => [M::N, M] end end because first we open M, and then in a nested call we open M::N. But on the other hand module M::N p Module.nesting # => [M::N] end opens M::N and that's it. Nesting gets just that one module object pushed. Note that what we push are module objects, not constants: module M end N = M module N p Module.nesting # => [M] end In the example above, N evaluates to the module object stored in the constant M, that's the module object being reopened and therefore pushed to the nesting. --047d7b10cdf98478b104c6ad98e8 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable On Tue, Aug 7, 2012 at 4:02 PM, Thomas Thomassen <lists@ruby-forum.com<= /a>> wrote:

module TT_Test

=C2=A0 module Foo
=C2=A0 =C2=A0 CHEESE =3D 'I am Foo!'
=C2=A0 =C2=A0 module Bar
=C2=A0 =C2=A0 =C2=A0 def self.prod
=C2=A0 =C2=A0 =C2=A0 =C2=A0 puts CHEESE
=C2=A0 =C2=A0 =C2=A0 end
=C2=A0 =C2=A0 =C2=A0 def self.q
=C2=A0 =C2=A0 =C2=A0 p Module.nesting
=C2=A0 =C2=A0 end
=C2=A0 =C2=A0 end # Bar
=C2=A0 =C2=A0 def self.q
=C2=A0 =C2=A0 =C2=A0 p Module.nesting
=C2=A0 =C2=A0 end
=C2=A0 end # Foo


=C2=A0 module Foo::Biz
=C2=A0 =C2=A0 def self.prod
=C2=A0 =C2=A0 =C2=A0 puts CHEESE
=C2=A0 =C2=A0 end
=C2=A0 =C2=A0 def self.q
=C2=A0 =C2=A0 =C2=A0 p Module.nesting
=C2=A0 =C2=A0 end
=C2=A0 end # Foo

end # TT_Test


TT_Test::Foo.q
# =3D> [TT_Test::Foo, TT_Test]

TT_Test::Foo::Bar.q
# =3D> [TT_Test::Foo::Bar, TT_Test::Foo, TT_Test]

TT_Test::Foo::Bar.q
# =3D> [TT_Test::Foo::Bar, TT_Test]

TT_Test::Foo.constants
# =3D> ["Biz", "Bar", "CHEESE"]

My question is: Why is the constant scope different between Bar and Biz
- despite that they both exist under TT_Test::Foo ? I mean, if TT_Test
got a constant named "Foo::Biz" I would have understood the const= ant
lookup.


The module keywo= rd pushes to the nesting the module it has opened (either just created or r= eopened).

Therefore, in

=C2=A0 =C2=A0 module M
=C2=A0 =C2=A0 =C2=A0 module N
= =C2=A0 =C2=A0 =C2=A0 =C2=A0 p Module.nesting # =3D> [M::N, M]
= =C2=A0 =C2=A0 =C2=A0 end
=C2=A0 =C2=A0 end

because first we open M, and then in a nested call we open M::N. But on = the other hand

=C2=A0 =C2=A0 module M::N
=C2=A0 =C2=A0 =C2= =A0 p Module.nesting # =3D> [M::N]
=C2=A0 =C2=A0 end

opens M::N and that's it. Nesting gets just that one mo= dule object pushed.

Note that what we push are module objects, not constants:
<= div>
=C2=A0 =C2=A0 module M
=C2=A0 =C2=A0 end
=

=C2=A0 =C2=A0 N =3D M

=C2=A0 = =C2=A0 module N
=C2=A0 =C2=A0 =C2=A0 p Module.nesting # =3D> [= M]
=C2=A0 =C2=A0 end

In the example above, N eva= luates to the module object stored in the constant M, that's the module= object being reopened and therefore pushed to the nesting.

<= /div>
=C2=A0=C2=A0
--047d7b10cdf98478b104c6ad98e8--