Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I need to use .inject(0) rather than .inject to make this work?

I am creating a rails app and have used this code in one of my methods

item_numbers.inject(0) {|sum, i| sum + i.amount}

item_numbers is an array of objects from my item_numbers table. The .amount method that I apply to them looks up the value of an item_number in a separate table and returns it as a BigDecimal object. Obviously the inject method then adds all of the returned i.amount objects and this works just fine.

I am just curious as to why it didn't work when I wrote this statement as

item_numbers.inject {|sum, i| sum + i.amount}

According to my trusty pickaxe book these should be equivalent. Is it because i.amount is a BigDecimal? If so, why does it now work? If not, then why doesn't it work.

like image 487
brad Avatar asked Mar 22 '10 10:03

brad


People also ask

What does .inject mean in Ruby?

Inject applies the block result + element. to each item in the array. For the next item ("element"), the value returned from the block is "result". The way you've called it (with a parameter), "result" starts with the value of that parameter. So the effect is adding the elements up.

What does :+ mean in Ruby?

inject(:+) is not Symbol#to_proc, :+ has no special meaning in the ruby language - it's just a symbol.


1 Answers

What we can read in API:

If you do not explicitly specify an initial value for memo, then uses the first element of collection is used as the initial value of memo.

So item_numbers[0] will be specified as an initial value - but it is not a number, it is an object. So we have got an error

undefined method `+'.

So we have to specify initial value as 0

item_numbers.inject(0){ |sum, i| sum + i }

like image 172
fl00r Avatar answered Oct 14 '22 12:10

fl00r