[Oops, first copy accidently got sent to Brian instead of list. Sorry.]

On 10/9/2004 6:52 AM, Brian Candler wrote:
> On Sat, Oct 09, 2004 at 07:30:09PM +0900, Randy W. Sims wrote:
> 
>>Ahh, ok. I didn't realize set
> 
> 
> Range
> 
> 
>>was implemented in this way. I can see why 
>>you did it: it allows ranges for all types of objects. Very nice.
> 
> 
> Range#include? just uses the <=> operator to test for the bottom and top of
> the range (in other words, it's intended for objects which are Comparable
> rather than Enumberable)
> 
> 
>>Even with this, It would still be nice if membership could be tested... 
>>efficiently. Or at least efficient for the common cases. Range could be 
>>special cased for Integers so that a member could be found by 
>>calculating elements for a "binary search" (if (((end - start) / 2) > 
>>target))...
> 
> 
> You can't do a binary search over an Enumberable, because it just gives you
> the elements one at a time in order; it doesn't support "fetch Nth item".
> You'd have to first enumerate everything into an Array, which brings you
> back to the current situation anyway.

For some types it is possible to calculate whether a value exist within
a range without the need of iterating through the whole range with
#succ. Integer, Date, and possibly String could all offer the ability to
test if a member is in range by performing a quick calculation. Other
types would have to defer to the #succ method. Types that can provide
efficient membership test would all support an interface, a
#test_in_range(start, end, target) class method, that #member? could query.

> Also, if you really want that sort of membership test with integers, then
> there's no need for a binary search anyway:
> 
>      myrange.include?(x) and x.to_i == x
> 
> ISTM that in Ruby, a range is *primarily* a continuous range with lower and
> upper bounds. If the lower bound happens to be an object which responds to
> 'succ' to generate the next object in a sequence, and <=> to match the upper
> bound, then magically it also becomes Enumerable.

I guess it's not really that big of a deal to me. It just seems a little
inconsistent. Sometimes a Range seems continuous (#include?) and other
times not ((1..5).each {|i| puts i}). I was just trying to think of a
way to make it more consistent without a major speed penalty.

Randy.