From: Ralph Shnelvar Date: 2012-04-14T06:03:16+09:00 Subject: Re: unable to do "down" range? Roger and Jan, Friday, April 13, 2012, 1:23:54 PM, you wrote: JE> Hi, JE> No, this doesn't work, because 40..10 is an empty range. A range JE> consists of all objects between the left limit and the right limit. JE> We've already discussed this topic here (I cannot find it right now). My JE> personal opinion is that many people are confusing ranges with JE> sequences, because the ".." syntax looks like you're enumerating JE> numbers: 4..10 =>> 4, 5, 6, ..., 10 JE> But a range isn't a sequence. You're not saying "count from ... to ...". JE> The numbers are rather limits of a "static" interval. So there's isn't a JE> real direction implied, the elements are simply put out in the most JE> obvious way: from low to high. JE> I think Integer#downto is what you're looking for: JE> 40.downto 10 do |i| JE> puts i JE> end I have thought about this problem and I think I may make my contribution to the Ruby language an extension that would allow negative ranges as you describe. There are problems, though. How many pieces of code would break if range = 40..10 range.each{|n| puts n} # it doesn't actually did what you want? Probably not many. The documentation in http://www.ruby-doc.org/core-1.9.3/Range.html says each {| i | block } → rng click to toggle source each → an_enumerator Iterates over the elements rng, passing each in turn to the block. You can only iterate if the start object of the range supports the succ method (which means that you can’t iterate over ranges of Float objects). To do what Roger wants, we would need to define a prev function (similar to the succ function) on Fixnums. 3.succ # 4 4,prev # Undefined! Fortunately, this is easy to do in Ruby class Fixnum def prev self - 1 end end 4.prev # 3 So, should we clutter Ruby with a collection of prev functions (because we'd also need to do it for all the things that succ is defined on)? Possibly break existing code? I'd vote yes. There would be at least two advantages to having a well-defined way of dealing with negative ranges beyond the fact that we'd have the relatively minor advantage of having a negative range. As I understand the code right now, (1..10_000_000).last(5) # [9999996, 9999997, 9999998, 9999999, 10000000] will create a temporary array of ten million elements and then peel off the last five array elements. Now from my perspective, having to allocate that relatively huge temporary array is awful; truly Rube Goldberg-esque. Implementing a prev function that would operate on the "end object" (in this instance, 10_000_000) the way that succ works on the "start object" would eliminate the need for that temporary array. If we had that in the implementation of Ruby, then we could get access to the last five elements more-or-less directly. Ralph Shnelvar