Я пытаюсь создать массив хэшей, но у меня возникают проблемы с перебором массива. Я пробовал этот код, но он не работает:
for ($i = 0; $i<@pattern; $i++){
while(($k, $v)= each $pattern[$i]){
debug(" $k: $v");
}
}
Я пытаюсь создать массив хэшей, но у меня возникают проблемы с перебором массива. Я пробовал этот код, но он не работает:
for ($i = 0; $i<@pattern; $i++){
while(($k, $v)= each $pattern[$i]){
debug(" $k: $v");
}
}
Во-первых, почему вы не use
strict
и warnings
? Следующие строки должны быть в начале каждой создаваемой вами Perl-программы, сразу после #!/usr/bin/perl
. Всегда.
use strict;
use warnings;
И я знаю, что нет, потому что я почти уверен, что вы получите несколько хороших сообщений об ошибках из strict
и warnings
из этого, а также из многих других мест вашего кода, судя по использованию вами переменных.
Во-вторых, почему вы не делаете этого:
for my $i (@pattern) {
..
}
Это перебирает каждый элемент в @pattern
, назначая их $i
по одному. Затем в вашем цикле, когда вам нужен определенный элемент, просто используйте $i
. Изменения в $i
будут отражены в @pattern
, а когда цикл завершится, $i
выйдет из области видимости, по сути подчистив себя.
В-третьих, из любви к Ларри Уоллу, пожалуйста, объявите свои переменные с помощью my
, чтобы локализовать их. На самом деле это не так сложно, и это сделает тебя лучше, обещаю.
В-четвертых, и последнее, в вашем массиве хранятся ссылки на хэши, а не хэши. Если бы они хранили хэши, ваш код был бы неправильным, потому что хэши начинаются с %
, а не $
. Как бы то ни было, ссылки (любого вида) являются скалярными значениями и, таким образом, начинаются с $
. Поэтому нам нужно разыменовать их, чтобы получить хэши:
for my $i (@pattern) {
while(my($k, $v) = each %{$i}) {
debug(" $k: $v");
}
}
Или по-вашему:
for (my $i = 0; $i<@pattern; $i++) { # added a my() for good measure
while(my($k, $v) = each %{$pattern[$i]}) {
debug(" $k: $v");
}
}
%$i
. Причина, по которой я использовал скобки, заключается в том, что если вы получаете более сложные, чем просто $i
, они вам нужны: %{$pattern[$i]}
не может быть записано как %$pattern[$i]
, потому что второе неоднозначно.
- person Chris Lutz; 24.08.2009
Попробуйте это вместо этого:
for my $hashref (@pattern) {
for my $key (keys %$hashref) {
debug "$key: $hashref->{$key}";
}
}
Самой большой проблемой с тем, что вы пытались сделать, было each $pattern[$i]
. Функция each ожидает, что хеш будет работать, но $pattern[$i]
возвращает хэш-ссылку (т. е. ссылка на хеш). Вы можете исправить свой код, разыменовав $pattern[$i]
как хеш:
while(my($k, $v) = each %{$pattern[$i]}) {
Кроме того, остерегайтесь каждой функции, она может оставить итератор хэша в незавершенном состоянии.
each()
это плохо. Мне нравится твоя отсылка к Звездным войнам.
- person Chris Lutz; 24.08.2009
each
не столько плоха, сколько опасна. И функция keys
тоже не совсем безопасна: my @keys = keys %hash
. Что произойдет, если %hash является связанной базой данных, которая содержит во много раз больше памяти? В этом случае while (my ($key, $val) = each %hash) {}
явно лучше.
- person Chas. Owens; 24.08.2009
См. документацию к кулинарной книге структур данных perl: perldoc perldsc