100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Programming

Loops in Perl

Master Perl's loop constructs — while, until, for, foreach — along with loop control statements like next, last, and redo.

Control Flow & SubroutinesBeginner9 min readJul 10, 2026
Analogies

Iterating in Perl

Perl offers while, until, a C-style for, and foreach (which can also be written for) for iteration. foreach is idiomatic for stepping through the elements of a list, defaulting to the topic variable $_ when no named loop variable is given, while while/until are driven purely by a boolean condition rather than a list.

🏏

Cricket analogy: Bowling all six deliveries of an over is like Perl's foreach looping over a fixed list, while a bowler continuing to bowl until the batting side is dismissed resembles a while loop running until a condition changes.

while, until, and C-style for

while(COND) { ... } repeats its body as long as COND is true, testing before each pass; until(COND) is its logical inverse. The C-style for(init; cond; incr) { ... } gives explicit control over an initializer, a test, and a step expression, evaluated in that order each pass. do { ... } while/until differs from all of these by testing after the first execution, guaranteeing the body runs at least once.

🏏

Cricket analogy: A run chase can turn into an infinite ordeal if the required-rate calculation never updates the loop condition, just as a Perl while ($overs_left) {...} loop spins forever if nothing inside the block ever decrements $overs_left.

perl
# while loop reading input until EOF
my @lines;
while (my $line = <STDIN>) {
    chomp $line;
    push @lines, $line;
}

# C-style for loop counting
for (my $i = 1; $i <= 5; $i++) {
    print "Iteration $i\n";
}

# foreach with labeled loop and next/last
OUTER: foreach my $row (1..3) {
    foreach my $col (1..3) {
        next OUTER if $col == 2 && $row == 2;
        print "row=$row col=$col\n";
    }
}

foreach and Aliasing to $_

foreach my $item (@list) { ... } binds $item to each element of @list in turn. Crucially, $item is an alias to the real array element, not a copy — assigning to it inside the loop body mutates the underlying array. When no named variable is given, foreach uses the default topic variable $_, which many built-in functions also read implicitly.

🏏

Cricket analogy: When a scorer walks through foreach my $run (@ball_by_ball) and reassigns $run to correct a miscounted no-ball, that edit changes the actual @ball_by_ball array, because Perl's foreach variable is an alias to the real element, not a copy.

Perl's foreach loop variable is aliased to the actual array element, not a copy. Writing foreach my $n (@nums) { $n *= 2; } doubles every value in @nums itself. If you don't want to mutate the source array, copy explicitly first, e.g. foreach my $n (@nums) { my $doubled = $n * 2; ... }.

Loop Control: next, last, redo, and Labels

next skips the remainder of the current iteration's body and moves on, re-testing the loop's condition. last exits the enclosing loop entirely. redo re-executes the current iteration's body from the top without re-testing the condition or advancing to the next element. By default these affect only the innermost loop; a label like OUTER: placed before a loop lets next/last/redo target that outer loop explicitly from inside a nested one.

🏏

Cricket analogy: A bowler who overstepped calls for a redo of that delivery, it doesn't count and gets bowled again, just like Perl's redo restarting the current loop iteration without re-testing the condition or advancing to the next element.

redo re-runs the current loop body without re-testing the loop's condition or moving to the next element, so a redo that isn't eventually guarded by some changing state can loop forever, unlike next, which always advances the iteration first. Labeled loops (e.g., OUTER:) are the only way to target next/last/redo at an outer loop from inside a nested one.

  • while loops run while a condition is true; until loops run while a condition is false — they're logical inverses.
  • C-style for(init; cond; incr) loops give explicit control over initialization, testing, and stepping.
  • foreach (or its alias for) iterates over a list, aliasing the loop variable directly to each element.
  • do { ... } while/until guarantees the block runs at least once before the condition is tested.
  • next skips to the next iteration; last exits the loop entirely; redo re-runs the current iteration without re-testing.
  • Labeled loops (OUTER: ...) let next/last/redo target an outer loop from within a nested one.
  • Modifying the foreach loop variable modifies the underlying array element unless you explicitly copy it first.

Practice what you learned

Was this page helpful?

Topics covered

#Programming#PerlStudyNotes#LoopsInPerl#Loops#Perl#Iterating#While#StudyNotes#SkillVeris#ExamPrep