# Nesting and constants

**URL:** <https://www.ruby-forum.com/t/nesting-and-constants/221963>\
**Category:** Ruby\
**Created:** [August 7, 2012, 4:02pm UTC](https://www.ruby-forum.com/t/nesting-and-constants/221963 "2012-08-07T16:02:47Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![aris](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/258eb7/32.png) [@aris](https://www.ruby-forum.com/u/aris)\
**Post date:** [August 7, 2012, 4:02pm UTC](https://www.ruby-forum.com/t/nesting-and-constants/221963/1 "2012-08-07T16:02:47Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![thomthom](https://www.ruby-forum.com/user_avatar/www.ruby-forum.com/thomthom/32/341_2.png) [@thomthom](https://www.ruby-forum.com/u/thomthom)\
**Post date:** [August 7, 2012, 4:15pm UTC](https://www.ruby-forum.com/t/nesting-and-constants/221963/2 "2012-08-07T16:15:07Z")

</div>

On Tue, Aug 7, 2012 at 4:02 PM, Thomas T.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)wrote:

module TT\_Test

> ```
> end # Bar
> def self.q
> 
> ```
> 
> TT\_Test::Foo::Bar.q  
> 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.

---

<div class="post-metadata">

**Author:** ![thomthom](https://www.ruby-forum.com/user_avatar/www.ruby-forum.com/thomthom/32/341_2.png) [@thomthom](https://www.ruby-forum.com/u/thomthom)\
**Post date:** [August 7, 2012, 4:17pm UTC](https://www.ruby-forum.com/t/nesting-and-constants/221963/3 "2012-08-07T16:17:33Z")

</div>

Hi,

Module.nesting lists all modules that _lexically_ surround the method  
call. So it only takes into account the modules that are actually  
present in the form of

module …  
module …  
…  
end  
end

If a parent module is only mentioned in the name, it’s ignored.

---

<div class="post-metadata">

**Author:** ![thomthom](https://www.ruby-forum.com/user_avatar/www.ruby-forum.com/thomthom/32/341_2.png) [@thomthom](https://www.ruby-forum.com/u/thomthom)\
**Post date:** [August 7, 2012, 4:22pm UTC](https://www.ruby-forum.com/t/nesting-and-constants/221963/4 "2012-08-07T16:22:09Z")

</div>

This has just recently been reported to Ruby’s issue tracker:

> **[Feature #6810: \`module A::B; end\` is not equivalent to \`module A; module B;...](https://bugs.ruby-lang.org/issues/6810)**
>
> Redmine

– Matma R.

---

<div class="post-metadata">

**Author:** ![thomthom](https://www.ruby-forum.com/user_avatar/www.ruby-forum.com/thomthom/32/341_2.png) [@thomthom](https://www.ruby-forum.com/u/thomthom)\
**Post date:** [August 7, 2012, 6:06pm UTC](https://www.ruby-forum.com/t/nesting-and-constants/221963/5 "2012-08-07T18:06:40Z")

</div>

Bartosz Dziewoński wrote in post #1071556:

> This has just recently been reported to Ruby’s issue tracker:  
> [Feature #6810: `module A::B; end` is not equivalent to `module A; module B; end; end` with respect to constant lookup (scope) - Ruby - Ruby Issue Tracking System](http://bugs.ruby-lang.org/issues/6810)
> 
> – Matma R.

The comments there reflects what Matz mentions here:

> **[PornFalcon.com is for sale | HugeDomains](https://www.hugedomains.com/domain_profile.cfm?d=pornfalcon.com)**
>
> Choosing the right domain name can be overwhelming. Our personalized customer service helps you get a great domain.

But I still don’t understand why this is considered expected behaviour.  
All I can find is technical explanation to what happens - but not the  
reason and logic for it. From my point of view it’s counter-intuitive  
and I cannot see a use-case for it.

---

<div class="post-metadata">

**Author:** ![thomthom](https://www.ruby-forum.com/user_avatar/www.ruby-forum.com/thomthom/32/341_2.png) [@thomthom](https://www.ruby-forum.com/u/thomthom)\
**Post date:** [August 7, 2012, 9:16pm UTC](https://www.ruby-forum.com/t/nesting-and-constants/221963/6 "2012-08-07T21:16:06Z")

</div>

On Tue, Aug 7, 2012 at 6:06 PM, Thomas T.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)wrote:

The comments there reflects what Matz mentions here:

> 

> **[PornFalcon.com is for sale | HugeDomains](https://www.hugedomains.com/domain_profile.cfm?d=pornfalcon.com)**
>
> Choosing the right domain name can be overwhelming. Our personalized customer service helps you get a great domain.

> But I still don’t understand why this is considered expected behaviour.

Well, it is expected behavior because that’s the way Ruby works.

A given module can be stored in a hundred constants in dozens of  
differently nested constant paths. Constants are largely irrelevant to  
Ruby, Ruby semantics are defined around module and class objects.

So, the rule is that whatever module object is opened by the module  
keyword, that’s what gets pushed to the nesting. It is simple, and it  
works  
in all cases. It does not matter the constant path used to reach the  
module  
object. Given (untested code):

```
module M
  N = Module.new
end

module A
  module B
    C = M::N
  end
end

module M::N
  # (1)
end

module A::B::C
  # (2)
end

X = M::N
module X
  # (3)
end

```

the nesting in (1), (2), and (3) is the same (M::N). The fact that we  
got  
the M::N module via X or A:🅱:C is irrelevant. And the fact that we  
reach  
it via M::N is equally irrelevant by the same principle. _Constants do  
not  
matter_, Ruby only cares about the module objects they yield.

In my view all is round and follows those basic axioms, but of course  
the  
only one who can ensure which is the rationale is Matz himself.
