7

如果我注释掉,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 我在 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'
4

1 回答 1

12

哈希迭代器使用隐藏的each每个哈希变量来跟踪它在哈希中的位置。我的猜测是用于生成$cmd_string哈希的代码也使用each但没有迭代完成。

要重置each迭代器,请放置keys %{$cmd_string->{$desc}};在您的 while 循环之前。在 void 上下文中调用keys是重置哈希迭代器的标准方法。

或者,只需使用for my $cmd (keys %{$cmd_string->{$desc}}) {然后$arg在循环内创建变量。

using 修复问题的原因Dumper()是 Dumper 最有可能调用keys哈希,从而重置迭代器。

于 2011-03-23T21:25:46.483 回答