背景:我需要确定远程位置的记录数量。记录按顺序编号(从0
开始,没有间隙),并且只能根据它们的编号逐个提取。
通过网络获取记录的方法在成功时返回truthy值,在失败时返回false。以下是一个例子:
fetch_record(0) #=> true (record #0 exists)
fetch_record(1) #=> true (record #1 exists)
fetch_record(2) #=> true (record #2 exists)
fetch_record(3) #=> nil (no record #3)
我正试图找到一种优雅的方法来计算我可以用递增参数调用fetch_record
的次数,直到它返回nil
(在上例中为3次)。
到目前为止我尝试了什么
考虑到这种简化的测试实现:
def fetch_record(index)
raise if index > 3 # just to prevent endless loops
true if index < 3
end
以下是我的尝试:
带有显式计数器变量的
while
循环显然可以工作,但我看起来不太习惯:i = 0 i += 1 while fetch_record(i) i #=> 3
我可以使用带有显式结果值的
step
和break
,但这看起来很麻烦:0.step(by: 1).each { |i| break i unless fetch_record(i) } #=> 3
懒惰的枚举器更糟糕:
0.step(by: 1).lazy.map { |i| fetch_record(i) }.take_while(&:itself).count #=> 3
有没有一种更容易的方法来实现上述目标?
假设您可以自由地以另一种方式实现fetch_record
,则为不存在的记录返回true
:
def fetch_record index
index >= 3
end
(0..Float::INFINITY).detect &method(:fetch_record)
#⇒ 3
take_while any?
records = 0.step.take_while{|i| fetch_record(i)}