Looping differences in Ruby using Range vs. Times Looping differences in Ruby using Range vs. Times ruby ruby

Looping differences in Ruby using Range vs. Times


This information can be easily obtained by inspecting the documentation.

Array#each has a signature of array.each {|item| block } → array, so we can see that the return value of foo.each { ... } is foo.

Likewise, Int#upto has a signature of int.upto(limit) {|i| block } => int, so that x.upto(y) { ... } will always return x.

Then we can also see that 2.times { ... } will return 2 because of Integer#times's signature.

I'm having trouble finding the right documentation, but for x in y... gets translated to y.each do |x| ..., so that's why your for-in loop returns the same thing as your .each loop.

Anyway, depending on the return values of these looping constructs is... a strange approach. I don't think this happens much (at all?) in idiomatic Ruby code.


If I understood you correctly, you're asking why n.times is the only method which iterates upto, but not including n. In that case:

For ranges it's simple: x..y defines a range from x to y inclusive and x...y defines a range from x to y exclusive. So if you want the same behavior as times use 0...n.

For x.upto(y) there is only one version which will iterate upto and including y. This is simply how upto is defined and documented to work.

It is also quite clear why n.times does not include n: if it iterated from 0 to n (inclusive), it would yield n+1 times. But since the method is called n.times it should clearly only yield n times.