Question
I find this code in Ruby to be pretty intriguing
(1..4).inject(&:+)
Ok, I know what inject
does, and I know this code is basically equivalent to
(1..4).inject(0) {|a,n| a + n}
but how exactly does it work?
Why &:+
is the same as writing the block {|a,n| a + n}
?
Why it doesn't need an initial value? I'm ok with the inicial value being 0,
but (1..4).inject(&:*)
also works, and there the initial value must be 1...
Answer
From [Ruby documentation](http://ruby- doc.org/ruby-1.9/classes/Enumerable.html#M002714):
If you specify a symbol instead, then each element in the collection will be passed to the named method of memo
So, specifying a symbol is equivalent to passing the following block: {|memo, a| memo.send(sym, a)}
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, there is no magic, Ruby simply takes the first element as the initial
value and starts injecting from the second element. You can check it by
writing [].inject(:+)
: it returns nil
as opposed to [].inject(0, :+)
which returns 0.
Edit: I didn't notice the ampersand. You don't need it, inject
will work
with a symbol. But if you do write it, the symbol is converted to block, it
can be useful with [other
methods](https://stackoverflow.com/questions/1217088/what-does-mapname-mean-
in-ruby)