Hi,

In message "Re: Range.first is incompatible with Enumerable.first"
    on Tue, 16 Oct 2007 15:47:34 +0900, David Flanagan <david / davidflanagan.com> writes:

|The new Enumerable.first method is a generalization of Array.first to 
|work on any Enumerable object.  But it behaves differently than 
|Range.first.  There are two incompatibilities:
|
|1) Range.first cannot accept an argument for the number of elements to 
|return.
|
|2) Range.first always returns Range.begin, even if the range is empty. 
|That it, it is not consistent with Range.each.  The Range 1..0 has no 
|elements according to each, but Range.first returns 1.

Indeed.

|I just got caught by this incompatability when trying to test 
|Enumerable.first(n) using a Range object as the Enumerable I was testing 
|on.
|
|I suggest that Range.first be removed, allowing Range objects to use the 
|more general (and more correct) Enumerable.first method.  The existing 
|behavior is retained in Range.begin, of course.
|
|If that is too radical a change, I suggest that Range.first be extended 
|to accept an integer argument.  And in that case, it should delegate to 
|Enumerable.first. That is, even if (1..0).first continues to return 1, 
|(1..0).first(1) should correctly return [].

I'd take this option, plus Range#last to work like range.to_a.last(n)
if argument is given.  The left issue is whether Range#begin (and
correspondent #end) should behave like first.

							matz.