[Chapter 9] 9.4 Labeled Blocks
Author: Randal Schwartz, Tom Christiansen & Larry Wall
Date: 1999-07-02T01:33:45Z

#

| Chapter 9 Miscellaneous Control Structures |

## 9.4 Labeled Blocks

What if you want to jump out of the block that contains the innermost block, or to put it another way, exit from two nested blocks at once? In C, you'd resort to that much maligned `goto` to get you out. No such kludge is required in Perl; you can use `last`, `next`, and `redo` on any enclosing block by giving the block a name with a label.

A label is yet another type of name from yet another namespace following the same rules as scalars, arrays, hashes, and subroutines. As we'll see, however, a label doesn't have a special prefix punctuation character (like `$` for scalars, `&` for subroutines, and so on), so a label named `print` conflicts with the reserved word `print` and would not be allowed. For this reason, you should choose labels that consist entirely of uppercase letters and digits, which will never be chosen for a reserved word in the future. Besides, using all uppercase stands out better within the text of a mostly lowercase program.

Once you've chosen your label, place it immediately in front of the statement containing the block followed by a colon, like this:

    SOMELABEL: while (condition) {
        statement;
        statement;
        statement;
        if (nuthercondition) {
            last SOMELABEL;
        }
    }

We added `SOMELABEL` as a parameter to `last`. This tells Perl to exit the block named `SOMELABEL`, rather than just the innermost block. In this case, we don't have anything but the innermost block. But suppose we had nested loops:

    OUTER: for ($i = 1; $i <= 10; $i++) {
        INNER: for ($j = 1; $j <= 10; $j++) {
            if ($i * $j == 63) {
                print "$i times $j is 63!\n";
                last OUTER;
                }
            if ($j >= $i) {
                next OUTER;
            }
        }
    }

This set of statements tries all successive values of two small numbers multiplied together until it finds a pair whose product is 63 (7 and 9). Once the pair is found, there's no point in testing other numbers, so the first `if` statement exits both `for` loops using `last` with a label. The second `if` ensures that the bigger of the two numbers will always be the first one by skipping to the next iteration of the outer loop as soon as the condition would no longer hold. This means that the numbers will be tested with (`$i`, `$j`) being (`1`,`1`), (`2`,`1`), (`2`,`2`), (`3`,`1`), (`3`,`2`), (`3`,`3`), (`4`,`1`), and so on.

Even if the innermost block is labeled, the `last`, `next`, and `redo` statements without the optional parameter (the label) still operate with respect to that innermost block. Also, you can't use labels to jump into a block - just out of a block. The `last`, `next`, or `redo` has to be within the block.

9.3 The redo Statement |  | 9.5 Expression Modifiers