[prev in list] [next in list] [prev in thread] [next in thread] 

List:       ruby-talk
Subject:    Design problem with 'inject'
From:       Gary Boone <dr () garyboone ! com>
Date:       2006-11-15 6:46:44
Message-ID: 9309e6b25d77d691669dfff1d4786556 () ruby-forum ! com
[Download RAW message or body]


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/.

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic