0

这是一些演示我正在谈论的行为的代码:

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

所以def添加到 B 的 s 会反映在 C 中,而添加include的 s 则不会(除非之后重新包含 B)。为什么会这样,有没有干净的方法解决它?

4

1 回答 1

1

When you include a module M in a class C, this is what happens:

  1. Ruby creates a class (let's call it ⟦M′⟧) whose method table pointer, constant table pointer and class variable table pointer point to M's method table, constant table and class variable table.
  2. ⟦M′⟧'s superclass pointer is set to C's superclass.
  3. C's superclass pointer is set to ⟦M′⟧.

If there are modules includeed in M, this process is applied recursively.

Note that the recursive flattening of mixins is applied once, when you call include. Any changes in the inheritance hierarchy that are made afterwards will not be reflected.

However, when you add a method to M's method table, that change will be reflected, because there is only one method table, to which both M and ⟦M′⟧ refer.

于 2013-05-06T10:57:38.180 回答