Module include matters?

Hi,

I was playing with various modules and found something I can’t
explain. It seems like module inclusion’s order matters ? Here is a
simple test case :

module B; end
module C; include B; end

module A; def somemethod; end; end
#reopening
module B; include A; end

p B.instance_methods #=> [“somemethod”]
p C.instance_methods #=> [] ???

I don’t understand why C doesn’t inherit A’s instance_methods. Does
somebody know something about that ?


Cheers,
zimbatm

Hello,

On Tue, 20 Jun 2006 07:32:22 +0900, Jonas P. [email protected]
wrote:

I was playing with various modules and found something I can’t
explain. It seems like module inclusion’s order matters ? Here is a
simple test case :

[Snip example]

I don’t understand why C doesn’t inherit A’s instance_methods. Does
somebody know something about that ?

Yes, I asked a similar version of this question in [ruby-talk:121118]

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/121118

Pit C. provided a good summary and link to further details in
[ruby-talk:121191]

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/121191

I hope this helps,
Zev

This is called the “Dyanmic Module Inclusion Problem”. And Pit is
right, it is an implmentation issue. I think Matz would love to have a
fix for it, but appearently it is difficult, if not impossible, to do
so efficiently,

T.

Thanks both of you for your insight. I’ve created a small hack to fix
that issue

class Module

Weird hack to ensure deep inclusion of modules

def include_deep(mod)
include mod
ancestors[1…-1].select do |a|
a != mod and not a.ancestors.include?(mod)
end.each { |a| a.include_deep(mod) }
end
end


Cheers,
zimbatm

On 20/06/06, [email protected] [email protected] wrote:

Hmm… Doesn’t seem to do anything. Notice even without the above one
can instantiate a class and the mothod will “magically” showup. From
your example:

Hmm right, let me correct that

On 20/06/06, Jonas P. [email protected] wrote:

On 20/06/06, [email protected] [email protected] wrote:

Hmm… Doesn’t seem to do anything. Notice even without the above one
can instantiate a class and the mothod will “magically” showup. From
your example:

Hmm right, let me correct that

doh’ I would need to find the children and not the ancestors [C] of
the module (B) in which in include the other (A)… I guess it’s
doable by browsing the ObjectSpace but it’s quite expensive. If only
modules and classes would also list their childrens. Which is also
doable by overriding Module#included I guess but it’s not really
reliable isn’t it ?


Cheers,
zimbatm

Jonas P. wrote:

end
Hmm… Doesn’t seem to do anything. Notice even without the above one
can instantiate a class and the mothod will “magically” showup. From
your example:

class X
include B
end

X.new.somemethod

T.