如何创建枚举器包装类?

时间:2013-09-12 19:00:19

标签: ruby

我有这个功能:

def file_parser (filename)
  Enumerator.new do |yielder|
    File.open(filename, "r:ISO-8859-1") do |file|
      csv = CSV.new(file, :col_sep => "\t", :headers => true, :quote_char => "\x07")                            
      csv.each do |row|
        yielder.yield map_fields(clean_data(row.to_hash))
      end
    end
  end
end

我可以这样使用它:

parser = file_parser("data.tab")
parser.each do { |data| do_profitable_things_with data }

相反,我想将它放在自己的类中并像这样使用它:

parser = SpecialParser.new("data.tab")
parser.each do { |data| do_profitable_things_with data }

我尝试了一些我不希望工作的事情,比如只是将initialize()self = file_parser()退回调整器。

我也试过super do |yielder|

出于某种原因,这样做的方法不是来找我。

2 个答案:

答案 0 :(得分:2)

您可以在您的班级中加入Enumerable模块,并定义一个each函数,该函数会调用yield

您仍然可以免费获得Enumerablemap等所有reduce方法。

class SpecialParser
  include Enumerable

  def initialize(n)
    @n = n
  end

  def each
    0.upto(@n) { |i| yield i }
  end
end

sp = SpecialParser.new 4
sp.each { |i| p i }
p sp.map { |i| i }

输出:

0
1
2
3
4
[0, 1, 2, 3, 4]

答案 1 :(得分:1)

file_parser中将SpecialParser设为私有方法。

然后像这样设置其余的类:

class SpecialParser
  include Enumerable  # needed to provide the other Enumerable methods

  def initialize(filename)
    @filename = filename
    @enum = file_parser(filename)
  end

  def each
    @enum.each do |val|
      yield val
    end
  end
end

编辑:

如果你想免费获得另一个Enumerable方法,你也必须在课堂上include Enumerable