Klaus
Klaus

Reputation: 865

Perl hash: while-each-loop runs into endless loop

The following Perl code runs into an endless loop. It looks like each resets itself after the subroutine call. Why is that so?

#!/usr/bin/perl
use warnings;
use strict;

my %h = ( "a" => "b" );
while ( my ($x, $y) = each %h ) {
    &do_something( \%h );
}

sub do_something(){
    my %tmp  = %{$_[0]};
}

Interestingly, this works:

while ( my ($x, $y) = each %h ) {
    &do_something( \%h );
}

sub do_something(){
}

While this does not:

while ( my ($x, $y) = each %h ) {
    &do_something( %h );
}

sub do_something(){
}

Upvotes: 2

Views: 556

Answers (1)

ikegami
ikegami

Reputation: 385764

Getting the hash's content by evaluating it in list context uses the same iterator as each/keys/values, causing it to be reset.

Minimal demonstration:

>perl -E"%h=(a=>4); while (($k) = each(%h)) { say $k; keys %h }"
a
a
a
...

>perl -E"%h=(a=>4); while (($k) = each(%h)) { say $k; %t=%h }"
a
a
a
...

Since you only evaluate the hash in list context in the first and third snippets, the iterator is only reset in those two snippets.


PS — Why do you use an incorrect prototype (()) then tell Perl to ignore it (&)?

Upvotes: 6

Related Questions