2011-03-23 11 views
7

Si comento el Dumper($cmd_string), entonces el while bucle nunca se toma.¿Cuáles son los efectos secundarios de Data :: Dumper()?

¿Qué efectos secundarios tiene Dumper() en $ cmd_string?

Esto es lo $ cmd_string es antes de la sub llamada:

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; 
} 

Si funciono el depurador Perl sin la Volquete() y utilizar el comando X en $ cmd_string entonces funciona, pero si sólo paso a través del código no funciona.

esto es después de sólo pisar aunque el código al final de la sub

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 

Ahora, si x $ cmd_string antes de que el bucle for me sale esto al final de la 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' 

Respuesta

12

El iterador sobre hashes each utiliza una variable oculta por hash para realizar un seguimiento de dónde se encuentra en el hash. Mi suposición es que el código usado para generar el hash $cmd_string también usa each, pero no está iterando hasta su finalización.

Para restablecer el iterador each, coloque keys %{$cmd_string->{$desc}}; antes del ciclo while. Llamar al keys en contexto vacío es la forma estándar de restablecer el iterador hash.

Como alternativa, simplemente use for my $cmd (keys %{$cmd_string->{$desc}}) { y luego cree la variable $arg dentro del ciclo.

La razón por la cual el uso de Dumper() soluciona el problema es que Dumper probablemente llama a keys en el hash, restableciendo así el iterador.

+0

Al menos una versión muy antigua de Dumper dejó accidentalmente el iterador al final de hashes que arrojó. – ysth

+0

Rápido, preciso y correcto. Me encanta SO ... – bitbucket

+1

'Dumper()' restablece el iterador interno. Esto lleva a un bucle infinito: 'perl -MData :: Dumper -e '% x = (0,0); El volcador% x mientras que $ k = cada% x'' –

Cuestiones relacionadas