# How to get modules included by a class/module (not those from the superclasses)

**URL:** <https://rubytalk.org/t/how-to-get-modules-included-by-a-class-module-not-those-from-the-superclasses/35744>\
**Category:** ruby-talk\
**Created:** [28 February 2007 17:32 UTC](https://rubytalk.org/t/how-to-get-modules-included-by-a-class-module-not-those-from-the-superclasses/35744 "2007-02-28T17:32:22Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ruby\_Admirer](https://avatars.discourse-cdn.com/v4/letter/r/97f17d/32.png) [@Ruby\_Admirer](https://rubytalk.org/u/Ruby_Admirer)\
**Post date:** [28 February 2007 17:32 UTC](https://rubytalk.org/t/how-to-get-modules-included-by-a-class-module-not-those-from-the-superclasses/35744/1 "2007-02-28T17:32:22Z")

</div>

Is there a way to get only the modules included by a given class.  
&nbsp;&nbsp;Using included\_modules returns also the modules that are included by the superclass(es).  
&nbsp;&nbsp;&nbsp;  
&nbsp;&nbsp;Example :  
&nbsp;&nbsp;class MyClass  
&nbsp;&nbsp;end  
&nbsp;&nbsp;MyClass.included\_modules  
&nbsp;&nbsp;# will return Kernel  
&nbsp;&nbsp;&nbsp;  
&nbsp;&nbsp;As a given module may be included several times in the class hierarchy (e.g. by the class and by one of its superclass), just getting all included modules and removing the included modules from the superclasses may not be a solution. The given module may have been removed erroneously.  
&nbsp;&nbsp;&nbsp;  
&nbsp;&nbsp;It would have been great if included\_modules takes a boolean parameter in order to disable the recursion like instance\_methods for example.  
&nbsp;&nbsp;&nbsp;  
&nbsp;&nbsp;Thanks for any help.

> **···**
>
> ---------------------------------  
> Need Mail bonding?  
> Go to the Yahoo! Mail Q&A for great tips from Yahoo! Answers users.

---

<div class="post-metadata">

**Author:** ![Pit](https://avatars.discourse-cdn.com/v4/letter/p/f14d63/32.png) [@Pit](https://rubytalk.org/u/Pit)\
**Post date:** [28 February 2007 19:29 UTC](https://rubytalk.org/t/how-to-get-modules-included-by-a-class-module-not-those-from-the-superclasses/35744/2 "2007-02-28T19:29:24Z")

</div>

Ruby Admirer schrieb:

> Is there a way to get only the modules included by a given class. Using included\_modules returns also the modules that are included by the superclass(es).  
> (...)  
> As a given module may be included several times in the class  
> hierarchy (e.g. by the class and by one of its superclass), just  
> getting all included modules and removing the included modules from  
> the superclasses may not be a solution. The given module may have  
> been removed erroneously.

Including a module in a class that already has been included by one of its superclasses doesn't change the inheritance hierarchy:

&nbsp;&nbsp;&nbsp;module M  
&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;class P  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;include M  
&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;class C \< P  
&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;p C.ancestors # =\> [C, P, M, Object, Kernel]

&nbsp;&nbsp;&nbsp;class C  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;include M  
&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;p C.ancestors # =\> [C, P, M, Object, Kernel]

The only way to create the situation you describe above would be to include the module in the child class \*before\* including it in the superclass. If you want to detect this, you could try the following code:

&nbsp;&nbsp;&nbsp;class Class  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def my\_own\_included\_modules  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ancestors.inject() { |acc, mod|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break acc if mod == superclass  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;acc \<\< mod unless mod == self  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;acc  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;p P.my\_own\_included\_modules # =\> [M]  
&nbsp;&nbsp;&nbsp;p C.my\_own\_included\_modules # =\>

&nbsp;&nbsp;&nbsp;class P2  
&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;class C2 \< P2  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;include M  
&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;class P2  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;include M  
&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;p C2.ancestors # =\> [C2, M, P2, M, Object, Kernel]

&nbsp;&nbsp;&nbsp;p P2.my\_own\_included\_modules # =\> [M]  
&nbsp;&nbsp;&nbsp;p C2.my\_own\_included\_modules # =\> [M]

Out of curiosity: why do you need this?

Regards,  
Pit

---

<div class="post-metadata">

**Author:** ![Ruby\_Admirer](https://avatars.discourse-cdn.com/v4/letter/r/97f17d/32.png) [@Ruby\_Admirer](https://rubytalk.org/u/Ruby_Admirer)\
**Post date:** [28 February 2007 22:47 UTC](https://rubytalk.org/t/how-to-get-modules-included-by-a-class-module-not-those-from-the-superclasses/35744/3 "2007-02-28T22:47:38Z")

</div>

Pit,

> Including a module in a class that already has been included by one of  
> its superclasses doesn't change the inheritance hierarchy:
> 
> module M  
> end

&nbsp;&nbsp;&nbsp;\>class P  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\>include M  
&nbsp;&nbsp;&nbsp;\>end

> 

&nbsp;&nbsp;&nbsp;\>class C \< P  
&nbsp;&nbsp;&nbsp;\>end

> 

&nbsp;&nbsp;&nbsp;\>p C.ancestors # =\> [C, P, M, Object, Kernel]

> 

&nbsp;&nbsp;&nbsp;\>class C  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\>include M  
&nbsp;&nbsp;&nbsp;\>end

> 

&nbsp;&nbsp;&nbsp;\>p C.ancestors # =\> [C, P, M, Object, Kernel]

> The only way to create the situation you describe above would be to  
> include the module in the child class \*before\* including it in the  
> superclass.

You are absolutely right ! I did not catch this.  
This seems to be a similar behaviour as for a class variable/method :

class B  
@@var = "Hello"  
end

class C \< class B  
end

The class variable @@var is shared/inherited in C. Similar as the case where there is only one include.

Conversely :

class B  
end

class C \< class B  
@@var = "Hello"  
&nbsp;&nbsp;end

class B  
@@var = "Goodbye"  
&nbsp;&nbsp;end

The two class variables @@var are different. This is similar as the case where there is an include at each class.

I know that this behaviour for class variable/method will change with Ruby 2.0.  
(A class variable/method will be static to the class)  
Will it be the same for module inclusion ??

> class Class

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\>def my\_own\_included\_modules  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\>ancestors.inject() { |acc, mod|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\>break acc if mod == superclass  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\>acc \<\< mod unless mod == self  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\>acc  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\>}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\>end  
&nbsp;&nbsp;&nbsp;\>end

This is exactly what I need.

> Out of curiosity: why do you need this?

I just want to know/understand :  
- the hierarchy (inheritance) between the Ruby classes  
- which class really includes which module(s)

Thanks a lot.

Chauk-Mean.

> **···**
>
> ---------------------------------  
> Don't be flakey. Get Yahoo! Mail for Mobile and  
> always stay connected to friends.

---

<div class="post-metadata">

**Author:** ![Rick\_DeNatale1](https://avatars.discourse-cdn.com/v4/letter/r/bbce88/32.png) [@Rick\_DeNatale1](https://rubytalk.org/u/Rick_DeNatale1)\
**Post date:** [1 March 2007 14:24 UTC](https://rubytalk.org/t/how-to-get-modules-included-by-a-class-module-not-those-from-the-superclasses/35744/4 "2007-03-01T14:24:11Z")

</div>

This has changed in 1.9 (or at least as of a few months ago which was  
the last time I built 1.9)

rick@frodo:~$ cat modtest.rb  
module M  
end

class P  
&nbsp;&nbsp;include M  
end

class C \< P  
end

p C.ancestors

class C  
&nbsp;&nbsp;include M  
end

p C.ancestors

rick@frodo:~$ ruby1.8 modtest.rb  
[C, P, M, Object, Kernel]  
rick@frodo:~$ ruby1.9 modtest.rb  
[C, P, M, Object, Kernel, BasicObject]  
[C, M, P, M, Object, Kernel, BasicObject]

I wrote about this back in October  
[http://talklikeaduck.denhaven2.com/articles/2006/10/09/a-subtle-change-to-mixin-semantics-in-ruby-1-9](http://talklikeaduck.denhaven2.com/articles/2006/10/09/a-subtle-change-to-mixin-semantics-in-ruby-1-9)

> **···**
>
> On 2/28/07, Pit Capitain \<pit@capitain.de\> wrote:
> 
> > Including a module in a class that already has been included by one of  
> > its superclasses doesn't change the inheritance hierarchy:
> > 
> > &nbsp;&nbsp;&nbsp;module M  
> > &nbsp;&nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;&nbsp;class P  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;include M  
> > &nbsp;&nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;&nbsp;class C \< P  
> > &nbsp;&nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;&nbsp;p C.ancestors # =\> [C, P, M, Object, Kernel]
> > 
> > &nbsp;&nbsp;&nbsp;class C  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;include M  
> > &nbsp;&nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;&nbsp;p C.ancestors # =\> [C, P, M, Object, Kernel]
> 
> --  
> Rick DeNatale
> 
> My blog on Ruby  
> [http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)

---

<div class="post-metadata">

**Author:** ![Ruby\_Admirer](https://avatars.discourse-cdn.com/v4/letter/r/97f17d/32.png) [@Ruby\_Admirer](https://rubytalk.org/u/Ruby_Admirer)\
**Post date:** [1 March 2007 15:03 UTC](https://rubytalk.org/t/how-to-get-modules-included-by-a-class-module-not-those-from-the-superclasses/35744/5 "2007-03-01T15:03:06Z")

</div>

> This has changed in 1.9 (or at least as of a few months ago which was the last time I built 1.9)
> 
> rick@frodo:~$ cat modtest.rb  
> module M  
> end
> 
> class P  
> include M  
> end
> 
> class C \< P  
> end
> 
> p C.ancestors
> 
> class C  
> include M  
> end
> 
> p C.ancestors
> 
> rick@frodo:~$ ruby1.8 modtest.rb  
> [C, P, M, Object, Kernel]  
> [C, P, M, Object, Kernel]  
> rick@frodo:~$ ruby1.9 modtest.rb  
> [C, P, M, Object, Kernel, BasicObject]  
> [C, M, P, M, Object, Kernel, BasicObject]

&nbsp;&nbsp;Thanks for your reply.  
&nbsp;&nbsp;This is what I expected as this is consistent with the new class var/methods behaviour.  
&nbsp;&nbsp;&nbsp;  
&nbsp;&nbsp;\>I wrote about this back in October

> [http://talklikeaduck.denhaven2.com/articles/2006/10/09/a-subtle-change-to-mixin-semantics-in-ruby-1-9](http://talklikeaduck.denhaven2.com/articles/2006/10/09/a-subtle-change-to-mixin-semantics-in-ruby-1-9)

&nbsp;&nbsp;Oups ! I just created a new thread on this subject.  
&nbsp;&nbsp;&nbsp;  
&nbsp;&nbsp;Maybe we will get some official/more up to date position as I haven't found any mention on this change on the report from EigenClass "Changes of Ruby 1.9 update 6".  
&nbsp;&nbsp;&nbsp;  
&nbsp;&nbsp;Chauk-Mean.

> **···**
>
> ---------------------------------  
> Need a quick answer? Get one in minutes from people who know. Ask your question on Yahoo! Answers.

---

<div class="post-metadata">

**Author:** ![Rick\_DeNatale1](https://avatars.discourse-cdn.com/v4/letter/r/bbce88/32.png) [@Rick\_DeNatale1](https://rubytalk.org/u/Rick_DeNatale1)\
**Post date:** [1 March 2007 16:34 UTC](https://rubytalk.org/t/how-to-get-modules-included-by-a-class-module-not-those-from-the-superclasses/35744/6 "2007-03-01T16:34:55Z")

</div>

Actually, I just checked out the latest version of the 1.9 trunk code,  
and it seems to have gone back:.

rick@frodo:~$ ruby1.9 modtest.rb  
[C, P, M, Object, Kernel, BasicObject]

I'm not sure why, personally I thought that the way 1.9 used to work  
was more natural.

> **···**
>
> On 3/1/07, Ruby Admirer \<ruby\_admirer@yahoo.com\> wrote:
> 
> > \>This has changed in 1.9 (or at least as of a few months ago which was the last time I built 1.9)  
> > \>  
> > \>rick@frodo:~$ cat modtest.rb  
> > \>module M  
> > \>end  
> > \>  
> > \>class P  
> > \>include M  
> > \>end  
> > \>  
> > \>class C \< P  
> > \>end  
> > \>  
> > \>p C.ancestors  
> > \>  
> > \>class C  
> > \>include M  
> > \>end  
> > \>  
> > \>p C.ancestors  
> > \>  
> > \>rick@frodo:~$ ruby1.8 modtest.rb  
> > \>[C, P, M, Object, Kernel]  
> > \>rick@frodo:~$ ruby1.9 modtest.rb  
> > \>[C, P, M, Object, Kernel, BasicObject]  
> > \>[C, M, P, M, Object, Kernel, BasicObject]  
> > \>
> > 
> > &nbsp;&nbsp;Thanks for your reply.  
> > &nbsp;&nbsp;This is what I expected as this is consistent with the new class var/methods behaviour.
> 
> --  
> Rick DeNatale
> 
> My blog on Ruby  
> [http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)
