Британец Барри Уолш пишет в своем блоге о важной особенности работы оператора each в Perl 5.12.
Вызов each, примененный к массиву, возвращает пару величин: индекс и значение очередного элемента. Очевидно, что в пределах цикла (напрмер, while) each сохраняет указатель на текущую позицию.
use v5.12;
my @letters = 'a'..'z';
while (my ($number, $char) = each @letters) {
say "$number $char";
}
Однако, менее очевидно, что если преравать итерацию, то при следующем вызове нумерация будет продолжена с прежней позиции. Например:
use v5.12;
my @letters = 'a'..'z';
while (my ($number, $char) = each @letters) {
say "$number $char";
last if $number == 15;
}
say "Second loop";
while (my ($number, $char) = each @letters) {
say "$number $char";
}
В этом примере напечатается следующее:
0 a
1 b
2 c
. . .
14 o
15 p
Second loop
16 q
17 r
. . .
24 y
25 z
Видно, что each продолжил с того же места, где остановился в первом цикле.
Сбросить счетчик удается вызовом keys @array или values @array. Также важно, что изменение массива (с помощью push или pop) и даже присвоение новых значений не изменяет позицию счетчика:
use v5.12;
my @letters = 'a'..'z';
while (my ($number, $char) = each @letters) {
say "$number $char";
last if $number == 15;
}
@letters = 'A'..'Z';
say "Second loop";
while (my ($number, $char) = each @letters) {
say "$number $char";
}
В этом случае второй цикл упрямо продолжит с того же места, но уже с другим содержанием:
0 a
1 b
2 c
. . .
14 o
15 p
Second loop
16 Q
17 R
. . .
24 Y
25 Z
Комментировать