Question

I know the arguments for inject() between the parentheses are optional, so what happens when you leave them out? For example:

    [2, 4, 6, 8].inject{ |x, y|
      puts "x: #{x}   y: #{y}"
    }

outputs the following:

x: 2   y: 4 
x:     y: 6
x:     y: 8

Why does x start at 2? Shouldn't it start at nil? And why are there only 3 lines of output instead of 4?

Mainly: What does it do differently when it's given no arguments?

Was it helpful?

Solution

so what happens when you leave them out?

Then in the first pass, x, y will be set to the first 2 values from your collection. From the next pass onwards, x will be set to the value returned by the block, and y by the next element from the collection.

In your case in first pass x and y is set to as 2 and 4 respectively.

From the next pass onwards, x is set nil, as last statement in your block is Kernel#puts, which returns nil after printing the arguments you passed to it. But y is 6, then 8.

#inject

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

All is very expected as per the code.


Now suppose, you passed the initial value as - 11, then output will be :-

x: 11   y: 2
x:     y: 4
x:     y: 6
x:     y: 8

Explanation is same here -

In this case in first pass x and y is set to as 11 and 2 respectively.

From the next pass onwards, x is set nil, as last statement in your block is Kernel#puts, which returns nil after printing the arguments you passed to it. But y is 4, then 6 then 8.

NOTE : After x:, when you are seeing nothing. Why ? As nil.to_s is empty string, i.e. "".

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top