[Chapter 9] Miscellaneous Control Structures
Author: Randal L. Schwartz, Erik Olson & Tom Christiansen
Date: 1999-07-02T01:34:08Z

#

| Chapter 9 |

# 9. Miscellaneous Control Structures

Contents:
The last Statement
The next Statement
The redo Statement
Labeled Blocks
Expression Modifiers
&&, ||, and ?: as Control Structures
Exercises

## 9.1 The last Statement

In some of the previous exercises, you may have thought, "if I just had a C `break` statement here, I'd be done." Even if you didn't think that, let me tell you about Perl's equivalent for getting out of a loop early: the `last` statement.

The `last` statement breaks out of the innermost enclosing loop block,[1] causing execution to continue with the statement immediately following the block. For example:

> [1] Note that the `do {} while/until` construct does not count as a loop for purposes of `next`, `last`, and `redo`.

    while (something) {
            something;
            something;
            something;
            if (somecondition) {
                somethingorother;
                somethingorother;
                last; # break out of the while loop
            }
            morethings;
            morethings;
    }
    # last comes here

If `somecondition` is true, the `somethingorother`s are executed, and then the `last` forces the `while` loop to terminate.

The `last` statement counts only looping blocks, not other blocks that are needed to make up some syntactic construct. As a result, the blocks for the `if` and `else` statement, as well as the one for a `do` `{}` `while/until`, do not count; only the blocks that make up the `for`, `foreach`, `while`, `until`, and "naked" blocks count. (A naked block is a block that is not otherwise part of a larger construct, such as a loop, subroutine, or `if`/`then`/`else` statement.)

Suppose we wanted to see whether a mail message that had been saved in a file was from Erik. Such a message might look like:

    From: eriko@axtech.com (Erik Olson)
    To: rdenn@ora.com
    Date: 01-MAY-97 08:16:24 PM MDT -0700
    Subject: A sample mail message

    Here's the body of the mail message. And
    here is some more.

We'd have to look through the message for a line that begins with `From:`, and then notice whether the line also contains the login name, `eriko`.

We could do it this way:

    while (<STDIN>) {           # read the input lines
             if (/^From: /) {   # does it begin with From:? If yes...
                 if (/eriko/) { # it's from Erik!
                     print "Email from Erik! It's about time!\n";
                 }
                 last;          # no need to keep looking for From:, so exit
             }                  # end "if from:"
             if (/^$/) {        # blank line?
                 last;          # if so, don't check any more lines
             }
    }                           # end while

After the line starting with `From:` is found, we exit the main loop because we want to see only the first `From:` line. Also, because a mail message header ends at the first blank line, we can exit the main loop there as well.

8.8 Exercises |  | 9.2 The next Statement