使用枚举器而不是循环

时间:2014-07-16 14:42:33

标签: ruby enumerator

我通常使用loop如下所示从外部API或DB(redis pop)请求数据:

records = []
loop do
  record = MyHandler.new(token).fetch
  break unless record
  records.push(record)
end

它有效,但为了让它看起来更好,我想知道是否有任何方法可以使用Enumerator。有谁知道吗?

4 个答案:

答案 0 :(得分:5)

将代码包装在Enumerator中非常简单:

record_enumerator = Enumerator.new do |y|
  loop do
    record = MyHandler.new(token).fetch
    break unless record
    y << record
  end
end

您现在可以使用块迭代记录:

record_enumerator.each { |record|
   # do something with record
}

或者使用以下内容获取所有记录:

records = record_enumerator.to_a

如果您的班级是MyHandler,则可以改为MyHandler#each并包含Enumerable

答案 1 :(得分:2)

这个怎么样?

while(record = MyHandler.new(token).fetch)
  records.push(record)
end

摆脱了丑陋的循环/中断逻辑。

或者,您可以创建一个可相关的对象,而不是使用records数组:

class RecordList
  include Enumerable

  attr :token

  def initialize(token)
    @token = token
  end

  def each
    MyHandler.new(token).fetch
  end
end

records = RecordList.new token

答案 2 :(得分:0)

你可以在ruby中使用while循环:

records = []
record = MyHandler.new(token).fetch
while record do
    records << record
    record = MyHandler.new(token).fetch
end

可能有一种更加优雅的方式,但从提供的信息来看,这是我能想到的最好的方式。

答案 3 :(得分:0)

如果您正在寻找非常简短的语法,请转到:

records << record while record = MyHandler.new(token).fetch

它会像魅力一样工作,在执行循环体之前完成条件检查,因此记录总是被初始化。