Just add one line p acc
to debug it.
(arup~>~)$ pry --simple-prompt
>> module Enumerable
| def injecting(*acc, &block)
| acc = acc.empty? ? self.shift : acc.first
| p acc
| self.each do |x|
| acc = block.call(acc, x)
| end
| acc
| end
| end
=> nil
>> [1,2,3].injecting { |a,x| a + x }
1
=> 6
>>
When you called the method injecting
on the array [1,2,3]
, as acc
was empty, sef.shift
gets invoked. Now acc
is 1
. Now self
has only [2,3]
. so the call self.each..
first pass 2
, and then block gets invoked and the result of a = x
is assigned to acc
, whis now holds 3
. So now on the next iteration, from self
next value passed(3
), and block gets called again, and perform a + x
again, so now value of acc
is 6
. So you got the result 6
.
A one level more debugging :
(arup~>~)$ pry --simple-prompt
>> module Enumerable
| def injecting(*acc, &block)
| acc = acc.empty? ? self.shift : acc.first
| p "acc now holds #{acc}"
| p "elements in self is #{self}"
| self.each do |x|
| acc = block.call(acc, x)
| p "current value of acc is #{acc}"
| end
| acc
| end
| end
=> nil
>> [1,2,3].injecting { |a,x| a + x }
"acc now holds 1"
"elements in self is [2, 3]"
"current value of acc is 3"
"current value of acc is 6"
=> 6
>>
Am I safe assuming that by calling first, is still returning the 1st item but starts the iteration from that item, hence why I would get 7?
Again I would suggest you to add some debugging messages, to see what's going go under-hood. Look below :
(arup~>~)$ pry --simple-prompt
>> module Enumerable
| def injecting(*acc, &block)
| acc = acc.empty? ? self.first : acc.first
| p "acc now holds #{acc}"
| p "elements in self is #{self}"
| self.each do |x|
| acc = block.call(acc, x)
| p "current value of acc is #{acc}"
| end
| acc
| end
| end
=> nil
>> [1,2,3].injecting { |a,x| a + x }
"acc now holds 1"
"elements in self is [1, 2, 3]"
"current value of acc is 2"
"current value of acc is 4"
"current value of acc is 7"
=> 7
>>
self.first
just returns the first element, which is 1
, and get assigned to acc
. But self didn't get modified. But in case of self.shift
, that 1
was assigned to acc
and at the sane time got removed from self
, and then self
has [2,3]
.
Now in this part, self.each..
code passes 3 values of self
, which are 1
,2
and 3
. Now the summation is 6
, and added with 1
, which is the first acc
value, when self.first
got called. This is how the final result of acc
is 7
.