I tried to iterate backwards with using a Range and each
:
(4..0).each do |i|
puts i
end
==> 4..0
Iteration through 0..4
writes the numbers. On the other Range r = 4..0
seems to be ok, r.first == 4
, r.last == 0
.
It seems to be strange to me that the construct above does not produce the expected result. What is the a reason for that? What are the situations when this behaviour is reasonable?
A range is just that: something defined by its start and end, not by its contents. "Iterating" over a range doesn't really make sense in a general case. Consider, for example, how you would "iterate" over the range produced by two dates. Would you iterate by day? by month? by year? by week? It's not well-defined. IMO, the fact that it's allowed for forward ranges should be viewed as a convenience method only.
If you want to iterate backwards over a range like that, you can always use downto
:
$ r = 10..6
=> 10..6
$ (r.first).downto(r.last).each { |i| puts i }
10
9
8
7
6
Here are some more thoughts from others on why it's tough to both allow iteration and consistently deal with reverse-ranges.