Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are Data::Dumper()'s side effects?

If I comment out the Dumper($cmd_string) then the while loop is never taken.

What side effects does Dumper() have on $cmd_string?

Here is what $cmd_string is before the sub call:

VAR1 = {
    'The Java Runtime Library' => {
        'apt-get install -y' => 'sun-java6-jre'
    }
};


sub installPackages
{
    my $cmd_string = shift;
    my %rc_hash;

    my $rc;

    Dumper($cmd_string);

    for my $desc (keys %{$cmd_string})
    {
        while (my ($cmd, $arg) = each %{$cmd_string->{$desc}})
        {
            print "system($cmd $arg)\n";

            $rc = system("$cmd $arg");

            if ($rc)
            {
                $rc_hash{$desc}{$cmd} = '';
            }
        }
    }
    return \%rc_hash;
}

If I run the Perl debugger without the Dumper() and use the x command on $cmd_string then it works, but if I just step through the code it does not work.

This is after only stepping though the code at the end of the sub

  DB<3> x $cmd_string
0  HASH(0x2769550)
   '' => HASH(0x2769880)
        empty hash
   'The Java Runtime Library' => HASH(0x25cc2a0)
      'apt-get install -y' => 'sun-java6-jre'
  DB<4> x $cmd_string->{$desc}
0  HASH(0x2769880)
     empty hash

Now, if I x $cmd_string before the for loop I get this at the end of the sub

main::installPackages(msi.pl:1979):       return \%rc_hash;
  DB<3> x $cmd_string
0  HASH(0x1125490)
   'The Java Runtime Library' => HASH(0xf852a0)
      'apt-get install -y' => 'sun-java6-jre'
like image 991
bitbucket Avatar asked Mar 23 '11 21:03

bitbucket


1 Answers

The each iterator over hashes uses a hidden per hash variable to keep track of where it is in the hash. My guess is that the code used to generate the $cmd_string hash also uses each but is not iterating to completion.

To reset the each iterator, place keys %{$cmd_string->{$desc}}; before your while loop. Calling keys in void context is the standard way of resetting the hash iterator.

Alternatively, just use for my $cmd (keys %{$cmd_string->{$desc}}) { and then create the $arg variable inside the loop.

The reason why using Dumper() fixes the problem is that Dumper most likely calls keys on the hash, thereby resetting the iterator.

like image 192
Eric Strom Avatar answered Sep 23 '22 12:09

Eric Strom