На этом шаге мы введем понятие именованных блоков.
В Perl блок операторов, заключенный в фигурные скобки, семантически эквивалентен циклу, выполняющемуся только один раз. Поэтому можно использовать команду last для выхода из блока, а команду redo для повторного вычисления операторов блока. Команда next также осуществляет выход из блока, но отличается от команды last тем, что вычисляются операторы блока continue, который может задаваться для блока операторов в фигурных скобках:
BLOCK1: { $i = 1; last BLOCK1; } continue { ++$i; } print "Переменная \$i после BLOCK1: $i\n"; BLOCK2: { $i = 1; next BLOCK2; } continue { ++$i; } print "Переменная \$i после BLOCK2: $i\n";
Первый оператор print этого фрагмента кода напечатает значение переменной $i равным 1, тогда как второй оператор print напечатает 2, так как при выходе из блока BLOCK2 будет выполнен оператор увеличения на единицу переменной $i из блока continue.
Блоки могут иметь метки, и в этом случае их называют именованными блоками. Подобные конструкции используются для реализации переключателей - конструкций, которые не определены в синтаксисе языка Perl. Существует множество способов создания переключателей средствами языка Perl. Один из них представлен в следующем примере:
$var = 3; SWITCH: { $case1 = 1, last SWITCH if $var == 1; $case2 = 2, last SWITCH if $var == 2; $case3 = 3, last SWITCH if $var == 3; $nothing = 1; }
После выполнения именованного блока операторов SWITCH переменная $case1 будет равна 1, если $var равна 1, $case2 будет равна 2, если $var равна 2 и, наконец, $case3 будет равна 3, если $var равна 3. В случае, если переменная $var не равна ни одному из перечисленных значений, то переменная $nothing будет равна 1. Конечно, это простейший переключатель, разработанный всего лишь для демонстрации возможности быстрого создания переключателя в Perl.
Блоки могут вложенными друг в друга. Именованные блоки и команды управления циклом, используемые для выхода из внутренних блоков, позволяют создавать достаточно интересные конструкции, реализующие сложные алгоритмы. Например, можно организовать бесконечный цикл без использования какого-либо оператора цикла:
$notempty = 0;
$total = 0;
INPUT: {
$line=<STDIN>;
chop($line);
last INPUT if $line eq "END"; # Выход из бесконечного цикла
++$total;
redo INPUT if $line eq "";
++$notempty;
redo INPUT;
}
print "Всего прочитано строк: $total\n Из них не пустых: $notempty\n";
Это программа из шага 20: реализация без оператора цикла программы ввода строк и подсчета общего числа введенных, а также непустых строк. Единственное, что пришлось добавить - еще одну команду redo в конце блока операторов.
На следующем шаге мы рассмотрим оператор безусловного перехода.