# Unexpected behavior in inject

**URL:** <https://www.ruby-forum.com/t/unexpected-behavior-in-inject/190161>\
**Category:** Ruby\
**Created:** [June 17, 2010, 4:22pm UTC](https://www.ruby-forum.com/t/unexpected-behavior-in-inject/190161 "2010-06-17T16:22:04Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![absolute-beginner](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a5b964/32.png) [@absolute-beginner](https://www.ruby-forum.com/u/absolute-beginner)\
**Post date:** [June 17, 2010, 4:22pm UTC](https://www.ruby-forum.com/t/unexpected-behavior-in-inject/190161/1 "2010-06-17T16:22:04Z")

</div>

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

It works perfectly fine when I run it. No surprises here. However, when  
I  
add a puts call after the accumulator addition, like so:

[1,2,3].inject(0) do |acc, num|  
acc + num  
puts acc  
end

Ruby gives me this error:

bash ~ $ ruby test.rb  
0  
test.rb:2: undefined method `+' for nil:NilClass (NoMethodError) from test.rb:5:in`inject’  
from test.rb:1:in `each' from test.rb:1:in`inject’  
from test.rb:1

This seems pretty strange to me, as if puts is modifying the accumulator  
by  
resetting it to nil. Is this normal behavior? If so, I would greatly  
appreciate it if someone could point me in the right direction as to why  
this is the way it is. I also noticed that if I place the puts call  
_before_  
the addition, there is no error, which also strikes me as a little odd.  
Here’s my ruby version (using cygwin on windows server 2003):

bash ~ $ ruby -v  
ruby 1.8.6 (2007-09-24 patchlevel 111) [i386-mswin32]

Thanks,  
Alex

---

<div class="post-metadata">

**Author:** ![absolute-beginner](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a5b964/32.png) [@absolute-beginner](https://www.ruby-forum.com/u/absolute-beginner)\
**Post date:** [June 17, 2010, 4:22pm UTC](https://www.ruby-forum.com/t/unexpected-behavior-in-inject/190161/2 "2010-06-17T16:22:15Z")

</div>

On Tue, Jun 15, 2010 at 9:21 AM, Alex F. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> 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

---

<div class="post-metadata">

**Author:** ![absolute-beginner](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a5b964/32.png) [@absolute-beginner](https://www.ruby-forum.com/u/absolute-beginner)\
**Post date:** [June 17, 2010, 4:22pm UTC](https://www.ruby-forum.com/t/unexpected-behavior-in-inject/190161/3 "2010-06-17T16:22:38Z")

</div>

> test.rb:2: undefined method `+' for nil:NilClass (NoMethodError) from test.rb:5:in`inject’  
> from test.rb:1:in `each' from test.rb:1:in`inject’  
> from test.rb:1
> 
> This seems pretty strange to me, as if puts is modifying the accumulator by  
> resetting it to nil. Is this normal behavior? If so, I would greatly  
> appreciate it if someone could point me in the right direction as to why  
> this is the way it is.

Yes, this is exactly as expected. The last statement you put in the  
block  
is the return value of the block. ‘puts’ always returns nil, so the  
next  
iteration acc is nil.

To get the behavior you are looking for:

[1,2,3].inject(0) do |acc, num|  
sum = acc + num  
puts sum  
sum  
end

Now since ‘sum’ is the final statement in the block, acc will be sum for  
the  
next iteration.

-Jonathan N.

---

<div class="post-metadata">

**Author:** ![absolute-beginner](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a5b964/32.png) [@absolute-beginner](https://www.ruby-forum.com/u/absolute-beginner)\
**Post date:** [June 17, 2010, 4:26pm UTC](https://www.ruby-forum.com/t/unexpected-behavior-in-inject/190161/4 "2010-06-17T16:26:21Z")

</div>

On Tue, Jun 15, 2010 at 10:31 AM, Jonathan N. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> > test.rb:2: undefined method `+’ for nil:NilClass (NoMethodError)
> 
> end
> 
> Now since ‘sum’ is the final statement in the block, acc will be sum for the  
> next iteration.

I understand now. Thank you for clarifying that for me.

Alex

---

<div class="post-metadata">

**Author:** ![absolute-beginner](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a5b964/32.png) [@absolute-beginner](https://www.ruby-forum.com/u/absolute-beginner)\
**Post date:** [June 17, 2010, 4:22pm UTC](https://www.ruby-forum.com/t/unexpected-behavior-in-inject/190161/5 "2010-06-17T16:22:49Z")

</div>

On Tue, Jun 15, 2010 at 10:35 AM, Josh C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> > [1,2,3].inject(0) do |acc, num|
> 
> The fourth time the block is passed 35 , 10 and it returns 45
> 
> > 
> 
> 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.

That’s where I was going wrong, I didn’t realize that inject passed  
the value of the _block_, back to the accumulator, not just the  
modified accumulator. I was thinking that ruby was somehow detecting  
when I modified the accumulator, so I was sometimes writing code like  
this:

[1,2,3].inject(0) {|acc, num| acc += num}

Now I get it. It’s all about the value of the block, and there’s  
really no magic going on. Insight is a wonderful thing 🙂

> to\_pass = yield to\_pass , element  
> end  
> to\_pass  
> end

Thanks again,  
Alex
