如何创建枚举器包装类?

时间:2022-12-26 22:47:55

I have this function:

我有这个功能:

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

I can use it like this:

我可以像这样使用它:

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

Instead, I'd like to put it in its own class and use it like this:

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

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

I've tried some things I didn't expect to work, like just returning the enumerator out of initialize(), and self = file_parser().

我已经尝试了一些我不希望工作的东西,比如只是将枚举器从initialize()和self = file_parser()中返回。

I've also tried super do |yielder|.

我也试过超做| yielder |。

For some reason, the way to do this is not coming to me.

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

2 个解决方案

#1


2  

You can just include the Enumerable module into your class, and define an each function which calls yield.

您可以在您的类中包含Enumerable模块,并定义一个调用yield的函数。

You still get all the Enumerable methods like map, reduce, etc, for free.

你仍然可以免费获得所有的Enumerable方法,如map,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 }

Output:

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

#2


1  

Make file_parser a private method in SpecialParser.

使file_parser成为SpecialParser中的私有方法。

Then set up the rest of the class like this:

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

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

EDIT:

If you want the other Enumerable method for free, you also have to include Enumerable in the class.

如果你想免费获得另一个Enumerable方法,你还必须在类中包含Enumerable。

#1


2  

You can just include the Enumerable module into your class, and define an each function which calls yield.

您可以在您的类中包含Enumerable模块,并定义一个调用yield的函数。

You still get all the Enumerable methods like map, reduce, etc, for free.

你仍然可以免费获得所有的Enumerable方法,如map,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 }

Output:

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

#2


1  

Make file_parser a private method in SpecialParser.

使file_parser成为SpecialParser中的私有方法。

Then set up the rest of the class like this:

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

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

EDIT:

If you want the other Enumerable method for free, you also have to include Enumerable in the class.

如果你想免费获得另一个Enumerable方法,你还必须在类中包含Enumerable。