shift#
Remove and return the first element of an array.
shift mutates its argument: it removes the element at index 0,
shifts every remaining element down by one position, and returns the
removed value. The array shrinks by one. If the array is empty,
nothing is removed and undef is returned.
Synopsis#
shift @arr
shift @$aref
shift # @_ inside a sub, @ARGV outside
What you get back#
The scalar that used to be at index 0, or undef if the array was
empty. Because undef is also a legal array element, a bare undef
return does not by itself mean the array was empty — use
scalar @arr or a prior defined check
when the distinction matters:
my @arr = (undef, 'two');
my $item = shift @arr; # undef — but @arr was not empty
Default array: @ARGV vs @_#
Called without an argument, shift picks its array from the
surrounding context:
Inside a named or anonymous subroutine —
@_. This is the idiomatic way to consume positional arguments one at a time.Outside any sub (including in the file scope of a script, and in
eval STRING,BEGIN,INIT,CHECK,UNITCHECK,ENDblocks) —@ARGV. This is how top-of-script argument consumption is usually written.
The choice is made at compile time based on lexical position, not at
runtime. A shift inside a sub always targets @_ even if the sub
is called from file scope.
Examples#
Consume a single positional argument inside a method. This is the canonical first line of almost every Perl OO method:
sub greet {
my $self = shift;
my $name = shift;
return "hello, $name, from $self";
}
The same method written with a list-unpack @_ slice. Both forms are
idiomatic; shift wins when you want to peel off the invocant
before deciding what to do with the rest of @_:
sub greet {
my ($self, $name) = @_;
return "hello, $name, from $self";
}
Consume @ARGV at the top of a script, one argument at a time:
my $mode = shift // 'default'; # first CLI arg, or 'default'
my $path = shift // die "need a path\n";
# @ARGV now holds whatever is left
A FIFO queue: push on the tail, shift off the head:
my @queue;
push @queue, 'a', 'b', 'c';
while (defined(my $job = shift @queue)) {
handle($job);
}
Dereference an array ref in place — shift works on @$aref exactly
as it does on a named array:
my $aref = [10, 20, 30];
my $head = shift @$aref; # 10, $aref now [20, 30]
Edge cases#
Empty array: returns
undefand leaves the array untouched.shifton an empty array is not an error.Complexity is O(n): every remaining element is moved down by one slot. For large arrays used as queues this adds up. When FIFO ordering is not required,
popis O(1); when it is, consider a deque-style data structure or a pair of stacks rather thanshift-ing a million-element array in a loop.shiftwith no argument is context-sensitive by lexical position: inside a sub it targets@_, outside it targets@ARGV. Moving a line of code between those scopes silently changes which array it mutates.Tied arrays:
shiftcalls theSHIFTmethod on the tied object if one is defined; otherwise it falls back toFETCHon element0, thenDELETE, then a sequence ofFETCH/STOREpairs to shift the remaining elements down, thenSTORESIZE. A customSHIFThandler is almost always worth writing for performance.Array references:
shift @$arefandshift @{ $expr }both work.shift $aref(without the@sigil) was an experimental feature added in Perl 5.14 and removed in 5.24 — it is a syntax error in the Perl version pperl targets.shiftis an lvalue-consumer, not an lvalue: you cannot assign to the result ofshiftto modify the array. Usespliceor direct index assignment for that.Return value in list context:
shiftalways returns a single scalar. Assigning its result to a list —my ($x) = shift @arr— works only because the single scalar fills the first list slot; the remaining slots areundef. Usespliceto remove multiple elements at once.
Differences from upstream#
Fully compatible with upstream Perl 5.42.
See also#
pop— remove and return the last element; O(1), the right choice when FIFO order is not neededpush— append to the tail; pairs withshiftto form a FIFO queueunshift— prepend to the head; the inverse ofshift, and also O(n) for the same reasonsplice— remove, insert, or replace any contiguous run of elements; the general tool whenshift/pop/unshift/pushare not enough@ARGV— the default arrayshiftconsumes at file scope@_— the default arrayshiftconsumes inside a sub; holds the caller’s argument list