Листинг 5.10. Определение максимального элемента массива циклом foreach
#! perl -w
@array = (1,-6,9,18,0,-10);
@max = $array[0];
foreach $temp (@array) {
$max = $temp if $temp > $max;
}
print "$max";
Отметим несколько особенностей цикла foreach. Прежде всего, следует сказать, что ключевое слово
foreach является синонимом ключевого слова for. Цикл из листинга 5.10 можно было бы записать и так:
for $temp (@array) ( # Ключевое слово foreach синоним for.
$max = $temp if $temp > $max;
}
Однако, как нам кажется, использование foreach лучше отражает семантику этого оператора цикла,
так как в самом ключевом слове уже отражена его сущность (foreach — для каждого).
Следующая особенность оператора foreach связана с переменной цикла. По умолчанию эта переменная
является локальной, область видимости которой ограничена телом цикла, включая блок continue. Она
создается только на время выполнения цикла foreach, доступна внутри всего цикла и уничтожается при
выходе из него.
Обычно программисты Perl в циклах foreach вообще не применяют переменную цикла. Это связано с
тем обстоятельством, что при отсутствии явно заданной переменной цикла Perl по умолчанию использует
специальную переменную $_. С учетом этого факта цикл foreach листинга 5.10 можно переписать и так:
foreach (@аrrау) { # В качестве переменной цикла
# используется $_.
$max = $_ if $_ > $max;
}
Последняя особенность оператора foreach, которая также связана с переменной цикла, заключается в
том, что фактически на каждом шаге выполнения цикла эта переменная является синонимом того элемента
списка, значение которого она содержит. Это позволяет в цикле изменять значения элементов списка,
если они представляют правильные l-значения. Например, возвести в квадрат каждый элемент списка можно
следующим оператором foreach:
foreach (@аrrау) {
$_ **= 2;
}
Как отмечалось, список в цикле foreach может быть задан и функцией, которая в списковом контексте
возвращает целый список значений. Канонический способ печати хэш-массива в упорядоченном по ключам
порядке представлен в программе из листинга 5.11.
Листинг 5.11. Упорядочивание и печать хэш-массива
#! perl -w
%array = (
blue => 1,
red => 2,
green => 3,
yellow => 3
);
foreach (sort keys %array) {
print "$_\t => $array{$_}\n";
}
Эта программа напечатает пары ключ/значение хэш-массива %array в соответствии с лексикографическим
упорядочиванием его ключей:
blue => 1
green => 3
red => 2
yellow => 3
ВНИМАНИЕ Цикл foreach, примененный к массиву, выполняется быстрее аналогичного цикла for, так как не
требует дополнительных затрат на вычисление индекса элемента списка.
Как и в случае с оператором цикла while, если задан блок continue, то его операторы будут обязательно
выполнены при переходе на новую итерацию цикла.
ВНИМАНИЕ Все рассмотренные нами операторы цикла могут быть вложенными друг в друга. Основное
требование – вложенный оператор цикла должен завершаться в теле цикла, в котором он вложен.