From: David Alan Black Date: 2001-01-08T06:59:43+09:00 Subject: [ruby-talk:8788] Re: Backward Range implementation Hello -- On Sun, 7 Jan 2001, Kevin Smith wrote: > > Here's what I came up with that seems to work. I > didn't exhaustively test all the methods of > Range, but I think I probably hit the ones that > weren't working. Oh, I don't expect backward > ranges to support exclusive mode (it seems > unbalanced), so I didn't test that. > > Gotta love this language! > > Kevin > > ========================== > class Range > alias old_each each > def each(&block) > if (first > last) > first.downto(last) { |element| yield element} > return self > end > return old_each(&block) > end > > alias old_equal === > def ===(obj) > if (first > last) > return (last..first).old_equal(obj) > end > return old_equal(obj) > end > end Using yours as a starting point, I tried to generalize it so that it would work on strings as well as numbers. I've resorted (so far) to turning the range into an array. (Which requires a bit of sleight of hand, because Range#to_a seems to use Range#each, so one has to sidestep the infinite recursion.) I also factored it out a bit, just to reveal (to my own thick self) exactly what was needed/involved. And, like your version, this one does not do anything about '...'. Anyway..... class Range alias old_each each alias old_equal === def downward first > last end def reverse last .. first end def ascending if downward reverse else self end end def each(&block) arr = [] ascending.old_each do |e| arr.push e end arr.reverse! if downward arr.each &block return self end def ===(obj) ascending.old_equal(obj) end def show puts to_a.join ', ' end end m = (5..0) n = ('d' .. 'a') m.show n.show __END__ Further thoughts/hacks/enhancements/whatever? David -- David Alan Black home: dblack@candle.superlink.net work: blackdav@shu.edu Web: http://pirate.shu.edu/~blackdav