Каковы побочные эффекты Data :: Dumper ()? - PullRequest
7 голосов
/ 24 марта 2011

Если я закомментирую 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;
}

Если я запускаю отладчик Perl без Dumper () и использую команду x на $ 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 перед циклом for, я получаю это в конце подпрограммы

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 Ответ

12 голосов
/ 24 марта 2011

Итератор each для хэшей использует скрытую переменную per hash, чтобы отслеживать, где она находится в хэше.Я предполагаю, что код, используемый для генерации хеша $cmd_string, также использует each, но не выполняет итерацию до завершения.

Чтобы сбросить итератор each, поместите keys %{$cmd_string->{$desc}}; перед циклом while.Вызов keys в пустом контексте является стандартным способом сброса хеш-итератора.

Либо просто используйте for my $cmd (keys %{$cmd_string->{$desc}}) {, а затем создайте переменную $arg внутри цикла.

Причинапочему использование Dumper() решает проблему, потому что Dumper, скорее всего, вызывает keys для хэша, тем самым сбрасывая итератор.

...