初始化由包含的模块覆盖时调用父构造函数

时间:2012-05-30 18:30:41

标签: ruby mongodb mongoid

我有一个类层次结构如下:

class Tree
  def initialize(id, value)
    @id, @value = id, value
  end
end

class Entity < Tree

  include Mongoid::Document

  def initialize(id, value)
    # Do some stuff...
    super(id, value)
  end

end

但是,在super方法中调用Entity#initialize会调用initialize中的Mongoid::Document方法,而不是父类Tree中的Tree#initialize方法。

Entity#initialize模块被包含之后,如何从Mongoid::Document的正文中调用{{1}}方法?

1 个答案:

答案 0 :(得分:4)

这就是Ruby的工作方式。当您包含模块时,ruby会隐式创建一个匿名类,并将其置于方法查找队列中的当前值之上。

同时调用Entity.ancestors会在列表中显示Mongoid::Document

我可以推荐一本好书:Metaprogramming Ruby Paolo Perotta

此处还有a forum thread on a similar topic explaining super stuff

更新

如果避免调用模块构造函数就是你想要的一个可能的技巧

class Entity < Tree

  def initialize(id, value)
    # Do some stuff...
    # initialize first
    super(id, value)
    # and after that - extend
    extend Mongoid::Document
  end

end

此方法未在模块上运行self.included。如果您需要保留此功能,仍然不能运行模块的初始化程序,则可以在init中使用本征类:

class Entity < Tree

  def initialize(id, value)
    # Do some stuff...
    # initialize first
    super(id, value)
    # and after that - include into eigenclass
    class << self
      include Mongoid::Document
    end
  end

end