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. After
delete, exists on the same key or index returns false, keys
no longer lists it, and iterating the hash with 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#
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 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 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.
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 —
deletedispatches to theDELETEmethod 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.$_— unaffected.deletedoes not default to anything;EXPRis mandatory.
Examples#
Remove one key, inspect what was there:
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):
delete @cache{@stale_keys};
Pluck a set of named entries and keep the pairs (5.20+ kv-slice):
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:
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:
delete $h{outer}{inner}; # does not create $h{outer} if absent
Compare with splice when you want indices to renumber. delete
on an array element leaves a hole; splice closes the hole:
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#
deletevs assigningundef:$h{k} = undefleaveskin 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}returnsundef. That’s indistinguishable from deleting a key whose value wasundef; useexistsfirst if the distinction matters.each+deleteinside the loop: safe when you delete only the current key (the key just returned byeach). 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: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,
$#arraydrops to the highest index still testing true underexists. Holes in the middle stay as holes.deleteon an array is discouraged: the concept of “missing index” is not coherent for arrays — indices are positional, not named. Leave array shrinkage toshift,pop, orsplice.WARNINGin upstream POD restated: reach for an arraydeleteonly 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:{ 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:
deletecallsDELETE; the return value is whatever the tie implementation supplies. A tied DBM hash deletes the entry on disk.Readonly target:
deleteon a readonly element croaks withModification of a read-only value attempted.The expression must end in an element or slice:
delete $h{k} + 1is a compile-time error;deletehas 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— the query counterpart; use it beforedeletewhen you need to tell “was never there” apart from “was there with valueundef”each— hash iterator; safe to combine withdeleteonly when you delete the current keykeys— snapshot of hash keys; the usual way to build a deletion list that won’t interact with iterator statevalues— companion tokeyswhen you want the deleted-value set without the keyssplice— the right tool when you want to remove array elements and renumber remaining indicesundef— 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