What do you mean by "inconsistent"? The optional argument to "first" and "last" means number of items requested, not offset. For example, the second value for "ary[pos,len]" does not accept negative value.
-- matz.
I agree with matz. A negative parameter only makes sense when you are asking for an offset. When you are asking for the number of items to return, a negative number doesn't really apply.
-- Jamis
I think there shouldn't be a distinction between indices and lengths in this case -- I think #first and #last should really use Range fetches instead which would avoid also having to accept arr[1, -5]. (which doesn't seem to make sense to me)
I think it makes sense to think about the argument as an amount of values you're asking for which can be relative to the total amount of values available.
-- flgr
I couldn't see any reason for your "should". Can you show us why do you think they should be no distinction? I feel offsets and number of items are different, even though they are related (e.g. 0 .. number of items = range for those items). When I describe the "first(n)" method, it should be: "retrieve first n items from the array"; not "retrive items from offset zero to offset n (including n)", which makes me somewhat confusing.
- matz.
I think I see what you're getting at -- so this is about not exposing features of underlying implementations, because the underlying implementation might change and make it harder to make those features available?
I still think this would a nice compromise between another pair of methods and not having the features they would offer at all without introducing any icky flags and the like, but I think I can understand if you choose to reject this because of the above reason. (Though it would be a bit sad.)
-- flgr
When I request n items from an array, I think and I expect, n must be a natural number (non zero, positive integer). Respecting *my* expectation is the key of Ruby's design. If you want to persuade me, you have to give me rationale better than "compromise". How often do you want to retrieve "items but last n"? If you want often, it's good to have another pair of methods. If you want rarely, ary[0..-n] would be suffice.
-- matz.
I have found myself trying to use items.first(-1) multiple times, simply assuming that it would work, and feeling quite satisfied that Ruby allowed me to express the idea so succinclty. Except it didn't, and I was disappointed. To me, it seems prefectly reasonable to expect that since items[-1] selects the last item, items.first(-1) should select everything up to the last item.
Matz, you argue that this change would make it more difficult to explain exactly what the #first method does. That's certainly true, but isn't that a pretty small price to pay? After all, it still wouldn't be particularly hard: ``It selects the first item of the array. To select multiple initial items, give an integer argument. To count from the end, give a negative argument, just like with Array#[].''
Certainly, it is not immediately obvious what items.first(-1) means. However, that is equally true for items[-1], and I really think that if one works, then both should. It just seems like the natural thing to expect. And I definitely think that they should --- it's a really great notation.
Voted strongly in favor.
-- Daniel Brockman
What do you mean by "inconsistent"? The optional argument to "first" and "last" means number of items requested, not offset. For example, the second value for "ary[pos,len]" does not accept negative value.
-- matz.
I agree with matz. A negative parameter only makes sense when you are asking for an offset. When you are asking for the number of items to return, a negative number doesn't really apply.
-- Jamis
I think there shouldn't be a distinction between indices and lengths in this case -- I think #first and #last should really use Range fetches instead which would avoid also having to accept arr[1, -5]. (which doesn't seem to make sense to me)
I think it makes sense to think about the argument as an amount of values you're asking for which can be relative to the total amount of values available.
-- flgr
I couldn't see any reason for your "should". Can you show us why do you think they should be no distinction? I feel offsets and number of items are different, even though they are related (e.g. 0 .. number of items = range for those items). When I describe the "first(n)" method, it should be: "retrieve first n items from the array"; not "retrive items from offset zero to offset n (including n)", which makes me somewhat confusing.
- matz.
I think I see what you're getting at -- so this is about not exposing features of underlying implementations, because the underlying implementation might change and make it harder to make those features available?
I still think this would a nice compromise between another pair of methods and not having the features they would offer at all without introducing any icky flags and the like, but I think I can understand if you choose to reject this because of the above reason. (Though it would be a bit sad.)
-- flgr
When I request n items from an array, I think and I expect, n must be a natural number (non zero, positive integer). Respecting *my* expectation is the key of Ruby's design. If you want to persuade me, you have to give me rationale better than "compromise". How often do you want to retrieve "items but last n"? If you want often, it's good to have another pair of methods. If you want rarely, ary[0..-n] would be suffice.
-- matz.
I have found myself trying to use items.first(-1) multiple times, simply assuming that it would work, and feeling quite satisfied that Ruby allowed me to express the idea so succinclty. Except it didn't, and I was disappointed. To me, it seems prefectly reasonable to expect that since items[-1] selects the last item, items.first(-1) should select everything up to the last item.
Matz, you argue that this change would make it more difficult to explain exactly what the #first method does. That's certainly true, but isn't that a pretty small price to pay? After all, it still wouldn't be particularly hard: ``It selects the first item of the array. To select multiple initial items, give an integer argument. To count from the end, give a negative argument, just like with Array#[].''
Certainly, it is not immediately obvious what items.first(-1) means. However, that is equally true for items[-1], and I really think that if one works, then both should. It just seems like the natural thing to expect. And I definitely think that they should --- it's a really great notation.
Voted strongly in favor.
-- Daniel Brockman