Compound Statements

A sequence of statements within a scope[1] is called a block. Sometimes the scope is the entire file, such as a required file or the file containing your main program. Sometimes the scope is a string being evaluated with eval. But generally, a block is surrounded by braces ({}). When we say scope, we mean any of these three. When we mean a block with braces, we'll use the term BLOCK.

Compound statements are built out of expressions and BLOCKs. Expressions are built out of terms and operators. In our syntax descriptions, we'll use the word EXPR to indicate a place where you can use any scalar expression. To indicate an expression evaluated in list context, we'll say LIST.

The following statements may be used to control conditional and repeated execution of BLOCKs. (The LABEL portion is optional.)

if (EXPR) BLOCK
if (EXPR) BLOCK else BLOCK
if (EXPR) BLOCK elsif (EXPR) BLOCK …
if (EXPR) BLOCK elsif (EXPR) BLOCK … else BLOCK

unless (EXPR) BLOCK
unless (EXPR) BLOCK else BLOCK
unless (EXPR) BLOCK elsif (EXPR) BLOCK …
unless (EXPR) BLOCK elsif (EXPR) BLOCK … else BLOCK

LABEL while (EXPR) BLOCK
LABEL while (EXPR) BLOCK continue BLOCK

LABEL until (EXPR) BLOCK
LABEL until (EXPR) BLOCK continue BLOCK

LABEL for (EXPR; EXPR; EXPR) BLOCK

LABEL foreach (LIST) BLOCK
LABEL foreach VAR (LIST) BLOCK
LABEL foreach VAR (LIST) BLOCK continue BLOCK

LABEL BLOCK
LABEL BLOCK continue BLOCK

Note that unlike in C and Java, these are defined in terms of BLOCKs, not statements. This means that the braces are required--no dangling statements allowed. If you want to write conditionals without braces there are several ways to do so. The following all do the same thing:

unless (open(FOO, $foo))    { die "Can't open $foo: $!" }
if (!open(FOO, $foo))       { die "Can't open $foo: $!" }

die "Can't open $foo: $!"   unless open(FOO, $foo);
die "Can't open $foo: $!"   if !open(FOO, $foo);

open(FOO, $foo)             || die "Can't open $foo: $!";
open FOO, $foo              or die "Can't open $foo: $!";

Under most circumstances, we tend to prefer the last pair. These forms come with less eye-clutter than the others, especially the "or die" version. With the || form you need to get used to using parentheses religiously, but with the or version, it doesn't matter if you forget.

But the main reason we like the last versions better is because of how they pull the important part of the statement right up to the front of the line where you'll see it first. The error handling is shoved off to the side so that you don't have to pay attention to it unless you want to.[2] If you tab all your "or die" checks over to the same column on the right each time, it's even easier to read:

chdir $dir                  or die "chdir $dir: $!";
open FOO, $file             or die "open $file: $!";
@lines = <FOO>              or die "$file is empty?";
close FOO                   or die "close $file: $!";


[1] Scopes and namespaces are described in Chapter 2, in Section 2.5.

[2] (Like this footnote.)

Get Programming Perl, 3rd Edition now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.