# Extend weirdness?

**URL:** <https://www.ruby-forum.com/t/extend-weirdness/80123>\
**Category:** Ruby\
**Created:** [December 21, 2006, 4:20pm UTC](https://www.ruby-forum.com/t/extend-weirdness/80123 "2006-12-21T16:20:32Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![ian](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/bb73d2/32.png) [@ian](https://www.ruby-forum.com/u/ian)\
**Post date:** [December 21, 2006, 4:20pm UTC](https://www.ruby-forum.com/t/extend-weirdness/80123/1 "2006-12-21T16:20:32Z")

</div>

Hi Group,

This code:  
module Foo  
def self.included(base)  
base.class\_eval \<\<-end\_eval  
def self.meth  
“Foo”  
end  
end\_eval  
end  
end

```
module Bar
  def self.included(base)
    base.class_eval do
      extend ClassMethods
    end
  end

  module ClassMethods
    def meth
      "Bar"
    end
  end
end

class A
  include Foo
  include Bar
end

puts A.meth

```

produces:  
Foo

whereas I would expect it to produce “Bar”

Can anyone explain what’s going on here? i.e. Why the latter extend  
with Bar doesn’t over-write the class method introduced by Foo

Cheers,  
Ian W.

---

<div class="post-metadata">

**Author:** ![ian](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/bb73d2/32.png) [@ian](https://www.ruby-forum.com/u/ian)\
**Post date:** [December 21, 2006, 4:36pm UTC](https://www.ruby-forum.com/t/extend-weirdness/80123/2 "2006-12-21T16:36:35Z")

</div>

The previous post is using a rails-style idiom, which is unnecessarily  
complex for the problem at hand.  
Here’s a simpler example to the same effect:

```
module Foo
  def self.included(base)
    class<<base
      def meth
        "Foo"
      end
    end
  end
end

module Bar
  def meth
    "Bar"
  end
end

class A
  include Foo
  extend Bar
end

puts A.meth

```

Which produces “Foo”

There’s a workaround (remove the method by hand):

```
module Bar
  def self.extended(base)
    class<<base
      remove_method :meth
    end
  end
end

```

But this workaround does what I’d expect Ruby to do (overwrite any  
existing methods when extending)

I’m confused - is this expected behaviour?

Cheers,  
Ian

ps.

$ ruby --version  
ruby 1.8.5 (2006-08-25) [powerpc-darwin8.7.0]

---

<div class="post-metadata">

**Author:** ![ian](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/bb73d2/32.png) [@ian](https://www.ruby-forum.com/u/ian)\
**Post date:** [December 21, 2006, 4:58pm UTC](https://www.ruby-forum.com/t/extend-weirdness/80123/3 "2006-12-21T16:58:40Z")

</div>

Hi –

On Fri, 22 Dec 2006, Ian W. wrote:

> ```
> end
> include Foo
> def self.extended(base)
> class<<base
> remove_method :meth
> end
> end
> 
> ```
> 
> end
> 
> But this workaround does what I’d expect Ruby to do (overwrite any  
> existing methods when extending)
> 
> I’m confused - is this expected behaviour?

Yes. When you send a message to A, it searches for a  
corresponding method in:

its singleton class  
modules mixed into its singleton class  
its “birth class” (Class in this case)  
modules mixed into its birth class  
etc. (up to Object and Kernel)

in that order. When you do “extend Bar”, you’ve inserted Bar as one  
of the modules mixed into the singleton class of A (line 2). But when  
you do include Foo, you insert the method “meth” directly into the  
singleton class (line 1). Therefore, that version of “meth” will  
always take priority, no matter how many modules you mix in or in what  
order.

David

---

<div class="post-metadata">

**Author:** ![ian](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/bb73d2/32.png) [@ian](https://www.ruby-forum.com/u/ian)\
**Post date:** [December 21, 2006, 6:00pm UTC](https://www.ruby-forum.com/t/extend-weirdness/80123/4 "2006-12-21T18:00:55Z")

</div>

Ian W. wrote:

> ```
> end
> def meth
> puts A.meth
> 
> ```
> 
> produces:  
> Foo
> 
> whereas I would expect it to produce “Bar”
> 
> Can anyone explain what’s going on here? i.e. Why the latter extend  
> with Bar doesn’t over-write the class method introduced by Foo

The answer is simple: extend doesn’t overwrite methods, it just  
includes the module for the singleton object. As there is already a  
singleton method ‘meth’ defined in the singleton object A, this method  
is used systematically in method calls.

Does that explain your result ? For information, extend is

rb\_extend\_object(obj, module)  
VALUE obj, module;  
{  
rb\_include\_module(rb\_singleton\_class(obj), module);  
}

It is basically like

class \<\< self  
include Something  
end

Cheers,

```
Vince
```

---

<div class="post-metadata">

**Author:** ![ian](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/bb73d2/32.png) [@ian](https://www.ruby-forum.com/u/ian)\
**Post date:** [December 21, 2006, 5:26pm UTC](https://www.ruby-forum.com/t/extend-weirdness/80123/5 "2006-12-21T17:26:46Z")

</div>

Thanks David for that very clear explanation, I am no longer confused.

Cheers,  
Ian
