From: "Mauricio Fernández" Date: 2002-08-23T01:45:37+09:00 Subject: Re: Puzzeled by Range object On Thu, Aug 22, 2002 at 05:08:59PM +0900, Peter Hickman wrote: > However you might write come code such as > > (start..10).each {|x| ... } > > I would expect such code to loop from start to 10 for a values of start > <= 10. For values greater than 10 I would not expect the code to run. > > For my code to start 'running backwards' as it were would be very > counter intuative. Then I'll give another name for the new iterator with the other semantic. Plus now "reverse" ranges are processed in order, ie 1..-3 => 1 0 -1 -2 -3 instead of -3 -2 -1 0 1 as before. Note that when doing (A..B).each2, A.succ must be defined if A < B B.succ must be defined if B >= A That's why (1..2.3).each2 and (1.1..-3).each2 both work but not (1.1..3).each2 nor (1..-3.1).each2. A <=> B (or the reverse) must be defined in both cases. batsman@kodos:~/src/rubylang$ cat myrange.rb class Range def each2 if (first <=> last) == -1 # proceed in normal order a = first while (a <=> last) == -1 yield a a = a.succ end yield last unless exclude_end? if (a <=> last) == 0 else # reverse! v = [] a = last a = a.succ if exclude_end? while (a <=> first) == -1 v << a a = a.succ end v << a if (a <=> first) == 0 v.reverse! v.each { |x| yield x } end end end l = [ "(1..3).each2 { |x| print x, ' ' }", "(1..-3).each2 { |x| print x, ' ' }", "(1...3).each2 { |x| print x, ' ' }", "(1...-3).each2 { |x| print x, ' ' }", "(1..3.1).each2 { |x| print x, ' ' }", "(1...3.1).each2 { |x| print x, ' ' }", "(1.1..-3).each2 { |x| print x, ' ' }", "(1.1...-3).each2 { |x| print x, ' ' }", ] l.each { |x| print "Executing #{x}: "; eval x; puts } batsman@kodos:~/src/rubylang$ ruby myrange.rb Executing (1..3).each2 { |x| print x, ' ' }: 1 2 3 Executing (1..-3).each2 { |x| print x, ' ' }: 1 0 -1 -2 -3 Executing (1...3).each2 { |x| print x, ' ' }: 1 2 Executing (1...-3).each2 { |x| print x, ' ' }: 1 0 -1 -2 Executing (1..3.1).each2 { |x| print x, ' ' }: 1 2 3 Executing (1...3.1).each2 { |x| print x, ' ' }: 1 2 3 Executing (1.1..-3).each2 { |x| print x, ' ' }: 1 0 -1 -2 -3 Executing (1.1...-3).each2 { |x| print x, ' ' }: 1 0 -1 -2 batsman@kodos:~/src/rubylang$ -- _ _ | |__ __ _| |_ ___ _ __ ___ __ _ _ __ | '_ \ / _` | __/ __| '_ ` _ \ / _` | '_ \ | |_) | (_| | |_\__ \ | | | | | (_| | | | | |_.__/ \__,_|\__|___/_| |_| |_|\__,_|_| |_| Running Debian GNU/Linux Sid (unstable) batsman dot geo at yahoo dot com People disagree with me. I just ignore them. -- Linus Torvalds, regarding the use of C++ for the Linux kernel