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'
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With