Perl Crash Course: Control Structures

by André Batosti
revision: Fernando Giorgetti and Vinny Alves

Control Structures are used to control the flow of a program. We are going to see programs that can iterate (loop) or make decisions (conditionals) based on the state of variables.

More interesting possibilities arise when we introduce control structures and looping. Perl supports lots of different kinds of control structures which tend to be like those in C, but are very similar to Pascal, too.


Conditionals

The simplest control structures are the if and unless statements. Its syntax basically follows the rule below:

if ( expression ) {
    instruction1;
    instruction2;
}

Value obtained from “expression”, determines whether it will be considered as true or false. Table below helps you to identify the meaning of values based on how Perl interprets expressions.

ExpressionString/Number?Boolean value
0numberfalse
0.0numberfalse
0.0000numberfalse
“” or ”stringfalse
“0”stringfalse
“0.0”stringtrue
undefN/Afalse
42 – (6 * 7)numberfalse
“0.0” + 0.0numberfalse
“0E0”numbertrue
0E0numberfalse
“foo”stringtrue

Everything in Perl is true, except:

  • the strings “” (the empty string) and “0” (the string containing only the character, 0), or any string expression that evaluates to either “” (the empty string) or “0”.
  • any numeric expression that evaluates to a numeric 0.
  • any value that is not defined (i.e., equivalent to undef).

A very simple example of a real “if statement” would be:

if ( $name ) {
    print "Non empty string";
} 
else {
    print "Empty string";
}

Another example, to illustrate the syntax of the “if” statement:

if ( $money <= 0 ) {
    print "You are out of money";
} 
elsif ( $money > 1000000 ) {
    print "You are a millionaire";
} 
else {
    print "You are probably better than I am";
}

Blocks of code in Perl are enclosed by curly braces {   }. They are always required inside a control structure (except for cases where we use idiomatic ifs – see more below).

Two things to mention:

1 – elsif spelling;
2 – both elsif and else statements are optional.

Another conditional statement we need to mention is the unless. Its meaning is the opposite of an if statement. It will only execute a block of code if expression is NOT true.

Let’s look at an example:

if  ( $num == 10 ) { #Usual if statement
    print "Number is equal to 10";
} else {
    print "Number not equal to 10";
}

# Unless statement that will execute the block of code below 
# if number's value is not 10 (same thing as the else statement above)

unless ( $num == 10 ) {
    print "Number not equal to 10";
}
else {
    print "Number is equal to 10";
}

Action based on statement test

You can test a single statement and perform a pre-defined action in case it is true or another one if statement is false.

For example:

    print "You are a man" if ($gender eq "M"); # parentheses are optional here, since only one expression is evaluated



Ternary or Trinary Operator

Like many other programming languages, Perl offers the ternary (aka trinary) operator “?:” which behaves just like if/elsif/else:

print "You are a " . (($gender eq "M") ? "man" : "woman") . "n";
# read: if $gender eq "M" then "man" else "woman"

# or perhaps
($birthday == $today) ? print "Happy birthday!" : print "Have a good day";

Mimmic elsif this way:

$month = (localtime)[4]; # fifth element of localtime in list context returns month, base 0;

print "The month is now " . 
($month == 0) ? "January" :
($month == 1) ? "February" :
($month == 3) ? "March" :
                      "something other than Jan, Feb, or March";

Operators

Initially we will introduce the testing operators. They rely on a test being considered as true or false. Following you can see a few examples:

$a == $b                      # Is $a numerically equal to $b?
# Beware: Don't use the = operator.
$a != $b                       # Is $a numerically unequal to $b?
$a eq $b                       # Is $a string-equal to $b?
$a ne $b                       # Is $a string-unequal to $b?

Perl also supports the logical operators “OR” and “AND”. The “OR” operator is represented by the “||” characters while the “AND” is represented by “&&” characters.

Lets go through a few examples:

# If value of number is greater than 10 or lesser than 5
if ( ( $num > 10 ) || ( $num < 5 ) ) {
    ...
}

# If language is equal to "perl" and num is 10, or, if num is 0 (or has a "false" value)
if ( (( $language eq "perl" ) && ( $num == 10 )) || !( $num ) ) {
    ...
}

Loops

We have several statements to perform iterations using Perl. Perl supports: while, until, do ... while, for and foreach statements.

While

Performs the iteration while the given expression is true. Syntax:

while (expression) {
    instruction1;
    instruction2;
    ...
}

Until

It is the opposite of while. So take it as, in example:

while (!(expression)) {
    instruction1;
    instruction2;
}

#same as
until (expression) {
   instruction1;
   instruction2;
}

Do .. While

Its functionality is almost the same as for the normal “while” statement, but with this kind of control structure you guarantee that the block of code will be executed at least once.

do {
    instruction1;
    instruction2;
} while (expression);

For

It’s a C like style. Syntax:

for (initialize; expression; increment/decrement) {
    instruction1;
    instruction2;
    ...
}
  • The initialize statement is basically used to initialize the variable that will be used on the test statement. It can also be used anywhere in the block. Declare it with my to keep it private to the for block;
  • Expression follows the same rule for if or while. It will be tested, and if its return is true, block code will be executed;
  • Increment/decrement is then executed

Real example:

for ($i = 0; $i < 10; $i++ ) {
    printf "Iteration number: %sn", $i;
}

Another good example (not using a numeric expression):

for ( @names = ('John', 'Paul', 'Roger', 'David'); @names; shift(@names) ) {
    print "$names[0]n";
}

# Or work on 2 expressions at the same time
for ($i = 0, $j = 10; $i<=10,$j>=0; $i++, $j--) {
    print "$i    $jn";
}

# Or kick off an infinite loop
for ( ; ; ) {
    instruction1;
    instruction2;
}

Foreach

It is another control structure that allows iteration, but here you can iterate over an array.

Following you can see a few examples of it:

@names = ('John', 'Paul', 'Roger', 'David');

#Passing through all names
foreach $name (@names) {
    printf "%sn", $name;
}

The scalar variable is optional to the foreach statement. So you can bypass it by doing:

@names = ('John', 'Paul', 'Roger', 'David');

#Passing through all names
foreach (@names) {
    printf "%sn", $_;
}

If you don’t specify a scalar variable to get each iteration, then the default scalar ($_) will be used. Note that for can also be used as a synonym to foreach – same exact functionality, but without the each portion of the word.

Loop flow control

We have a few special commands to help us controlling the flow under a loop statement. Here we go.

last

It is similar to the “break” statement used on C programming language (as well as in several others). Tells Perl to skip the current loop statement, or even, to skip a labeled loop statement. Take a look at the example below:

@names = ('fernando', 'smith', 'Mark', 'John');
foreach (@names) {
    last if $_ eq "John";
    print "Name is " . $_ . "n";
}

next

next has the same function as the “continue” loop statement used in C. Used to force your loop statement to go to the next iteration. In example:

@names = ('fernando', 'smith', 'Mark', 'John');
foreach (@names) {
    next if $_ eq "smith";
    print "Name is " . $_ . "n";
}

The example above will just force the “foreach” statement to read next iteration once “smith” is the value read from the “names” array.

If you need to work on multiple levels of loops, you can tell next and last which named block to work on:

LINE: while () {
	next LINE if /^#/;	# discard comments
	...
}

« Basic Regular Expressions | TOC | Basic I/O »

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.