Шаг 20.
Команда redo

    На этом шаге мы рассмотрим использование команды redo.

    Ее общий вид:

  redo ИДЕНТИФИКАТОР_МЕТКИ;

    Команда redo повторно выполняет операторы тела цикла, не инициализируя следующую итерацию. Это означает, что ни выражение изменения цикла for, ни операторы блока continue, если он присутствует, ни выражение условия не вычисляются. Операторы тела цикла, расположенные за оператором redo, пропускаются и снова начинается выполнение тела цикла со значениями переменных, которые они имели перед выполнением этой передачи управления. следующая программа демонстрирует использование команды redo.

$notempty = 0;
$total = 0;
for (;;) {                           # Бесконечный цикл
     $line = <STDIN>;                # Ввод строки
     chop($line);                    # Удаление из строки символа “\n”
     last  if  $line  eq  “END”;     # Выход из цикла
     ++$total;
     redo  if  $line  eq  “”;        # Возврат на чтение строки
     ++$notempty;
}
print “Всего прочитано строк: $total\n Из них не пустых: $notempty\n”;
Текст этого примера можно взять здесь.

    Эта программа в бесконечном цикле ожидает ввода пользователем с клавиатуры строки данных и в переменной $total подсчитывает количество введенных строк. В переменной $notempty располагается количество введенных не пустых строк. Если введена пустая строка, то команда redo начинает повторное выполнение операторов тела цикла, не увеличивая на единицу переменную $notempty. Для завершения бесконечного цикла следует ввести строку END. В этом случае выполняется команда last. Функция chop используется для удаления из введенной пользователем строки символа перехода на новую строку “\n”, поэтому в программе она сравнивается со строками без завершающего символа перехода на новую строку.

    Если команда redo используется с идентификатором метки, то ее действие аналогично действию команды next с той лишь разницей, что она просто передает управление на первый оператор тела цикла с указанной меткой, не инициируя следующей итерации и не вычисляя операторов блока continue. В качестве иллюстрации такого использования команды redo перепишем предыдущую программу следующим образом:

$notempty = 0; 
$total = 0; 
OUT: while (1) {
    print "Введи строки\n";  # Сюда передает управление команда redo OUT; 
    for (;;) {
      $line=<STDIN>; 
      chop($line);
 
      last OUT if $line eq "END";  # Выход из всех циклов
      ++$total;
      redo OUT if $line eq "";
      ++$notempty;
  }
}
print “Всего прочитано строк: $total\n Из них не пустых: $notempty\n”;
Текст этого примера можно взять здесь.

    В этом примере мы ввели внешний бесконечный цикл OUT и изменили команды redo и last, добавив к ним метку на внешний цикл. Теперь в случае, если пользователь вводит пустую строку, команда redo OUT передает управление на первый оператор внешнего цикла, и программа печатает приглашение ввести строки.

    На следующем шаге мы рассмотрим именованные блоки.




Предыдущий шаг Содержание Следующий шаг