当我将一个模块包含在另一个已经包含在类中的模块时,该类无法访问新方法

时间:2013-05-06 03:36:45

标签: ruby

以下是一些代码,展示了我正在谈论的行为:

module A
  def foo; end
end

# initialize B with no methods
module B; end

class C
  include B
end

# add methods to B
module B
  def foo; end
  include A
end

C.new.foo
C.new.bar # error: instance method bar is not defined for C

因此添加到B的def反映在C中,而添加的include s则不反映(除非之后重新包含B)。为什么会这样,并且有一个干净的方式吗?

1 个答案:

答案 0 :(得分:1)

当您在include课程中M模块C时,会发生以下情况:

  1. Ruby创建了一个类(让我们称之为⟦M′⟧),其方法表指针,常量表指针和类变量表指针指向M的方法表,常量表和类变量表。 / LI>
  2. ⟦M′⟧的超类指针设置为C的超类。
  3. C的超类指针设置为⟦M′⟧
  4. 如果include中有M个模块,则会以递归方式应用此过程。

    请注意,当您调用include时,mixin的递归展平会在一次时应用。 之后对继承层次结构所做的任何更改都将被反映出来。

    但是,当您向M的方法表添加方法时,将反映该更改,因为只有一个方法表,M⟦M′⟧参考。