使模块预先包含另一个(模块继承)ruby

时间:2014-11-29 04:45:59

标签: ruby module

我有两个Ruby Module,其中一个逻辑上继承了'从另一个:

module FileBacked
  attr_reader :file
  def file=( path )
    @file    = path
    @content = File.read(path,encoding:'utf-8') if File.exist(path)
  end
  def save!
    File.open(@file,'w:utf-8'){ |f| f << @content } if @file
  end
end

module XMLBacked
  attr_reader :doc
  def file=( path )
    super
    @doc = Nokogiri.XML(@content)
  end
  def save!
    @content = @doc.to_xml
    super
  end
end

因此,对super的调用将起作用,需要像以下一样使用它们:

class Foo
  include FileBacked # Always include this first
  include XMLBacked  # Always include this second
end

p Foo.ancestors
#=> [Foo, XMLBacked, FileBacked, Object, Kernel, BasicObject]

我希望能够写下:

class Bar
  include XMLBacked  # Also includes FileBacked
end

...但我无法弄清楚如何在搜索方法层次结构时导致FileBacked XMLBacked之后出现这种情况。

如果我入侵包含,则结果是错误的查找顺序:

module XMLBacked
  def self.included(klass)
    klass.instance_eval{ include FileBacked }
  end
end

class Jim
  include XMLBacked
end
p Jim.ancestors
#=> [Jim, FileBacked, XMLBacked, Object, Kernel, BasicObject]

如何在XMLBacked之后将FileBacked原因XMLBacked包含在查询链中?

1 个答案:

答案 0 :(得分:0)

答案存在于一个重复的问题中,尽管我最初没有看到它:

module XMLBacked
  include FileBacked
  # other XMLBacked methods here
end

这会导致FileBackedXMLBacked之前注入XMLBacked,只要它包含{{1}}。