2011-03-23 9 views
7

यदि मैं Dumper($cmd_string) पर टिप्पणी करता हूं तो while लूप कभी नहीं लिया जाता है।डेटा :: डूपर() के दुष्प्रभाव क्या हैं?

डुपर() के किनारे दुष्प्रभाव $ 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; 
} 

अगर मैं) डम्पर (बिना पर्ल डिबगर चलाने के लिए और उसके बाद cmd_string $ पर एक्स आदेश यह काम करता है का उपयोग करें, लेकिन अगर मैं सिर्फ कदम:

यहाँ $ cmd_string उप कॉल करने से पहले है कोड के माध्यम से यह काम नहीं करता है।

केवल उप के अंत में हालांकि कोड कदम

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 

अब, अगर मैं cmd_string $ x पाश के लिए पहले के बाद मैं उप के अंत में इस मिल यह है

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 इटरेटर रीसेट करने के लिए, अपने समय लूप से पहले keys %{$cmd_string->{$desc}}; रखें। शून्य संदर्भ में keys को कॉल करना हैश इटरेटर को रीसेट करने का मानक तरीका है।

वैकल्पिक रूप से, सिर्फ for my $cmd (keys %{$cmd_string->{$desc}}) { उपयोग करना और फिर पाश अंदर $arg चर पैदा करते हैं।

कारण है कि Dumper() समस्या ठीक करता है का उपयोग करते हुए कि डम्पर सबसे अधिक संभावना हैश पर keys कहता है, जिससे इटरेटर को रीसेट है।

+0

डम्पर के कम से कम एक पुराने संस्करण ने गलती से हश के अंत में इटेटरेटर को गलती से छोड़ दिया। – ysth

+0

तेज, सटीक, और सही। मुझे SO प्यार है ... – bitbucket

+1

'Dumper()' आंतरिक इटरेटर को रीसेट करता है। यह अनंत लूप की ओर जाता है: 'perl -MData :: Dumper -e '% x = (0,0); डम्पर% x जबकि $ k = प्रत्येक% x'' –

संबंधित मुद्दे