2011-03-23 64 views
7

如果我註釋掉Dumper($cmd_string)那麼while循環從來沒有采取。什麼是Data :: 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; 
} 

如果我跑,而不翻車機(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' 

回答

12

each迭代器來使用哈希散列每一個變量隱藏跟蹤它在哪裏的哈希值。我的猜測是,用於生成$cmd_string散列的代碼也使用each,但不會迭代完成。

要重置each迭代,while循環之前放置keys %{$cmd_string->{$desc}};。在void context中調用keys是重置哈希迭代器的標準方法。

備選地,只是使用for my $cmd (keys %{$cmd_string->{$desc}}) {,然後創建循環內的$arg變量。

之所以使用Dumper()修復的問題是,自卸車最有可能哈希呼籲keys,由此重置迭代器。

+0

至少有一個很老的版本自卸車在它傾倒哈希年底不小心留下的迭代器。 – ysth 2011-03-23 21:31:43

+0

快速,準確,正確。我喜歡SO ... – bitbucket 2011-03-23 21:41:54

+1

Dumper()'重置內部迭代器。這會導致無限循環:'perl -MData :: Dumper -e'%x =(0,0); Dumper%x while $ k = each%x'' – 2011-03-23 21:57:33

相關問題