From: Josh Cheek Date: 2010-06-15T23:35:38+09:00 Subject: Re: Unexpected behavior in inject --0016e6db29997267c404891283d4 Content-Type: text/plain; charset=ISO-8859-1 On Tue, Jun 15, 2010 at 9:21 AM, Alex Fort wrote: > I ran across something that puzzled me today, and I thought I'd ask here > and > see what you guys/girls think. I'm by no means a ruby guru, so if this is > obvious to everyone but me, I'll take the learning experience. > > > Here's the simple script I was testing out: > > [1,2,3].inject(0) do |acc, num| > acc + num > end > > Let me give you a slightly different example to show how it works: You pass in the zero, and it goes into acc in the block. Whatever the block returns is then fed back into acc, for the next iteration. After the last iteration, whatever the block returns is returned by the inject method. I think of it as a number passing through an Enumerable and coming out the other side modified. (5..10).inject 0 do |sum,num| sum + num end This should return 45 in the following manner: The first time the block is passed 0 , 5 and it returns 5 The second time the block is passed 5 , 6 and it returns 11 The third time the block is passed 11 , 7 and it returns 18 The fourth time the block is passed 18 , 8 and it returns 26 The fourth time the block is passed 26 , 9 and it returns 35 The fourth time the block is passed 35 , 10 and it returns 45 The method then returns 45 So why doesn't this work? [1,2,3].inject(0) do |acc, num| > acc + num > puts acc > end > Because the puts method returns nil. It is also the last thing in the block, so the block returns nil. So nil is fed back into acc. Then nil + acc raises the NoMethodError. To resolve this, think about where you could put the puts method that won't cause the block to return nil. ----- If you are interested, here is a functional version (takes the enumerable as a parameter) of inject that I wrote, except I call ti "passthrough" because that is more meaningful for me. def passthrough( enumerable , to_pass ) enumerable.each do |element| to_pass = yield to_pass , element end to_pass end --0016e6db29997267c404891283d4--