Метки
Что делать, если вы хотите выйти из блока, в которым содержится самый внутренний блок, иными словами, выйти сразу из двух вложенных блоков? В С вы могли бы обратиться к оклеветанному всеми оператору goto. В Perl такая хитрость не нужна — здесь по отношению к любому охватывающему блоку можно использовать операторы last, next и redo, присвоив этому блоку имя с помощью метки.
Метка — это еще один тип имени из еще одного пространства имен, отвечающего тем же правилам, что и имена скаляров, массивов, хешей и подпрограмм. Мы увидим, однако, что в метке нет специального префиксного символа (аналогичного $ в скалярах, символу & в подпрограммах и т.д.), поэтому метка print, к примеру, конфликтовала бы с зарезервированным словом print, в силу чего ее использование не допускается. По этой причине лучше создавать метки с именами, состоящими только из прописных букв и цифр, которые в будущем никогда не будут использоваться в зарезервированных словах. Кроме того, прописные буквы и цифры хорошо выделяются в тексте программы, который набирается в основном с использованием нижнего регистра.
Выбрав имя метки, введите его прямо перед оператором, содержащим блок, и поставьте двоеточие:
МЕТКА: while (условие) { оператор;
оператор;
оператор;
if (другое_условие) { last МЕТКА;
} )
Мы указали метку как параметр в операторе last. Это дает языку Perl указание выйти из блока с именем метка, а не только из самого внутреннего блока. В данном случае, однако, у нас есть только один циклический блок. Давайте рассмотрим вариант со вложенными циклами:
OUTER: for ($i=l; $i <= 10; $i++) {
INNER: for ($j=l; $j <= 10; $j++) ( if ($i * $j == 63) (
print "$i times $j is 63!\n";
last OUTER;
}
if ($j>=$i) ( next OUTER;
} }
}
Этот набор операторов позволяет перебирать все результаты перемножения небольших чисел до тех пор, пока не будет найдена пара, произведение которой равно 63 (7 и 9). После того как эта пара будет найдена, проверка остальных чисел теряет смысл, поэтому первый оператор if обеспечивает выход из обоих циклов for, используя для этого оператор last с меткой. Второй оператор if гарантирует, что большим из двух чисел всегда будет первое, переходя к следующей итерации внешнего цикла, как только поставленное условие перестанет быть истинным. Это значит, что числа будут проверяться при значениях переменных ($i,$j) = (1,1), (2,1), (2,2), (3,1), (3,2), (3,3), (4,1) ИТ.Д.
Даже если самый внутренний блок имеет метку, действие операторов last, next и redo без необязательного параметра (метки) все равно распространяется на него. Кроме того, с помощью меток нельзя переходить в блок — можно только выходить из него. Операторы last, next или redo должны находиться внутри блока.