starfry starfry - 7 months ago 8
Ruby Question

In Ruby, is it possible to move a module up the ancestor chain?

I have a Ruby class

C
that includes some third-party modules, say
A
and
B
.

Module
A
is included indirectly via
C
's class inheritance chain; assume I have no control over where
A
gets incuded. Now,
C
includes
B
directly, but
B
includes another module
D
which happens to provide functionality that is also provided by
A
, like this:

class C < Base

# Base includes A

include B # includes D

# methods in A overridden by D

end


The ancestor chain goes something like this (where
...
represents zero or more other ancestors that aren't relevant to this discussion):

C ... B ... D ... A


I want the functionality of
A
to take precdence over
D
: I want to move
A
so it is in front of
D
in the ancestor chain, like this:

C ... A ... B ... D


I have tried simply including
A
again but this didn't work. Is there a way to do this?

Answer

It is impossible to change the mixin hierarchy once it is established. And only the inclusion order determines the hierarchy. You have to include A into C (for the first time) after you include B into C, or, if you prepend A to C instead of including it, then it will have precedence over D even if B is included into C later.