如果我注释掉Dumper($cmd_string)
,则永远不会采用while
循环。
Dumper()对$ cmd_string有什么副作用?
以下是$ cmd_string在子调用之前的内容:
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;
}
如果我在没有Dumper()的情况下运行Perl调试器并在$ cmd_string上使用x命令,那么它可以工作,但是如果我只是单步执行代码它就不起作用。
这是仅仅通过子
末尾的代码 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
现在,如果我在for循环之前使用x $ cmd_string,我会在子结尾处得到这个
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'
答案 0 :(得分:12)
哈希上的each
迭代器使用隐藏的每个哈希变量来跟踪它在哈希中的位置。我的猜测是,用于生成$cmd_string
哈希的代码也使用each
,但没有迭代完成。
要重置each
迭代器,请在while循环前放置keys %{$cmd_string->{$desc}};
。在void上下文中调用keys
是重置散列迭代器的标准方法。
或者,只需使用for my $cmd (keys %{$cmd_string->{$desc}}) {
,然后在循环内创建$arg
变量。
使用Dumper()
修复问题的原因是Dumper很可能在哈希上调用keys
,从而重置迭代器。