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

> 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
>
> -- 
> Posted via 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 Gutteridge

Bioinformatics Center
Kyoto University