为什么向模块添加方法以不同方式添加子模块?

时间:2014-03-14 12:53:59

标签: ruby module

在以下示例中,模块M包含在类A中,然后重新打开以添加子模块MM和方法。然后,它包含在课程B中:

module M
  def foo; "foo" end 
end

class A
  include M
end

module MM
  def baz; "baz" end 
end

module M
  include MM
  def bar; "bar" end 
end

class B
  include M
end

AB的实例都可以访问M的方法,无论它们何时添加,但只有B具有子模块的方法{{1} }:

MM

我认为这是不一致的行为,并想了解为什么会发生这种情况。

1 个答案:

答案 0 :(得分:2)

当您include模块M进入具有超类C的班级S时,会发生以下情况:

  1. 创建一个类M',其方法表指针,常量表指针,实例变量表指针和类变量表指针指向M方法表,常量表,实例变量表和类变量表。
  2. M'的超类指针设置为C的超类(即S
  3. C的超类指针设置为M'
  4. 对于混合到M中的任何模块(以及混合到模块中的模块混合到M等等),递归重复此过程。

    这样,当你调用include时,mixin层次结构的线性化只需要发生一次。另一种选择(这似乎是你期望发生的事情)是为每个方法调用执行这个相当昂贵的过程。