В этой части Учебника 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.