# Simple metaclass question

**URL:** <https://www.ruby-forum.com/t/simple-metaclass-question/116796>\
**Category:** Ruby\
**Created:** [October 9, 2007, 9:46pm UTC](https://www.ruby-forum.com/t/simple-metaclass-question/116796 "2007-10-09T21:46:32Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![nlakkakula](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/fbc32d/32.png) [@nlakkakula](https://www.ruby-forum.com/u/nlakkakula)\
**Post date:** [October 9, 2007, 9:46pm UTC](https://www.ruby-forum.com/t/simple-metaclass-question/116796/1 "2007-10-09T21:46:32Z")

</div>

## Code 1:

module Mod  
def hello  
“Hello from Mod.\n”  
end  
end  
class Klass  
def hello  
“Hello from Klass.\n”  
end  
end

k = Klass.new  
p k.hello #=\> “Hello from Klass.\n”  
k.extend(Mod)  
p k.hello #=\> “Hello from Mod.\n”

## Code 2:

module Mod  
def hello  
“Hello from Mod.\n”  
end  
end  
class Klass  
include Mod  
def hello  
“Hello from Klass.\n”  
end  
end  
k = Klass.new  
p k.hello #=\> “Hello from Klass.\n”  
k.extend(Mod)  
p k.hello #=\> “Hello from Klass.\n”

Why last k.hello is “Hello from Klass” Not “Hello from Mod”? After  
Klass mixin with Mod, I am extending k object to include Mod so k’s  
metaclass methods now point to Mod methods… right? they should get  
called first before Klass instance methods if I am thinking right.

---

<div class="post-metadata">

**Author:** ![nlakkakula](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/fbc32d/32.png) [@nlakkakula](https://www.ruby-forum.com/u/nlakkakula)\
**Post date:** [October 9, 2007, 10:12pm UTC](https://www.ruby-forum.com/t/simple-metaclass-question/116796/2 "2007-10-09T22:12:25Z")

</div>

IIRC, the reason it doesn’t work the way you expected is that adding a  
mixin gives you a new point on a tree. Ruby searches the tree for  
methods. If you tell it to go to the method hello, it finds that right  
away, right there in the class, so it never bothers to check further  
up the tree. It looks first in the class, and then in the module.

–  
Giles B.

Blog: [http://gilesbowkett.blogspot.com](http://gilesbowkett.blogspot.com)  
Portfolio: [http://www.gilesgoatboy.org](http://www.gilesgoatboy.org)  
Tumblelog: [http://giles.tumblr.com/](http://giles.tumblr.com/)

---

<div class="post-metadata">

**Author:** ![nlakkakula](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/fbc32d/32.png) [@nlakkakula](https://www.ruby-forum.com/u/nlakkakula)\
**Post date:** [October 9, 2007, 10:18pm UTC](https://www.ruby-forum.com/t/simple-metaclass-question/116796/3 "2007-10-09T22:18:55Z")

</div>

To get what you want, you have to do this:

module Mod  
def self.included(base)  
base.class\_eval do  
def hello  
“module”  
end  
end  
end  
end

class Klass  
def hello  
“klass”  
end  
include Mod  
end

include triggers the self.included, which then triggers a class\_eval  
within Klass, which redfines the method.

–  
Giles B.

Blog: [http://gilesbowkett.blogspot.com](http://gilesbowkett.blogspot.com)  
Portfolio: [http://www.gilesgoatboy.org](http://www.gilesgoatboy.org)  
Tumblelog: [http://giles.tumblr.com/](http://giles.tumblr.com/)

---

<div class="post-metadata">

**Author:** ![nlakkakula](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/fbc32d/32.png) [@nlakkakula](https://www.ruby-forum.com/u/nlakkakula)\
**Post date:** [October 9, 2007, 10:28pm UTC](https://www.ruby-forum.com/t/simple-metaclass-question/116796/4 "2007-10-09T22:28:56Z")

</div>

On Wed, 10 Oct 2007 04:46:37 +0900, bob zee [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> Why last k.hello is “Hello from Klass” Not “Hello from Mod”? After  
> Klass mixin with Mod, I am extending k object to include Mod so k’s  
> metaclass methods now point to Mod methods… right? they should get  
> called first before Klass instance methods if I am thinking right.

Ruby inheritance is linearized so that each module only appears once.  
Since Mod is already present in k’s class ancestry, adding it again  
has no effect.

-mental

---

<div class="post-metadata">

**Author:** ![nlakkakula](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/fbc32d/32.png) [@nlakkakula](https://www.ruby-forum.com/u/nlakkakula)\
**Post date:** [October 10, 2007, 5:22am UTC](https://www.ruby-forum.com/t/simple-metaclass-question/116796/5 "2007-10-10T05:22:49Z")

</div>

Giles B. wrote:

> IIRC, the reason it doesn’t work the way you expected is that adding a  
> mixin gives you a new point on a tree. Ruby searches the tree for  
> methods. If you tell it to go to the method hello, it finds that right  
> away, right there in the class, so it never bothers to check further  
> up the tree. It looks first in the class, and then in the module.
> 
> –  
> Giles B.
> 
> Blog: [http://gilesbowkett.blogspot.com](http://gilesbowkett.blogspot.com)  
> Portfolio: [http://www.gilesgoatboy.org](http://www.gilesgoatboy.org)  
> Tumblelog: [http://giles.tumblr.com/](http://giles.tumblr.com/)

Giles …I think Search path is like this Singleton Object then any  
modules mixin by singleton object then the Class then Mixed Modules  
then Super classes. But as I am mixin same Module for singleton object  
which is mixin by Class already, it is skipping it as Rick and mental  
points out.

---

<div class="post-metadata">

**Author:** ![nlakkakula](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/fbc32d/32.png) [@nlakkakula](https://www.ruby-forum.com/u/nlakkakula)\
**Post date:** [October 9, 2007, 11:01pm UTC](https://www.ruby-forum.com/t/simple-metaclass-question/116796/6 "2007-10-09T23:01:45Z")

</div>

On 10/9/07, MenTaLguY [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> On Wed, 10 Oct 2007 04:46:37 +0900, bob zee [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > Why last k.hello is “Hello from Klass” Not “Hello from Mod”? After  
> > Klass mixin with Mod, I am extending k object to include Mod so k’s  
> > metaclass methods now point to Mod methods… right? they should get  
> > called first before Klass instance methods if I am thinking right.
> 
> Ruby inheritance is linearized so that each module only appears once.  
> Since Mod is already present in k’s class ancestry, adding it again  
> has no effect.

For a while, about a year ago, Ruby 1.9 had changed the semantics of  
re-inclusion:  
[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)

But as far as I know it’s now back to the 1.8 definition.

I still don’t understand why since it seems unnatural to me.

–  
Rick DeNatale

My blog on Ruby  
[http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)
