(i’m no ruby internals expert, just having some fun poking at rhg2)
On Tuesday 20 February 2007 02:59, Brian B. wrote:
Interesting to learn this behavior is considered a bug, and may one
day be fixed.
It is due the way method inheritance is implemented right now.
In MRI, every object has a linked list of classes from which inherits
This list contains either “plain” ruby classes, and other “hidden”
metaclasses, that serve to purposes such as singleton methods, class
and module inclusion1.
The latter is implemented by inserting in the linked list a new “include
class” whose mehtod table points to the included module’s method table.
This means that when you do
the ruby interpreter will build such an inheritance list:
A -> (iM) -> Object
so, instances of A will have access to M’s methods via the iM include
When you do
two include classes are created for A, pointing to every module in the
A -> (iM2’) -> (iM1) -> Object
… that’s why:
Interestingly, re-including Enumerable to Array, i.e., the line
class Array; include Enumerable end
… fixes the problem, because this include causes the include class of
module to be added to Array’s inheritance chain …
corrects the bug for Array — this is not necessarily a useful thing
to know since as you suggest putting code directly into Enumerable
rather than by using an include appears to be the way to go here.
… and also why adding code to enumerable works, because you are
method table already pointed by the include class in Array’s inheritance
Ruby internals are really really beautiful