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 Cpop() and Cshift() both accept a LIST to
"add" to an array, yet Cpop() and Cshift() only remove Bone element
from an array. In the interest of symmetry and TMTOWTDI, Cpop() and
Cshift 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:
Cpop ARRAY, or just Cpop. This RFC proposes that a third form be
added to Cpop()
=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 Cpop() would be a more natural inverse to Cpush() (If you can
add multiple elements to an array with Cpush(), why can't you remove
multiple elements from an array with Cpop?)
=back
This functionality can currently be accomplished with Csplice(), but
it is non-obvious that Csplice() 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 Csplice(), 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 Cshift() are similar to Cpop() except that it
operates on the other end of the array. Cshift() also suffers from
the inability to shift more than one element from the array. Just
like Cpop(), the two forms of Cshift() are a Cshift ARRAY, and
just plain Cshift. 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, Cshift() would be a more natural inverse to Cunshift. (If
you can add multiple elements to an array with Cunshift(), why can't
you remove multiple elements with Cshift()?)
=back
As with Cpop() the proposed semantics can be accomplished with
Csplice() 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 Cpop(), or
Cshift() 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) Cpop() would then act as Cshift() and Cshift() would
act as Cpop()
The author of this RFC sees arguments for all three.
=head1 REFERENCES
The Perl 5.6.0 documentation
Lperlfunc/pop
Lperlfunc/shift
Lperlfunc/splice