--- name: shift signature: 'shift ARRAY' since: 5.0 status: documented categories: ["Arrays"] --- ```{index} single: shift; Perl built-in ``` *[Arrays](../perlfunc-by-category)* # 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`](undef) is returned. ## Synopsis ```perl 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`](undef) if the array was empty. Because [`undef`](undef) is also a legal array element, a bare [`undef`](undef) return does not by itself mean the array was empty — use [`scalar @arr`](../perldata) or a prior [`defined`](defined) check when the distinction matters: ```perl 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`, `END` blocks) — **`@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: ```perl 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 `@_`: ```perl sub greet { my ($self, $name) = @_; return "hello, $name, from $self"; } ``` Consume `@ARGV` at the top of a script, one argument at a time: ```perl 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`](push) on the tail, `shift` off the head: ```perl 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: ```perl my $aref = [10, 20, 30]; my $head = shift @$aref; # 10, $aref now [20, 30] ``` ## Edge cases - **Empty array**: returns [`undef`](undef) and leaves the array untouched. `shift` on 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, [`pop`](pop) is O(1); when it is, consider a deque-style data structure or a pair of stacks rather than `shift`-ing a million-element array in a loop. - **`shift` with 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**: `shift` calls the `SHIFT` method on the tied object if one is defined; otherwise it falls back to `FETCH` on element `0`, then `DELETE`, then a sequence of `FETCH`/`STORE` pairs to shift the remaining elements down, then `STORESIZE`. A custom `SHIFT` handler is almost always worth writing for performance. - **Array references**: `shift @$aref` and `shift @{ $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. - **`shift` is an lvalue-consumer, not an lvalue**: you cannot assign to the result of `shift` to modify the array. Use [`splice`](splice) or direct index assignment for that. - **Return value in list context**: `shift` always 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 are [`undef`](undef). Use [`splice`](splice) to remove multiple elements at once. ## Differences from upstream Fully compatible with upstream Perl 5.42. ## See also - [`pop`](pop) — remove and return the **last** element; O(1), the right choice when FIFO order is not needed - [`push`](push) — append to the tail; pairs with `shift` to form a FIFO queue - [`unshift`](unshift) — prepend to the head; the inverse of `shift`, and also O(n) for the same reason - [`splice`](splice) — remove, insert, or replace any contiguous run of elements; the general tool when `shift` / [`pop`](pop) / [`unshift`](unshift) / [`push`](push) are not enough - [`@ARGV`](../perlvar) — the default array `shift` consumes at file scope - [`@_`](../perlvar) — the default array `shift` consumes inside a sub; holds the caller's argument list