Descending ranges in Ruby

Dear list members,

(5..1).to_a #returns []
(1..5).to_a #returns [1,2,3,4,5]
(5..1).each{|x| puts x} #prints (-5..-1)
(1..5).each{|x| puts x} #prints
1
2
3
4
5

I don't get an error message when I declare a descending Range or when I
apply an iterator method to it, but I'm not able to iterate over a
descending Range the same way I can an ascending Range. Can someone
explain what the rationale is behind that language restriction?

Thanks,
Harry

···

--
Posted via http://www.ruby-forum.com/.

5.downto(1) { |i| puts i }
5
4
3
2
1

···

On Thu, Nov 18, 2010 at 9:01 PM, Harry Spier <harryspier@hotmail.com> wrote:

Dear list members,

(5..1).to_a #returns
(1..5).to_a #returns [1,2,3,4,5]
(5..1).each{|x| puts x} #prints (-5..-1)
(1..5).each{|x| puts x} #prints
1
2
3
4
5

I don't get an error message when I declare a descending Range or when I
apply an iterator method to it, but I'm not able to iterate over a
descending Range the same way I can an ascending Range. Can someone
explain what the rationale is behind that language restriction?

Thanks,
Harry

--
Posted via http://www.ruby-forum.com/\.

--
thanks,
-pate
-------------------------
Don't judge those who choose to sin differently than you do

Thanks for this work-around but my question was not so much how to get
around this restriction but rather "why I'm restricted from iterating
over a descending range if descending Ranges are legal?". For example a
Range returned by a function in my program that I may not know whether
it is ascending or descending?

Harry

···

--
Posted via http://www.ruby-forum.com/.

AFAIK, ruby simply considers values like (5..1) as empty range.
Iterating over it has no sense. You can iterate over ascending range in
reverse order using Enumerable#reverse_each method, for example.

···

--
Posted via http://www.ruby-forum.com/.

(1..5).to_a.reverse
=> [5, 4, 3, 2, 1]

-- Maurice

···

On Nov 19, 5:01 am, Harry Spier <harrysp...@hotmail.com> wrote:

Dear list members,

(5..1).to_a #returns
(1..5).to_a #returns [1,2,3,4,5]

IIRC a Range finds the next value via #succ. And Fixnum#succ always
yields the next higher number. If you want to use a Range you must
use a type which reverses #succ and #<=>, example:

irb(main):001:0> RFN = Struct.new :value do
irb(main):002:1* def <=>(o) o.value <=> value end
irb(main):003:1> def succ; self.class.new(value - 1) end
irb(main):004:1> end
=> RFN
irb(main):005:0> (RFN.new(5) .. RFN.new(1)).to_a
=> [#<struct RFN value=5>, #<struct RFN value=4>, #<struct RFN
value=3>, #<struct RFN value=2>, #<struct RFN value=1>]

I'd rather stick with the other approaches presented or use Array#reverse.

Kind regards

robert

···

On Fri, Nov 19, 2010 at 5:49 AM, Harry Spier <harryspier@hotmail.com> wrote:

Thanks for this work-around but my question was not so much how to get
around this restriction but rather "why I'm restricted from iterating
over a descending range if descending Ranges are legal?". For example a
Range returned by a function in my program that I may not know whether
it is ascending or descending?

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/