I understand that when a module is included into a class, it behaves like a direct superclass of the class it is included into.
However, what if there are multiple modules included in the same class? Which one is now a direct superclass if there is no relationship between modules?
And what if module A includes module B (so there is a relationship in a way), overrides some of its methods, and now both A and B are included in the same class. Does that class now define all methods from A and B, and from the methods that are common to A and B, it uses only the methods that A overrides?
To help you understand that, ruby provides you with
Object.ancestors # => [Object, Kernel, BasicObject]
This is the order, in which an instance method of
Object will be searched for. So lets test your examples.
First, two modules included:
module M; end module N; end class C include M include N end C.ancestors # => [C, N, M, Object, Kernel, BasicObject]
So the methods will first be searched for in
C. If a method with the given name is not found, it is searched for first in
N and then in
M. In other words - the reverse order of which you included the modules.
Second, module, including a module, included in a class:
module X; end module Y include X end class K include Y end K.ancestors # => [K, Y, X, Object, Kernel, BasicObject]
So we can see that the same rule applies for including in modules. Just as in the previous example a method will first be searched for in
C and only then in the modules included in
C, here a method will first will be searched for in a module, and only then in the included modules in that module.
The reason for that, other than consistency, is that classes are actually modules in Ruby:
Class.superclass # => Module
There are a lot of rules. For example including the same module twice in the hierarchy, singleton classes,
#method_missing and so on. But you can deduce all of it knowing how to use