有一个cop: RuboCop::Cop::Lint::NextWithoutAccumulator
有谁能解释一下这个cop是用来做什么的,它是如何以什么方式改进代码的?
是否提高了可读性和效率?
github代码。
让我们考虑文档中的示例代码:
# bad
result = (1..4).reduce(0) do |acc, i|
next if i.odd?
acc + i
end
如果您在控制台中尝试此操作,您将获得nil
对象的NoMethodError
异常。这是因为如果没有指定对象,next
"返回"nil
。您可以将其视为迭代器的return
。
对于reduce
方法,它可能会导致一些意想不到的行为,因为它需要块返回的一些值。如果i
是奇数,则计算next
, block给出nil
作为结果。在下面的迭代器中,acc
等于nil
,并且不能向其添加整数。在我们的示例中,第一次迭代是针对i = 1
, next
将acc
设置为nil
作为块的结果。
在某些情况下,您可以为可枚举对象获得正确的值,但通常在内部指定next
的值更安全。
Bad
result = (1..4).reduce(0) do |acc, i|
next if i.odd?
acc + i
end
<标题> result = (1..4).reduce(0) do |acc, i|
next acc if i.odd?
acc + i
end
正如@smefju所指出的,next本身隐式返回nil
,并且当它作为下一次执行块的参数传入时,将导致NoMethodError
。