为了帮助您理解这一点,ruby 为您提供了Module#ancestors:
Object.ancestors # => [Object, Kernel, BasicObject]
这是搜索Object的实例方法的顺序。因此,让我们测试您的示例。
首先,包括两个模块:
module M; end
module N; end
class C
include M
include N
end
C.ancestors # => [C, N, M, Object, Kernel, BasicObject]
所以方法将首先在C 中搜索。如果未找到具有给定名称的方法,则首先在 N 中搜索,然后在 M 中搜索。换句话说 - 您包含模块的相反顺序。
二、模块,包含一个模块,包含在一个类中:
module X; end
module Y
include X
end
class K
include Y
end
K.ancestors # => [K, Y, X, Object, Kernel, BasicObject]
所以我们可以看到同样的规则也适用于包含在模块中。就像在前面的示例中,首先在C 中搜索方法,然后在C 中包含的模块中搜索,这里将首先在模块中搜索方法,然后才在包含的模块中搜索那个模块。
除了一致性之外,原因在于类实际上是 Ruby 中的模块:
Class.superclass # => Module
有很多规则。例如在层次结构中包含两次相同的模块、单例类、#prepend、#method_missing 等。但是知道怎么用#ancestors就可以推导出来。