--- name: delete signature: 'delete EXPR' signatures: - 'delete $hash{KEY}' - 'delete @hash{LIST}' - 'delete %hash{LIST}' - 'delete $array[INDEX]' - 'delete @array[LIST]' - 'delete local EXPR' since: 5.0 status: documented categories: ["Hashes"] --- ```{index} single: delete; Perl built-in ``` *[Hashes](../perlfunc-by-category)* # delete Remove the named key-value pair(s) from a hash, or element(s) from an array, and return what was removed. `delete` reaches into an aggregate and removes the specified entries outright — not just by setting them to [`undef`](undef). After `delete`, [`exists`](exists) on the same key or index returns false, [`keys`](keys) no longer lists it, and iterating the hash with [`each`](each) skips it. The argument must be an element or slice of a hash or array; its final operation selects what to remove, and anything leading up to that operation (dereferences, method calls) is just navigation. ## Synopsis ```perl delete $hash{KEY} # scalar key delete @hash{LIST} # hash slice: values of the listed keys delete %hash{LIST} # key/value hash slice (5.20+) delete $array[INDEX] # array element delete @array[LIST] # array slice ``` ## What you get back In list context, `delete` returns the value or values removed, in argument order. A slice argument whose key or index did not exist yields [`undef`](undef) at the matching position, so the length of the returned list matches the length of the key/index list. In scalar context, `delete` returns the value of the last element removed, or [`undef`](undef) if the key/index was not present. The 5.20+ key/value hash-slice form `delete %hash{LIST}` returns a list of alternating key/value pairs — two elements for every deleted entry — which makes it the idiomatic way to pluck a named set of entries and keep both sides. ```perl my %h = (foo => 11, bar => 22, baz => 33); my $v = delete $h{foo}; # 11 my @v = delete @h{qw(bar quux)}; # (22, undef) my %kv = delete %h{qw(baz quux)}; # (baz => 33, quux => undef) ``` ## Global state it touches - **`%ENV`** — `delete $ENV{VAR}` unsets the environment variable for the current process and its future children. The effect is real, not just the Perl-side hash; system calls see the change. - **tied aggregates** — `delete` dispatches to the `DELETE` method of the tying package. The return value is whatever the implementation chooses to hand back; some tied hashes return the deleted value, some do not. - **[`$_`](../perlvar)** — unaffected. `delete` does not default to anything; `EXPR` is mandatory. ## Examples Remove one key, inspect what was there: ```perl my %cfg = (host => "db1", port => 5432, user => "alice"); my $old_host = delete $cfg{host}; # $old_host is "db1"; exists $cfg{host} is false ``` Free memory by removing many entries in one call (hash slice): ```perl delete @cache{@stale_keys}; ``` Pluck a set of named entries and keep the pairs (5.20+ kv-slice): ```perl my %h = (a => 1, b => 2, c => 3); my %taken = delete %h{qw(a c)}; # %taken is (a => 1, c => 3); %h is (b => 2) ``` Delete through a nested structure. Leading navigation can be arbitrary — only the final operation decides what gets removed: ```perl my $tree = { users => { alice => { roles => [qw(admin ro)] } } }; delete $tree->{users}{alice}{roles}[0]; # roles is now (undef, "ro") delete $tree->{users}{alice}; # the whole user record is gone ``` Avoid autovivification on the read side while still removing on the write side. `delete` never vivifies the intermediate hashes it walks through: ```perl delete $h{outer}{inner}; # does not create $h{outer} if absent ``` Compare with [`splice`](splice) when you want indices to renumber. `delete` on an array element leaves a hole; [`splice`](splice) closes the hole: ```perl my @a = (10, 20, 30, 40); delete $a[1]; # @a is (10, undef, 30, 40); $#a is still 3 my @b = (10, 20, 30, 40); splice(@b, 1, 1); # @b is (10, 30, 40); $#b is 2 ``` ## Edge cases - **`delete` vs assigning [`undef`](undef)**: `$h{k} = undef` leaves `k` in the hash with an undefined value; `exists $h{k}` is still true. `delete $h{k}` removes the key entirely. - **Missing key in scalar context**: `delete $h{nope}` returns [`undef`](undef). That's indistinguishable from deleting a key whose value was [`undef`](undef); use [`exists`](exists) first if the distinction matters. - **[`each`](each) + `delete` inside the loop**: safe when you delete only the current key (the key just returned by [`each`](each)). Deleting *other* keys during iteration can skip entries or revisit them — Perl's hash iterator is not stable across structural change. The safe rewrite is to collect keys first: ```perl for my $k (grep { $h{$_} < 0 } keys %h) { delete $h{$k}; } ``` - **Trailing array deletions shrink the array**: if the deleted elements are at the top end, `$#array` drops to the highest index still testing true under [`exists`](exists). Holes in the middle stay as holes. - **`delete` on an array is discouraged**: the concept of "missing index" is not coherent for arrays — indices are positional, not named. Leave array shrinkage to [`shift`](shift), [`pop`](pop), or [`splice`](splice). `WARNING` in upstream POD restated: reach for an array `delete` only when you know you want a hole. - **`delete local $h{k}`**: removes the entry for the enclosing block and reinstates it on scope exit. Useful for temporarily hiding configuration keys from code called inside the block without losing the original value: ```perl { local $ENV{LANG}; # still present, but undef delete local $ENV{PATH}; # gone for this block only run_thing(); } # both restored to original values here ``` - **Tied hash, tied array**: `delete` calls `DELETE`; the return value is whatever the tie implementation supplies. A tied DBM hash deletes the entry on disk. - **Readonly target**: `delete` on a readonly element croaks with `Modification of a read-only value attempted`. - **The expression must end in an element or slice**: `delete $h{k} + 1` is a compile-time error; `delete` has lower precedence than arithmetic and expects an lvalue-ish aggregate lookup, not a computed value. ## Differences from upstream Fully compatible with upstream Perl 5.42. ## See also - [`exists`](exists) — the query counterpart; use it before `delete` when you need to tell "was never there" apart from "was there with value [`undef`](undef)" - [`each`](each) — hash iterator; safe to combine with `delete` only when you delete the current key - [`keys`](keys) — snapshot of hash keys; the usual way to build a deletion list that won't interact with iterator state - [`values`](values) — companion to [`keys`](keys) when you want the deleted-value set without the keys - [`splice`](splice) — the right tool when you want to remove array elements *and* renumber remaining indices - [`undef`](undef) — clears a whole aggregate (`undef %h`, `undef @a`) or a single scalar; the customary way to empty a hash or array wholesale rather than deleting every key