Perl Redo Statement
## Perl redo Statement
In Perl, the `redo` statement is a powerful loop control modifier. It immediately restarts the current loop iteration from the very first line of the loop block without re-evaluating the loop's conditional expression.
Unlike `next` (which jumps to the next iteration and evaluates the condition/increment), `redo` restarts the *same* iteration. Crucially, when `redo` is triggered, any statements following it in the block, as well as any associated `continue` blocks or `for` loop increment steps, are completely bypassed.
---
## Syntax
The syntax for the `redo` statement is as follows:
```perl
redo ;
```
The `LABEL` parameter is optional:
* **With `LABEL`**: The `redo` statement immediately transfers control back to the first line of the loop block associated with the specified `LABEL`. It bypasses any remaining code in the block and skips the `continue` block.
* **Without `LABEL`**: The `redo` statement transfers control back to the first line of the innermost enclosing loop block.
---
## How redo Works (Control Flow)
To understand how `redo` differs from other loop control statements like `next` and `last`, consider its execution flow:
1. The loop begins and executes statements normally.
2. When `redo` is encountered:
* Execution immediately jumps back to the top of the loop block.
* **No** loop condition is re-evaluated.
* **No** iteration step (like the third expression in a `for (;;)` loop) is executed.
* The `continue` block (if present) is **not** executed.
3. The loop block starts executing again from its first statement.
---
## Code Examples
### Example 1: Basic Usage with a `continue` Block
The following example demonstrates how `redo` skips the `continue` block and restarts the loop iteration.
```perl
#!/usr/bin/perl
use strict;
use warnings;
my $a = 0;
while ($a < 10) {
if ($a == 5) {
# Increment $a manually to avoid an infinite loop,
# then restart the current iteration.
$a = $a + 1;
redo;
}
print "a = $a\n";
} continue {
# This block is skipped when 'redo' is executed
$a = $a + 1;
}
```
#### Output:
```text
a = 0
a = 1
a = 2
a = 3
a = 4
a = 6
a = 7
a = 8
a = 9
```
**Explanation:**
When `$a` reaches `5`, the `if` condition evaluates to true. Inside the `if` block, `$a` is incremented to `6`, and `redo` is called. The program immediately jumps back to the start of the `while` loop block. The `print` statement and the `continue` block (which would normally increment `$a`) are skipped for this iteration.
---
### Example 2: Using `redo` with a Loop Label
Labels are highly useful when dealing with nested loops, allowing you to specify exactly which loop level you want to restart.
```perl
#!/usr/bin/perl
use strict;
use warnings;
my $i = 0;
OUTER: while ($i < 3) {
$i++;
print "Outer loop iteration: $i\n";
INNER: while (1) {
print " Inner loop: Enter a number (type 'skip' to redo outer, 'exit' to stop): ";
my $input = ;
chomp($input);
if ($input eq 'skip') {
print " --> Redoing OUTER loop...\n";
redo OUTER;
}
if ($input eq 'exit') {
last OUTER;
}
print " You entered: $input\n";
last INNER; # Exit inner loop normally
}
}
```
---
## Key Considerations and Best Practices
1. **Avoid Infinite Loops**: Because `redo` does not re-evaluate the loop condition or execute the increment step (in `for` loops or `continue` blocks), you must manually update your loop control variables before calling `redo`. Otherwise, you will create an infinite loop.
2. **Difference between `next` and `redo`**:
* `next` starts the *next* iteration (evaluates the condition and runs the `continue` block).
* `redo` restarts the *current* iteration (does not evaluate the condition and skips the `continue` block).
3. **Use Cases**: `redo` is exceptionally useful for input validation filtering (e.g., prompting a user for input again if they provide an invalid value without advancing the loop counter) and parsing text files where a line needs to be re-processed under different rules.
YouTip