Inclusion of module: differences

Hi all!

I have this code: Parked at Loopia

And the output of that script is:

“Included from Array3”
“Included from Array”
“Included from Array2”
“[]”
“[]”
“aaarghhhh…”
nil

Obiously the difference in output is because I include the module in
different ways. But why is it different? Am I doing something wrong?
Should I use class_eval or something?

Thanks in advance!

Leon

On Thu, May 29, 2008 at 12:27 AM, Leon B. [email protected]
wrote:

Hi all!

I have this code: Parked at Loopia

And the output of that script is:

Obiously the difference in output is because I include the module in
different ways. But why is it different? Am I doing something wrong?
Should I use class_eval or something?

Appending this to your test code may be enlightening:

p a.class.ancestors # => [Array, InstanceMethods, Enumerable, Object,
Kernel]
p a2.class.ancestors # => [Array2, Array, InstanceMethods,
Enumerable, Object, Kernel]
p a3.class.ancestors # => [Array3, InstanceMethods, Array,
InstanceMethods, Enumerable, Object, Kernel]

This gives an indication of the search order for method lookup. For
‘a’ which is an instance of Array, the inspect method is found in the
Array class and included modules are thus not checked. Because you
included InstanceMethods in array already, including it in Array2
doesn’t do anything because Ruby tries to include a module only once
in each class/module. Because the include in Array3 happens before the
one in Array, it is actually performed because Ruby cannot foresee
that you are about to include the same module in Array. So in case of
Array3, InstanceMethods comes before Array in the method lookup path,
in case of Array2 it doesn’t.

So basically, the order of includes in Ruby matters. Also, redefining
methods of a class by including a module doesn’t always work because
the module is put underneath the class, not on top of it. It only
works if the method is defined in a superclass of the class where you
include that module. (Still wishing Ruby had a preclude method…)

Peter

Wow, thanks Peter! That was very enlightening!