I don't get this conclusion either, so resolve it starting with the innermost expression:
puts 4 # 4 <- this should denote output #=> nil <- this should denote return value
It prints 4 and returns nil ( puts always returns nil ).
Wrap at 3.times { ... } prints 4 3 times:
3.times { puts 4 }
But instead of returning nil it returns 3 . This is because times always returns a receiver (i.e. the integer that you call times ).
Now add another puts :
puts 3.times { puts 4 }
The same as above, but also prints the result 3.times { ... } , i.e. 3 .
A wrapper in just 2.times { ... } duplicates the output above:
2.times { puts 3.times { puts 4 } } # 4 # 4 # 4 # 3 # 4 # 4 # 4 # 3 #=> 2
It also returns 2 instead of nil due to 2.times { ... } .
Adding puts means 2 :
puts 2.times { puts 3.times { puts 4 } }
Wrapping this in 1.times { ... } produces the same output, but changes the result from nil to 1 :
1.times { puts 2.times { puts 3.times { puts 4 } } } # 4 # 4 # 4 # 3 # 4 # 4 # 4 # 3 # 2 #=> 1
Adding the latest puts fingerprints that are 1 :
puts 1.times { puts 2.times { puts 3.times { puts 4 } } }
Stefan
source share