# Nested Mixin Problem(?)

**URL:** <https://www.ruby-forum.com/t/nested-mixin-problem/108306>\
**Category:** Ruby\
**Created:** [July 2, 2007, 3:51am UTC](https://www.ruby-forum.com/t/nested-mixin-problem/108306 "2007-07-02T03:51:03Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![vascoas](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/b3f665/32.png) [@vascoas](https://www.ruby-forum.com/u/vascoas)\
**Post date:** [July 2, 2007, 3:51am UTC](https://www.ruby-forum.com/t/nested-mixin-problem/108306/1 "2007-07-02T03:51:03Z")

</div>

Hi,

could someone check and comment if this is something that i don’t  
understand well or a ruby “somehow” problem? please

Here’s the code:

module A  
def a; :a; end  
end

module B  
include A  
def b; :b; end  
end

module C  
def c; :c; end  
end

class D  
include B  
end

D.new.a #=\> :a ## Ok for me  
D.new.b #=\> :b ## Ok for me

module B  
include C  
end

D.new.c #=\> NoMethodError: undefined method `c’ for #\<D:0xb7cb985c\> ##  
This is not ok for me.

Thanks,  
Vasco Andrade e Silva

---

<div class="post-metadata">

**Author:** ![vascoas](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/b3f665/32.png) [@vascoas](https://www.ruby-forum.com/u/vascoas)\
**Post date:** [July 2, 2007, 10:09am UTC](https://www.ruby-forum.com/t/nested-mixin-problem/108306/2 "2007-07-02T10:09:10Z")

</div>

Dear Vasco,

it seems like you wanted to include something before it is  
defined.  
The following worked for me:

module A  
def a; :a; end  
end

module B  
include A  
def b; :b; end  
end

module C  
def c; :c; end  
end

module B # \<------ interchanged these  
include C  
end

class D # \<------ interchanged these  
include B  
end

D.new.a #=\> :a ## Ok for me  
D.new.b #=\> :b ## Ok for me

p D.new.c #=\>:c ## Ok for you?

Best regards,

Axel

---

<div class="post-metadata">

**Author:** ![vascoas](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/b3f665/32.png) [@vascoas](https://www.ruby-forum.com/u/vascoas)\
**Post date:** [July 2, 2007, 10:33am UTC](https://www.ruby-forum.com/t/nested-mixin-problem/108306/3 "2007-07-02T10:33:13Z")

</div>

On 2 Jul 2007, at 10:51, Vasco Andrade e Silva wrote:

> include B  
> 0xb7cb985c\> ##  
> This is not ok for me.
> 
> Thanks,  
> Vasco Andrade e Silva
> 
> –  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

I think you’ve found an interesting edge case for modules and mixins.  
Redefining a module only seems to work to one ‘level’. So this works:

irb(main):001:0\> module FooBar  
irb(main):002:1\> end  
=\> nil  
irb(main):003:0\> class Baz  
irb(main):004:1\> include FooBar  
irb(main):005:1\> end  
=\> Baz  
irb(main):006:0\> a = Baz.new  
=\> #Baz:0x330568  
irb(main):007:0\> module FooBar  
irb(main):008:1\> def foo; :foo; end  
irb(main):009:1\> end  
=\> nil  
irb(main):010:0\> a.foo  
=\> :foo

But not here (analogous to your example I think):

irb(main):011:0\> module Bar  
irb(main):012:1\> def bar; :bar; end  
irb(main):013:1\> end  
=\> nil  
irb(main):014:0\> module FooBar  
irb(main):015:1\> include Bar  
irb(main):016:1\> end  
=\> FooBar  
irb(main):017:0\> a.bar  
NoMethodError: undefined method `bar’ for #Baz:0x330568  
from (irb):18

We need a guru to explain why…

Alex G.

Bioinformatics Center  
Kyoto University

---

<div class="post-metadata">

**Author:** ![vascoas](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/b3f665/32.png) [@vascoas](https://www.ruby-forum.com/u/vascoas)\
**Post date:** [July 2, 2007, 11:10am UTC](https://www.ruby-forum.com/t/nested-mixin-problem/108306/4 "2007-07-02T11:10:19Z")

</div>

\> irb(main):016:1\> end \> =\> FooBar \> irb(main):017:0\> a.bar \> NoMethodError: undefined method `bar' for # \> from (irb):18 \> \> We need a guru to explain why... That is definitely not me, but there was a very interesting thread by Tom (aka Trans) very recently and Pit provided a nice metaprogramming tool to address the issue which is called "double inclusion". [Sorry I am bad at finding references to threads :(]

As a matter of fact there is an easy way to update the method lookup  
chain  
just continue as follows in your irb session:

irb(main):019:0\> class Baz  
irb(main):020:1\> include FooBar # Play it again Sam  
irb(main):021:1\> end  
=\> Baz  
irb(main):022:0\> a.bar  
=\> :bar

It has something to do with the proxies that are created for included  
modules, maybe a Guru will explain this in detail.

Cheers  
Robert

---

<div class="post-metadata">

**Author:** ![vascoas](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/b3f665/32.png) [@vascoas](https://www.ruby-forum.com/u/vascoas)\
**Post date:** [July 2, 2007, 6:07pm UTC](https://www.ruby-forum.com/t/nested-mixin-problem/108306/5 "2007-07-02T18:07:38Z")

</div>

Hi,

Axel E. wrote:

> it seems like you wanted to include something before it is  
> defined.

No. I wanted to use mixins for more than ‘one level’, as Alex G.  
explain it:

> I think you’ve found an interesting edge case for modules and mixins.  
> Redefining a module only seems to work to one ‘level’. So this works:  
> …

I didn’t know that this “problem” was called “double inclusion” (thanks  
Robert) or “Dynamic Module Include Problem”. After a quick search for  
“double inclusion” you get:  
[http://eigenclass.org/hiki/The+double+inclusion+problem](http://eigenclass.org/hiki/The+double+inclusion+problem)  
[http://www.ruby-forum.com/topic/112897](http://www.ruby-forum.com/topic/112897)

If some Guru come along and see this thread maybe he/she could give a  
more indepth answer.

Meanwhile…  
Thank you guys,  
Vasco
