Ruby's inject has a design that can lead to hard to find bugs. The
problem is that you don't have to specify what is summed; the value of
the block is summed. That means 'next' can lead to a bug. Here's an
example:
No problem:
arr.inject(0) do |sum, i|
sum += i
done
But suppose you need to skip some elements, so you add a 'next'
statement.
Problem:
arr.inject(0) do |sum, i|
next if (i==3)
sum += i
done
This breaks. If i is 3, then when the next occurs, the value of the
block is nil. The value of the block is added to sum, but because "+"
isn't defined for nil, there's an exception. Note that this isn't due to
the line "sum += i"; it's due to the design of inject: the value of the
block is added to sum.
The real problem is that 'inject' has two semantics: 1) it adds onto sum
using an explicit "sum +=" or 2) is adds the value of the block. A
better approach would be allow only one way to accumulate. That way, you
can't make a change that inexplicitly changes the function from one
semantics to another.
···
--
Posted via http://www.ruby-forum.com/.