--- name: redo signatures: - 'redo LABEL' - 'redo EXPR' - 'redo' since: 5.0 status: documented categories: ["Control flow"] --- ```{index} single: redo; Perl built-in ``` *[Control flow](../perlfunc-by-category)* # redo Restart the current iteration of a loop without re-testing the condition and without running the [`continue`](continue) block. `redo` jumps back to the top of the loop body and re-runs it on the *same* input — the conditional that guards the loop is not re-evaluated, [`$_`](../perlvar) is not advanced by `while ()`, the iterator of a `foreach` is not advanced, and any `continue { }` block attached to the loop is skipped. The current pass happens again from the beginning. ## Synopsis ```perl redo redo LABEL redo EXPR ``` ## What you get back `redo` does not return a value. It is a flow-control operator: it transfers control and never falls through to the next statement. Do not try to use it as the value of an expression — in particular, it cannot be used to return a value from `eval { }`, `sub { }`, or `do { }`. ## Which loop it targets With no argument, `redo` refers to the innermost enclosing loop. With a `LABEL`, it restarts the loop tagged with that label, allowing you to reach out of nested loops: ```perl OUTER: while (...) { while (...) { redo OUTER; # restart the while (...) above } } ``` `redo EXPR` (added in Perl 5.18) computes the label at runtime. The expression must evaluate to a string naming a label currently in scope: ```perl my $target = "OUTER"; redo $target; ``` A bare block counts as a loop that runs once, so `redo` inside a block turns it into a looping construct: ```perl { my $line = ; redo if $line =~ /^\s*$/; # skip blank lines, re-read print $line; } ``` ## `redo` vs [`next`](next) vs [`last`](last) All three take an optional `LABEL` and all three affect loop control, but they differ in what they skip: - [`last`](last) — exit the loop entirely. [`continue`](continue) block is **not** run. - [`next`](next) — go to the next iteration. [`continue`](continue) block **is** run, then the loop condition is re-tested. - `redo` — re-run the *same* iteration. [`continue`](continue) block is **not** run, and the loop condition is **not** re-tested. The [`continue`](continue)-block difference is the one that catches people out. If a loop uses `continue { }` to increment a counter or advance a cursor, `redo` will not advance it — that's the whole point, but it is also the whole foot-gun. ## Examples Re-prompt until the user gives valid input. The [`continue`](continue) block is skipped, so `$attempts` only counts *completed* iterations, which is usually what you want: ```perl my $attempts = 0; while (1) { print "Enter a positive integer: "; my $n = ; chomp $n; redo unless $n =~ /^[0-9]+$/ && $n > 0; print "Got $n after $attempts rejected tries.\n"; last; } continue { $attempts++; } ``` Restart processing of the current line after patching it — the classic "lie to yourself about what was just read" pattern, here stripping Pascal-style block comments that may span multiple input lines: ```perl LINE: while () { while (s|({.*}.*){.*}|$1 |) {} s|{.*}| |; if (s|{.*| |) { my $front = $_; while () { if (/}/) { # end of comment? s|^|$front\{|; redo LINE; # re-process the patched line } } } print; } ``` Target an outer loop by label. `redo INNER` would restart the inner loop on the current `$x`; `redo OUTER` restarts the outer loop on the current `$x` *without* advancing the `foreach` iterator: ```perl OUTER: foreach my $x (@xs) { INNER: foreach my $y (@ys) { redo OUTER if should_restart($x, $y); } } ``` Turn a bare block into a retry loop. Without `redo` this block runs exactly once; with `redo` it runs until the fetch succeeds: ```perl my $tries = 0; { my $ok = try_fetch(); if (!$ok && ++$tries < 3) { sleep 1; redo; } } ``` ## Edge cases - **[`continue`](continue) is not run.** This is the defining difference from [`next`](next). If your loop relies on `continue { }` for counters, cursors, or cleanup, `redo` will bypass all of it. Either move the work into the body or use [`next`](next) instead. - **Loop condition is not re-tested.** `while (cond) { ... redo; }` will keep looping even if `cond` would now be false. You are responsible for ensuring the `redo` path eventually exits via [`last`](last), [`return`](return), or a conditional fall-through. - **Easy infinite loop.** `redo` with no state change is a tight infinite loop — typically not what you want. Always pair `redo` with a condition that eventually becomes false, or with a retry counter that triggers [`last`](last). - **`foreach` does not advance.** `foreach my $x (@xs) { redo }` keeps `$x` pinned at the current element and loops on it forever. The iterator only advances on fall-through or [`next`](next). - **`while ()` does not read the next line.** [`$_`](../perlvar) retains the current line across the `redo`, which is precisely why the Pascal comment stripper above works. - **`redo` out of [`grep`](grep) / [`map`](map) is not supported.** Upstream documents this as undefined; do not use `redo` to exit or restart a `grep BLOCK LIST` or `map BLOCK LIST`. - **`redo` out of [`eval`](eval), [`sub`](sub), or [`do`](do) is not a return.** It performs flow control; there is no value to return. A `redo` that would have to cross such a boundary to reach a loop is a runtime error ("Can't `redo` outside a loop block"). - **Precedence quirk.** Unlike most named operators, `redo` has the precedence of assignment and is exempt from the looks-like-a-function rule. `redo ("foo")."bar"` passes the whole concatenation as the argument to `redo` — the parentheses do not isolate `"foo"`. ## Differences from upstream Fully compatible with upstream Perl 5.42. ## See also - [`last`](last) — exit the loop entirely; [`continue`](continue) block is not run, same as `redo` - [`next`](next) — advance to the next iteration; [`continue`](continue) block **is** run and the loop condition is re-tested - [`return`](return) — return from the enclosing subroutine, not just the loop; unlike `redo`, it yields a value - [`continue`](continue) — the block that `redo` skips but [`next`](next) runs; the core of the three-way distinction