В этой строке вы пытаетесь объединить each
-тератор с циклом for-each.Несмотря на их похожие имена, они несовместимы:
foreach (my( $key, $val ) = each $p) {
print($key . "--->" . $val . "\n");
}
Это получает следующий элемент значения ключа от итератора %$p
и назначает список из двух элементов ($key, $val)
.Затем foreach
зацикливается на этих двух элементах.Вот почему вы всегда видите два одинаковых значения дважды.Поскольку порядок итерации с each
не определен, вы видите только случайную запись из %$p
хеша.
Чтобы исправить это:
Либо используйте цикл while для использованияeach
-тератор:
while (my ($key, $val) = each %$p) {
print "$key--->$val\n";
}
Или используйте цикл foreach для ключей:
for my $key (keys %$p) {
my $val = $p->{$key};
print "$key--->$val\n";
}
Я предпочитаю цикл for / foreach, поскольку это позволяет нам сортировать ключив стабильном порядке, вместо того, чтобы полагаться на неопределенный порядок итерации хэша:
for my $key (sort keys %$p) {
my $val = $p->{$key};
print "$key--->$val\n";
}
Это должно всегда давать одинаковый вывод для идентичных входных документов.
Как отметил zdim в своем ответеВы не должны передавать скаляры, такие как $p
, операторам, таким как keys
или each
, но должны разыменовывать их в хэш, такой как each %$p
.В противном случае ваш код не будет работать на последних версиях Perl.