Bug #8066

Inconsistency in ancestors chain

Added by Ilya Vorontsov about 1 year ago. Updated about 1 year ago.

[ruby-core:53278]
Status:Open
Priority:Normal
Assignee:-
Category:-
Target version:-
ruby -v:1.9.3p0, 2.0.0p0 Backport:

Description

Method including have some inconsistencies. Let's define module and include(or prepend) and then include it in classes in different order.

module M; end
Class.send :include, M
Module.send :include, M
Class.ancestors

=> [Class, M, Module, M, Object, Kernel, BasicObject]

module M; end
Module.send :include, M
Class.send :include, M
Class.ancestors

=> [Class, Module, M, Object, Kernel, BasicObject]

We see that ancestor chains are different. Is it a spec(i didn't find it in tests) or a bug?


Related issues

Duplicates ruby-trunk - Feature #1586: Including a module already present in ancestors should no... Assigned 06/07/2009

History

#1 Updated by Nathan Zook about 1 year ago

This is the behaviour I would expect in all versions of Ruby. The ancestor chain is set at the time that a class is created, and is updated at the time that a module is included in that class. What does not happen is that the chain for a class is recomputed when a module is included in an ancestor of the class.

So:

module N ; end
class C ; include N ; end
module M ; end
N.send :include, M
N.ancestors
=> [N, M]
C.ancestors
=> [C, N, Object, Kernel, BasicObject]

Your example is the natural result of this behaviour. Note, however, that reincluding a module will pick up its current includes:
C.send :include, N
C.ancestors
=> [C, N, M, Object, Kernel, BasicObject]

#2 Updated by Ilya Vorontsov about 1 year ago

Isn't it just a conseqency of the fact that module can't be included twice and because of that including a module in parent class prevents including module into a child class.
This behavior disallows for example creating decorators by prepending named modules.

Also available in: Atom PDF