# Including a module in an included module

**URL:** <https://www.ruby-forum.com/t/including-a-module-in-an-included-module/173929>\
**Category:** Ruby\
**Created:** [August 18, 2009, 12:20pm UTC](https://www.ruby-forum.com/t/including-a-module-in-an-included-module/173929 "2009-08-18T12:20:00Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![princenez](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/47e85d/32.png) [@princenez](https://www.ruby-forum.com/u/princenez)\
**Post date:** [August 18, 2009, 12:20pm UTC](https://www.ruby-forum.com/t/including-a-module-in-an-included-module/173929/1 "2009-08-18T12:20:00Z")

</div>

```
module M1; end
module M2; include M1; end
module M1; DOG = :woof; end
module M2; DOG; end
# => :woof

```

I can add to a module after it has been included. Neat.

```
module M1; DOG = :woof; end
module M2; include M1; end
module M3; include M2; end
module M3; DOG; end
# => :woof

```

Including a module seems to give me any modules that it includes. Swish.

```
module M2; end
module M3; include M2; end
module M1; DOG = :woof; end
module M2; include M1; end
module M3; DOG; end
# => NameError: uninitialized constant M3::DOG

```

So I assumed I’d be able to include a module in a module after it has  
been included, if you get my drift. It surprises me that this dog  
doesn’t bark.

---

<div class="post-metadata">

**Author:** ![princenez](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/47e85d/32.png) [@princenez](https://www.ruby-forum.com/u/princenez)\
**Post date:** [August 18, 2009, 1:22pm UTC](https://www.ruby-forum.com/t/including-a-module-in-an-included-module/173929/2 "2009-08-18T13:22:51Z")

</div>

Prince N. wrote:

> ```
> module M1; end
> module M2; include M1; end
> module M1; DOG = :woof; end
> module M2; DOG; end
> # => :woof
> 
> ```
> 
> I can add to a module after it has been included. Neat.
> 
> ```
> module M1; DOG = :woof; end
> module M2; include M1; end
> module M3; include M2; end
> module M3; DOG; end
> # => :woof
> 
> ```
> 
> Including a module seems to give me any modules that it includes. Swish.
> 
> ```
> module M2; end
> module M3; include M2; end
> module M1; DOG = :woof; end
> module M2; include M1; end
> module M3; DOG; end
> # => NameError: uninitialized constant M3::DOG
> 
> ```
> 
> So I assumed I’d be able to include a module in a module after it has  
> been included, if you get my drift. It surprises me that this dog  
> doesn’t bark.

The results seem to speak for themselves: include only unwraps the  
namespace name from the names that were in the module at the time the  
module was included–subsequently adding constants to the previously  
included module does not present them unwrapped.

---

<div class="post-metadata">

**Author:** ![princenez](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/47e85d/32.png) [@princenez](https://www.ruby-forum.com/u/princenez)\
**Post date:** [August 18, 2009, 1:27pm UTC](https://www.ruby-forum.com/t/including-a-module-in-an-included-module/173929/3 "2009-08-18T13:27:35Z")

</div>

7stud – wrote:

> The results seem to speak for themselves: include only unwraps the  
> namespace name from the names that were in the module at the time the  
> module was included–subsequently adding constants to the previously  
> included module does not present them unwrapped.

Nope. That rule doesn’t work with example 1. It appears one level of  
nesting is required for my rule to hold true.

---

<div class="post-metadata">

**Author:** ![princenez](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/47e85d/32.png) [@princenez](https://www.ruby-forum.com/u/princenez)\
**Post date:** [August 18, 2009, 1:47pm UTC](https://www.ruby-forum.com/t/including-a-module-in-an-included-module/173929/4 "2009-08-18T13:47:41Z")

</div>

2009/8/18 Prince N. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> module M3; include M2; end
> 
> # =\> NameError: uninitialized constant M3::DOG
> 
> So I assumed I’d be able to include a module in a module after it has  
> been included, if you get my drift. It surprises me that this dog  
> doesn’t bark.

Inclusion apparently works by extracting the ancestors of a module at  
inclusion time and placing them in the ancestor chain of the class:

irb(main):001:0\> module A  
irb(main):002:1\> def foo; “foo”; end  
irb(main):003:1\> end  
=\> nil  
irb(main):004:0\> A.ancestors  
=\> [A]  
irb(main):005:0\> class C  
irb(main):006:1\> include A  
irb(main):007:1\> end  
=\> C  
irb(main):008:0\> C.ancestors  
=\> [C, A, Object, Kernel, BasicObject]  
irb(main):009:0\> C.new.foo  
=\> “foo”  
irb(main):010:0\> module B  
irb(main):011:1\> def bar; “bar”; end  
irb(main):012:1\> end  
=\> nil  
irb(main):013:0\> module A  
irb(main):014:1\> include B  
irb(main):015:1\> end  
=\> A  
irb(main):016:0\> A.ancestors  
=\> [A, B]  
irb(main):017:0\> C.ancestors  
=\> [C, A, Object, Kernel, BasicObject]  
irb(main):018:0\> C.new.bar  
NoMethodError: undefined method `bar' for #<C:0x100de5c0> from (irb):18 from /opt/bin/irb19:12:in `’  
irb(main):019:0\> class C  
irb(main):020:1\> include A  
irb(main):021:1\> end  
=\> C  
irb(main):022:0\> C.ancestors  
=\> [C, A, B, Object, Kernel, BasicObject]  
irb(main):023:0\> C.new.bar  
=\> “bar”  
irb(main):024:0\>

As you can see, you can fix that by reincluding the module.

Kind regards

robert
