В этой части Учебника Perl мы узнаем, как работает цикл while в Perl.
use strict;
use warnings;
use 5.010;
my $counter = 10;
while ($counter > 0) {
say $counter;
$counter -= 2;
}
say 'done';
Цикл while
имеет условие (в нашем случае оно проверяет, положительна ли переменная
$counter) и блок кода в фигурных скобках.
Когда по ходу выполнения программа впервые встречает начало цикла while, она проверяет,
истинно ли условие. Если оно возвращает FALSE
, блок
пропускается и программа переходит к следующему выражению, в нашем случае к выводу 'done'.
Если условие цикла while
возвращает TRUE
, блок выполняется, и затем программа
возвращается к проверке условия. Условие снова проверяется. Если результат проверки - ложь, блок
пропускается и выводится 'done'. Если результат - истина, то блок выполняется и программа
возвращается к условию...
Это продолжается, пока условие выполняется, говоря по-русски:
while (условие-истинно) { сделать-что-то }
Бесконечный цикл
В предыдущем коде переменная всегда уменьшалась, так что мы были уверены, что условие рано или поздно перестанет выполняться. Если по какой-то причине условие никогда не станет ложным, мы попадем в бесконечный цикл. Программа застрянет в маленьком блоке, из которого не сможет выбраться.
Например, если мы забыли уменьшить $counter
или мы вообще увеличиваем его и ждем, пока он
окажется меньше какой-то величины.
Если это случается по ошибке, это баг.
С другой стороны, в некоторых случаях намеренное использование бесконечного цикла поможет нам проще и написать программу, и читать ее впоследствии. Мы любим читаемый код! Если нам нужен бесконечный цикл, стоит использовать условие, которое всегда истинно.
Например:
while (42) {
# делать что-то
}
Конечно, люди без должной эрудиции удивятся, почему 42, так что более общепринятое, хотя и немного скучное, решение - всегда использовать в бесконечных циклах число 1.
while (1) {
# делать что-то
}
Естественно, увидев, что в коде нет выхода из цикла, кто-то может удивиться, как вообще эта программа может закрыться без насильного прекращения извне?
Для этого существует несколько способов.
Один из них - это выражение last
внутри цикла while. Оно пропускает остаток блока и не
проверяет условие по новой, по сути, заканчивая цикл. Обычно его помещают в какое-нибудь условие.
use strict;
use warnings;
use 5.010;
while (1) {
print "Какой язык программирования вы сейчас изучаете? ";
my $name = <STDIN>;
chomp $name;
if ($name eq 'Perl') {
last;
}
say 'Неверно! Попробуйте еще раз!';
}
say 'готово';
В этом примере мы спрашиваем пользователя и надеемся, что он сможет ответить на вопрос и использовать правильный регистр. Он застрянет на этом вопросе навечно, если не сможет набрать 'Perl'.
Так что общение может происходить примерно так:
Какой язык программирования вы сейчас изучаете?
> Java
Неверно! Попробуйте еще раз!
Какой язык программирования вы сейчас изучаете?
> PHP
Неверно! Попробуйте еще раз!
Какой язык программирования вы сейчас изучаете?
> Perl
готово
Как вы видите, когда пользователь ввел правильный ответ, вызвалось выражение last
, остаток
блока, включая say 'Неверно! Попробуйте еще раз!';
, был пропущен, и выполнение продолжилось
с конца цикла while
.