Ed de Almeida Ed de Almeida - 10 days ago 7
Ruby Question

Ruby #inject behavior is different from documentation

Taking a look at Ruby documentation on

class I noticed something interesting and I'd like to know why it happens this way.

At
#inject
description
I've found these examples:

# Sum some numbers
(5..10).reduce(:+) #=> 45
# Same using a block and inject
(5..10).inject { |sum, n| sum + n } #=> 45
# Multiply some numbers
(5..10).reduce(1, :*) #=> 151200
# Same using a block
(5..10).inject(1) { |product, n| product * n } #=> 151200


Notice that when
#inject
is used for multiplication, it receives an initial value of 1. I thought this was necessary because otherwise product would receive 0 as start value (as it happens in the sum) and the multiplication would also be 0. In fact, if I run

p (1..5).inject(0) { |prod, n| prod * n }


I got

0


But then I run

p (1..5).inject { |sum, n| sum + n }
p (1..5).inject { |prod, n| prod * n }


and got

15
120


My questions are:

a) Why the documentation includes this 1 as initial value when, in fact, it is not needed?

and

b) What is the behavior of
#inject
when it comes to initializing the object being injected?

Answer

To answer your first question:

a) Why the documentation includes this 1 as initial value when, in fact, it is not needed?

inject does not take 1 as initial value, from the apidock:

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.

Answer of second question lies in the answer of first itself, as it initialises the object as the first element of array on which inject is being applied.