each#
Step through a hash or array one entry at a time.
each advances a per-container iterator and hands back the next
entry. For a hash that entry is a (key, value) pair; for an array
it is an (index, value) pair. When the iterator has walked every
entry, the next call returns the empty list (or undef in scalar
context) and then rewinds, so a fresh while (each ...) loop starts
from the beginning. Hash order is randomised per process and per
hash; array order is strictly lowest index first.
Synopsis#
while (my ($k, $v) = each %h) { ... }
while (my ($i, $v) = each @a) { ... }
while (each %h) { ... } # sets $_ to the key
my $k = each %h; # scalar context: key/index only
What you get back#
List context: a two-element list
($key, $value)for a hash,($index, $value)for an array. On exhaustion, the empty list.Scalar context: the key (for a hash) or the index (for an array). On exhaustion,
undef.Bare
each %hin awhile/forcondition: tests definedness of the returned key/index, not truth, and assigns the key to$_. This is what makeswhile (each %h) { print "$_\n" }work even when a key is the empty string or0.
After exhaustion the iterator is implicitly reset, so the call after the one that returned empty restarts iteration from the top.
Global state it touches#
Every hash and every array carries its own internal iterator.
each, keys, and values all advance and share
that one iterator — they are three views of the same cursor, not
three independent loops. This is the single most important fact
about each:
Calling
keys %horvalues %h(in any context, even as a one-off count likescalar keys %h) resets the hash’s iterator. Awhile (each %h)loop interrupted byscalar keys %hin the body will restart from the top on the next iteration — or worse, loop forever.Referencing a hash in list context resets its iterator too (e.g.
my @copy = %h, or passing%hto a sub). Array iterators are not reset by list-context reference.Two loops iterating the same
%hshare one cursor. Nestingwhile (each %h) { ... while (each %h) { ... } ... }visits each entry at most once total, notn * mtimes.An anonymous hash/array in the condition (
each %{ +{ a => 1 } }) builds a new container every iteration, so the iterator is always fresh — the loop never terminates.The bare-
eachform assigns to$_; if you rely on$_elsewhere in the loop body, save it withlocal.
Every entry to a while (each ...) loop picks up whatever iterator
position the container happens to be at. There is no way to isolate
a loop’s iterator from other code that touches the same container.
If the loop body calls a function that might read the same hash, the
safe pattern is a foreach loop over keys instead.
Examples#
Basic hash iteration:
my %colour = (red => "#f00", green => "#0f0", blue => "#00f");
while (my ($name, $hex) = each %colour) {
print "$name = $hex\n";
}
# order is unspecified
Array iteration (Perl 5.12+):
my @letters = ('a' .. 'e');
while (my ($i, $c) = each @letters) {
print "[$i] $c\n";
}
# [0] a
# [1] b
# [2] c
# [3] d
# [4] e
Printing a hash in sorted order — each does not sort, so reach
for keys plus sort instead:
for my $k (sort keys %colour) {
print "$k = $colour{$k}\n";
}
Bare each in a while condition, which sets $_ to the key every
iteration (Perl 5.18+):
while (each %ENV) {
print "$_=$ENV{$_}\n";
}
Safe deletion during iteration — you may delete the key just
returned by each without disturbing the cursor:
while (my ($key, $value) = each %hash) {
delete $hash{$key} if $value < 0; # safe
}
Iterating a hash with a foreach loop when anything in the body
might touch %hash (the robust pattern — snapshot the keys first):
for my $key (keys %hash) {
my $value = $hash{$key};
# body is free to read %hash, call subs that read it, even
# mutate it cautiously — our iteration list is fixed already.
}
Multi-value foreach over a hash (Perl 5.36+), which makes each
unnecessary for most loops and sidesteps the shared-iterator trap:
foreach my ($key, $value) (%hash) {
print "$key => $value\n";
}
Edge cases#
Iterator not reset between re-entries: a
while (each %h)loop that exits early vialast,return, ordieleaves the iterator mid-walk. The nextwhile (each %h)on the same hash picks up where the first left off, not at the start. Callkeys %hin void context —keys %h;— to force a reset before the new loop.keys/valuesresets the iterator: any call tokeysorvalueson the same hash — includingscalar keys %hinside the loop body — rewinds the cursor.List-context reference resets a hash’s iterator, not an array’s:
my @flat = %hrewinds%h’s cursor; the equivalentmy @copy = @adoes not touch@a’s iterator.Delete-during-iteration is unspecified except for the entry most recently returned. Deleting any other key may cause entries to be visited twice or skipped entirely.
Add-during-iteration is unspecified — inserting a new key mid loop may or may not be visited, and may disturb the order of entries not yet seen.
Anonymous container in the condition:
each %{ +{ a => 1 } }oreach @{ [1,2,3] }constructs a fresh container each time the condition is evaluated, so the iterator is always new and the loop never terminates.Tied hashes and arrays delegate to
FIRSTKEY/NEXTKEY(hashes) orFETCHSIZE/FETCH(arrays), so iteration order is whatever the tied class chooses and none of the guarantees above necessarily hold.Definedness vs truth in the loop condition:
while (each %h)andwhile (my $k = each %h)both test definedness of the expression, so a key of"0"or""does not terminate the loop. This is special-cased foreachspecifically.Scalar expressions:
each $hrefon a scalar holding a reference was an experimental feature in 5.14 and was removed in 5.24. Dereference explicitly:each %$href,each @$aref.Shared state across subs: passing
%hto a sub that callseach %h,keys %h, orvalues %hon it perturbs your caller’s iterator. If you publish a hash, assume callers may break your loop; preferforeach (keys ...)for robustness.
Differences from upstream#
Fully compatible with upstream Perl 5.42.
See also#
keys— snapshot of all keys (hash) or indices (array); resets the iteratoreachusesvalues— snapshot of all values; resets the iteratoreachusesdelete— safe for the entry just returned byeach, unsafe for any other during iterationexists— test key/index membership without perturbing the iteratorfor/foreach— the safer loop when the body might touch the container; combine withkeysto snapshot firstsort— pair withkeyswhen you need a defined iteration order;eachnever sorts