# Object#extend inner workings

**URL:** <https://www.ruby-forum.com/t/object-extend-inner-workings/99049>\
**Category:** Ruby\
**Created:** [July 20, 2006, 1:09am UTC](https://www.ruby-forum.com/t/object-extend-inner-workings/99049 "2006-07-20T01:09:04Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![tomfarm](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/b5ac83/32.png) [@tomfarm](https://www.ruby-forum.com/u/tomfarm)\
**Post date:** [July 20, 2006, 1:09am UTC](https://www.ruby-forum.com/t/object-extend-inner-workings/99049/1 "2006-07-20T01:09:04Z")

</div>

I’ve got a question regarding the inner workings of extend. Consider the  
following code that uses Object#extend twice:

class Klass  
def hello(options = {})  
p options  
end  
end

module Mod1  
def hello(options = {})  
super(options.merge({:mod1 =\> true}))  
end  
end

module Mod2  
def hello(options = {})  
super(options.merge({:mod2 =\> true}))  
end  
end

k = Klass.new  
k.hello #=\> {}

k.extend(Mod1)  
k.hello #=\> {:mod1=\>true}

k.extend(Mod2)  
k.hello #=\> {:mod2=\>true, :mod1=\>true}

I was a bit surprised that the second extend didn’t clobber the first.  
How is this handled by the Ruby interpreter? Is it creating more than  
one eigenclass?

Tom

---

<div class="post-metadata">

**Author:** ![tomfarm](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/b5ac83/32.png) [@tomfarm](https://www.ruby-forum.com/u/tomfarm)\
**Post date:** [July 20, 2006, 1:31am UTC](https://www.ruby-forum.com/t/object-extend-inner-workings/99049/2 "2006-07-20T01:31:50Z")

</div>

Justin C. wrote:

> > module Mod1
> > 
> > first. How is this handled by the Ruby interpreter? Is it creating
> 
> -Justin

But the behavior of the modules is that of a subclass (being able to  
call super to call a method in Klass). If I were to use include inside  
the class definition, then I would indeed get superclass behavior.

Tom

---

<div class="post-metadata">

**Author:** ![tomfarm](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/b5ac83/32.png) [@tomfarm](https://www.ruby-forum.com/u/tomfarm)\
**Post date:** [July 20, 2006, 1:35am UTC](https://www.ruby-forum.com/t/object-extend-inner-workings/99049/3 "2006-07-20T01:35:09Z")

</div>

Hi –

On Thu, 20 Jul 2006, Tom W. wrote:

> def hello(options = {})  
> k = Klass.new  
> eigenclass?  
> No, it’s just inserting the modules along the method lookup chain.  
> You can examine it like this:

class \<\< k  
p ancestors  
end

which gives you:

[Mod2, Mod1, Klass, Object, Kernel]

So Mod2 comes before Mod1, but the class (k’s singleton class) still  
has Mod1 mixed in.

David

---

<div class="post-metadata">

**Author:** ![tomfarm](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/b5ac83/32.png) [@tomfarm](https://www.ruby-forum.com/u/tomfarm)\
**Post date:** [July 20, 2006, 1:18am UTC](https://www.ruby-forum.com/t/object-extend-inner-workings/99049/4 "2006-07-20T01:18:45Z")

</div>

Tom W. wrote:

> def hello(options = {})  
> k = Klass.new  
> one eigenclass?
> 
> Tom

As I understand it, Ruby adds another “transparent” superclass each time  
you use extend or include. You can of course do that as many times as  
you want to get all kinds of mix-in functionality. There are some nice  
diagrams in the Pickaxe book that show this (I don’t have it with me at  
the moment).

-Justin

---

<div class="post-metadata">

**Author:** ![tomfarm](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/b5ac83/32.png) [@tomfarm](https://www.ruby-forum.com/u/tomfarm)\
**Post date:** [July 20, 2006, 1:38am UTC](https://www.ruby-forum.com/t/object-extend-inner-workings/99049/5 "2006-07-20T01:38:40Z")

</div>

Tom W. wrote:

> > > end  
> > > I was a bit surprised that the second extend didn’t clobber the  
> > > it with me at the moment).

Oh, right, nevermind.

-Justin

---

<div class="post-metadata">

**Author:** ![tomfarm](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/b5ac83/32.png) [@tomfarm](https://www.ruby-forum.com/u/tomfarm)\
**Post date:** [July 20, 2006, 1:38am UTC](https://www.ruby-forum.com/t/object-extend-inner-workings/99049/6 "2006-07-20T01:38:30Z")

</div>

removed\_email\_address@domain.invalid wrote:

> > end  
> > super(options.merge({:mod2 =\> true}))  
> > k.hello #=\> {:mod2=\>true, :mod1=\>true}  
> > end

Ah! Have I said I love Ruby today?

Thanks David.

Tom
