【发布时间】:2019-02-25 11:06:11
【问题描述】:
我编写了一个 Enumerable 类来无缝且延迟地获取 API 请求的所有页面。
class Pager
include Enumerable
def initialize(&fetch_next_page)
@fetch_next_page = fetch_next_page
reset
end
def reset
@page_number = 0
end
private def next_page
@page_number += 1
return @fetch_next_page.call(@page_number)
end
def each(&block)
if block_given?
while resp = next_page
resp.each(&block)
end
reset
else
to_enum(:each)
end
end
end
这是一个如何使用它的示例。
pager = Pager.new do |page_number|
response = fetch_page( page: page_number, **some_options )
response.page <= response.total_pages ? response.stuff : false
end
但我开始意识到这一切都是在执行一个返回 Enumerable 直到其为 false 的块,并且它正在压平 Enumerables。
pager = Pager.new { |page_number|
page_number <= 3 ? 1.upto(page_number) : false
}
# [1, 1, 2, 1, 2, 3]
puts pager.to_a.inspect
有没有更简单的方法来做到这一点?我已经接近 Enumerator,但无法让扁平化工作。
def paginate(&fetch_next)
return Enumerator.new do |yielder|
page_number = 1
while ret = fetch_next.call(page_number)
yielder.yield(*ret)
page_number += 1
end
end
end
pager = paginate { |page_number|
page_number <= 3 ? 1.upto(page_number) : false
}
# [1, [1, 2], [1, 2, 3]]
puts pager.to_a.inspect
【问题讨论】:
标签: ruby enumerable