This and other RFCs are available on the web at
http://dev.perl.org/rfc/
=head1 TITLE
Optional 2nd argument to pop() and shift()
=head1 VERSION
Maintainer: Jonathan Scott Duff <[EMAIL PROTECTED]>
Date: 7 Aug 2000
Version: 1
Mailing List: [EMAIL PROTECTED]
Number: 56
=head1 ABSTRACT
The inverse operations to C<pop()> and C<shift()> both accept a LIST to
"add" to an array, yet C<pop()> and C<shift()> only remove B<one> element
from an array. In the interest of symmetry and TMTOWTDI, C<pop()> and
C<shift> should allow the programmer to remove multiple items from an
array.
=head1 DESCRIPTION
The intent should be obvious, but I'll point it out anyway.
=head2 pop
The documentation for Perl 5.6.0 states that pop has one of two forms:
C<pop ARRAY>, or just C<pop>. This RFC proposes that a third form be
added to C<pop()>
=over 4
=item pop ARRAY, EXPR
EXPR would be evaluated to determine the number of elements to remove
from the end of ARRAY and that number would be removed and returned.
Thus C<pop()> would be a more natural inverse to C<push()> (If you can
add multiple elements to an array with C<push()>, why can't you remove
multiple elements from an array with C<pop>?)
=back
This functionality can currently be accomplished with C<splice()>, but
it is non-obvious that C<splice()> should be the routine to call and
the method isn't at all intuitive. To "pop" the last $N items off of
the end of an array using C<splice()>, the call looks like this:
splice @array, -$N; # remove the last $N items
contrast to the more natural looking
pop @array, $N; # remove the last $N items
=head2 shift
The semantics for C<shift()> are similar to C<pop()> except that it
operates on the other end of the array. C<shift()> also suffers from
the inability to shift more than one element from the array. Just
like C<pop()>, the two forms of C<shift()> are a C<shift ARRAY>, and
just plain C<shift>. This RFC proposes that a third form be added:
=over 4
=item shift ARRAY, EXPR
EXPR would be evaluated to determine the number of elements to remove
from the beginning of ARRAY and that number would be removed and returned.
Thus, C<shift()> would be a more natural inverse to C<unshift>. (If
you can add multiple elements to an array with C<unshift()>, why can't
you remove multiple elements with C<shift()>?)
=back
As with C<pop()> the proposed semantics can be accomplished with
C<splice()> and are just as un-intuitive:
splice @array, 0, $N; # remove the first $N elements
contrast to
shift @array, $N; # remove the first $N elements
=head2 Random examples
@numbers = 1..10;
$ten = pop @numbers; # still works
@popped = pop @numbers, 3; # Take away 7, 8, 9
push @numbers, @popped; # Put 'em back
@popped = pop @numbers, 0; # Nothing happens
@popped = pop @numbers, 9; # And then there were none.
@numbers = 1..10;
@popped = pop @numbers, 100; # And then there were none but
# @popped only has 10 things
@numbers = 1..10;
$one = shift @numbers; # still works
@shifted = shift @numbers, 3; # Take away 2, 3, and 4
unshift @numbers, @shifted; # Put 'em back
@shifted = shift @numbers, 0; # Nothing happens
@shifted = shift @numbers, 9; # And then there were none.
@numbers = 1..10;
@shifted = shift @numbers, 100; # And then there were none but
# @shifted only has 10 things
=head1 IMPLEMENTATION
I don't know the gory details other than it should be possible.
However, there is one implementation detail that occurs to me:
What should happen when the expression given to C<pop()>, or
C<shift()> evaluates to a negative number? I see three options:
1) Nothing. We can only pop/shift positive amounts
2) Act as if the number were positive (i.e. abs(EXPR))
3) C<pop()> would then act as C<shift()> and C<shift()> would
act as C<pop()>
The author of this RFC sees arguments for all three.
=head1 REFERENCES
The Perl 5.6.0 documentation
L<perlfunc/pop>
L<perlfunc/shift>
L<perlfunc/splice>