Why will a Range not work when descending? [duplicate] Why will a Range not work when descending? [duplicate] ruby ruby

Why will a Range not work when descending? [duplicate]


The easiest way to do that is use downto

5.downto(1) do |i| puts i end


Ranges use <=> to determine if an iteration is over; 5 <=> 1 == 1 (greater-than), so it's done before it starts. Even if they didn't, ranges iterate using succ; 5.succ is 6, still out of luck. A range's step cannot be negative, so that won't work either.

It returns the range because each returns what it was called on. Use downto if it's the functionality itself you're looking for, otherwise the above answers your actual question regarding "why".


You can easily extend the Range class, in particular the each method, to make it compatible with both ascending and descending ranges:

class Range   def each     if self.first < self.last       self.to_s=~(/\.\.\./)  ?  last = self.last-1 : last = self.last       self.first.upto(last)  { |i| yield i}     else       self.to_s=~(/\.\.\./)  ?  last = self.last+1 : last = self.last       self.first.downto(last) { |i|  yield i }     end   endend

Then, the following code will perform just as you'd expect:

(0..10).each  { |i| puts i}(0...10).each { |i| puts i}(10..0).each  { |i| puts i}(10...0).each { |i| puts i}