From: Brian Candler Date: 2004-10-06T19:16:29+09:00 Subject: Re: Range behavior (Re: [RCR] New [] Semantics) On Wed, Oct 06, 2004 at 06:26:25PM +0900, Peter Hickman wrote: > What are you expecting the to_a method to actually do? Return a list of > all the values within the range? Hint: infinite in number. I think Ranges represent at least two different things in Ruby. I will classify these as: (1) Ranges where the lower bound responds to the 'succ' operator -> generates a set of discrete values -> can iterate using 'each' and therefore use Enumerable methods like collect, grep, map, to_a etc. -> member?(x) tests whether x == any of the discrete values (2) Ranges where both bounds respond to the '<=>' operator -> generates an interval -> include?(x) tests whether x lies between the bounds And a Range can behave as both at once, if the bounds satisfy both conditions at once. (1..3.4).each {|s| puts s} # discrete values 1,2,3 (1..3.4).include?(3.3) # interval However, the first of these two examples shows something of an anomoly; the values are generated using 'succ', but the *end* of iteration is still detected using the spaceship operator. So more accurately, the two types of range are: (1) Lower bound responds to 'succ' operator to generate elements; each element responds to '==' to test membership; each element responds to '<=>' to compare to upper bound ---> discrete set of values (2) Lower and upper bounds respond to '<=>' operator ---> interval Now, other uses of ranges have been pointed out: (3) Ranges where the start and end values represent indexes, and negative values are offsets from the end of an object a = [2,3,5,7,11,13] a[2..-2] #=> [5, 7, 11] In this case, a range is IMO just a holder for two values; the Range itself does not have any useful methods apart from Range#first and Range#last (FWIW, these ranges annoy me: firstly because they're not ranges, and secondly because I can never remember the difference between a[2..4] versus a[2,4], and I write a[2,-1] when I should write a[2..-1]. I have to make test cases in irb every time!) (4) I'm sure someone mentioned another use, but I can't remember what it is right now. (The flip-flop operator looks like a range, but I don't think it actually creates a Range object) Regards, Brian.