Data :: Dumper()的副作用是什么?

时间:2011-03-23 21:06:11

标签: perl debugging side-effects

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

1 个答案:

答案 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,从而重置迭代器。

相关问题