Question about include and modules

ruby -v
ruby 1.6.7 (2002-03-01) [i586-mswin32]

Can someone tell me why:

module A
	def a
	end
end

module B
	include A
end

class C
	include B
end

puts C.ancestors
puts A === C.new
puts

will produce:

C
B
A
Object
Kernel
true

Yet, the following:
module A
def a
end
end

module Enumerable
	include A
end

puts Array.ancestors
puts A === Array.new
puts

yields:

Array
Enumerable
Object
Kernel
false

I expected something akin to

Array
Enumerable
A
Object
Kernel
Happily True

Did I do something wrong? Should I be tortured? Zod Ruby community help me!

  module Enumerable
    include A
  end

Add these lines

        class Array
           include Enumerable
        end

  puts Array.ancestors
  puts A === Array.new
  puts

Guy Decoux

Is this because array.c uses rb_include_module instead of
rb_mod_include?

···

On Wed, Mar 26, 2003 at 06:22:23PM +0900, ts wrote:

module Enumerable
  include A
end

Add these lines

    class Array
       include Enumerable
    end


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

But what can you do with it?
– ubiquitous cry from Linux-user partner

Is this because array.c uses rb_include_module instead of
rb_mod_include?

No, the problem is with the internal of ruby. When you add a module in
another module, you must re-call include to force ruby to update the
`path' of the class.

When you write

    class A
       include B
    end

The `path' for A is

    A ==> [B] ==> Object ==> [Kernel]

where [B] is a proxy class which refer to the module B

Now with

   module B
      include C
   end

   class A
      include B
   end

ruby will do

    A ==> [B] ==> [C] ==> Object ==> [Kernel]

i.e. the path is modified when ruby *make* the include

If you include another module in B, ruby will not update the path for A
(it has lost the information that B was included in A)

Guy Decoux

Is this because array.c uses rb_include_module instead of
rb_mod_include?

[great explanation]

If you include another module in B, ruby will not update the path for A
(it has lost the information that B was included in A)

Is this just an implementation issue that will be solved eventually (in
Rite?) or are the current semantics going to stay fixed?

···

On Wed, Mar 26, 2003 at 06:54:58PM +0900, ts wrote:


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

Linux: Where Don’t We Want To Go Today?
– Submitted by Pancrazio De Mauro, paraphrasing some well-known sales talk

Is this just an implementation issue that will be solved eventually (in
Rite?) or are the current semantics going to stay fixed?

Well, you can perhaps change this behavior with a judicious use of
#append_features :-))

Guy Decoux

Hi,

···

In message “Re: question about include and modules” on 03/03/26, Mauricio Fernández batsman.geo@yahoo.com writes:

If you include another module in B, ruby will not update the path for A
(it has lost the information that B was included in A)

Is this just an implementation issue that will be solved eventually (in
Rite?) or are the current semantics going to stay fixed?

It is implementation issue, but I don’t think it would be fixed,
since:

(a) it is easy to fix by re-include modules.

(b) it needs to track bi-directional inclusion relationship to “fix”
this automatically. I feel it is not worth it.

						matz.

The fact that this hasn’t bitten badly people out there seems to
indicate that in the praxis “module inclusion hierarchies” are not too
deep.

I’m going to start to collect such oddities (esp. implementation issues), as

  • they pinpoint where the implementation difficulties/tradeoffs lie
    => lessons for future efforts (?)
  • they might prove to be good material for FAQ and such docs.
  • they would be massively useful in case any “Obfuscated Ruby Code
    Contest” were to start :wink:
···

On Wed, Mar 26, 2003 at 11:02:32PM +0900, Yukihiro Matsumoto wrote:

Hi,

In message “Re: question about include and modules” > on 03/03/26, Mauricio Fernández batsman.geo@yahoo.com writes:

If you include another module in B, ruby will not update the path for A
(it has lost the information that B was included in A)

Is this just an implementation issue that will be solved eventually (in
Rite?) or are the current semantics going to stay fixed?

It is implementation issue, but I don’t think it would be fixed,
since:

(a) it is easy to fix by re-include modules.

(b) it needs to track bi-directional inclusion relationship to “fix”
this automatically. I feel it is not worth it.


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

If loving linux is wrong, I dont wanna be right.
– Topic for #LinuxGER