Chapter 6

Statements


CONTENTS

If you look at a Perl program from a very high level, it is made of statements. Statements are a complete unit of instruction for the computer to process. The computer executes each statement it sees-in sequence-until a jump or branch is processed.

Statements can be very simple or very complex. The simplest statement is this


123;

which is a numeric literal followed by a semicolon. The semicolon is very important. It tells Perl that the statement is complete. A more complicated statement might be


$bookSize = ($numOfPages >= 1200 ? "Large" : "Normal");

which says if the number of pages is 1,200 or greater, then assign "Large" to $bookSize; otherwise, assign "Normal" to $bookSize.

In Perl, every statement has a value. In the first example, the value of the statement is 123. In the second example, the value of the statement could be either "Large" or "Normal" depending on the value of $numOfPages. The last value that is evaluated becomes the value for the statement.

Like human language in which you put statements together from parts of speech-nouns, verbs, and modifiers-you can also break down Perl statements into parts. The parts are the literals, variables, and functions you have already seen in the earlier chapters of this book.

Human language phrases-like, "walk the dog"-also have their counterparts in computer languages. The computer equivalent is an expression. Expressions are a sequence of literals, variables, and functions connected by one or more operators that evaluate to a single value-scalar or array. An expression can be promoted to a statement by adding a semicolon. This was done for the first example earlier. Simply adding a semicolon to the literal made it into a statement that Perl could execute.

Expressions may have side effects, also. Functions that are called can do things that are not immediately obvious (like setting global variables) or the pre- and post-increment operators can be used to change a variable's value.

Let's take a short diversion from our main discussion about statements and look at expressions in isolation. Then we'll return to statements to talk about statement blocks and statement modifiers.

Understanding Expressions

You can break the universe of expressions up into four types:

Simple expressions consist of a single literal or variable. Table 6.1 shows some examples. Not much can be said about these expressions because they are so basic. It might be a matter for some debate whether or not an array or associative array variable can be considered a simple expression. My vote is yes, they can. The confusion might arise because of the notation used to describe an array or associative array. For example, an array can be specified as (12, 13, 14). You can see this specification as three literal values surrounded by parentheses or one array. I choose to see one array which fits the definition of a simple expression-a single variable.

Table 6.1  The Simplest Perl Expressions

Simple ExpressionDescription
123 Integer literal
Chocolate is great! String literal
(1, 2, 3) Array literal
$numPages Variable

Simple expressions with side effects are the next type of expression we'll examine. A side effect is when a variable's value is changed by the expression. Side effects can be caused using any of the unary operators: +, -, ++, --. These operators have the effect of changing the value of a variable just by the evaluation of the expression.No other Perl operators have this effect-other than the assignment operators, of course. Function calls can also have side effects- especially if local variables were not used and changes were made to global variables. Table 6.2 shows examples of different side effects.

Table 6.2  Perl Expressions with Side Effects

Simple ExpressionDescription
$numPages++ Increments a variable
++$numPages Increments a variable
chop($firstVar) Changes the value of $firstVar-a global variable
sub firstsub { $firstVar = 10; } Also changes $firstVar

Note that when the expressions $numPages++ and ++$numPages are evaluated, they have the same side effect even though they evaluate to different values. The first evaluates to $numPages, and the second evaluates to $numPages + 1. The side effect is to increment $numPages by 1.

The firstsub() function shown in Table 6.2 changes the value of the $firstVar variable, which has a global scope. This can also be considered a side effect, especially if $firstVar should have been declared as a local variable.

Simple expressions with operators are expressions that include one operator and two operands. Any of Perl's binary operators can be used in this type of expression. Table 6.3 shows a few examples of this type of expression.

Table 6.3  Perl Expressions with Operators

Simple ExpressionDescription
10 + $firstVar Adds ten to $firstVar
$firstVar . "AAA" Concatenates $firstVar and "AAA"
"ABC" x 5 Repeats "ABC" five times

Another way of viewing 10 + $firstVar is as simple expression plus simple expression. Thus, you can say that a simple expression with an operator is defined as two simple expressions connected by an operator. When computer programmers define something in terms of itself, we call it recursion. Each time a recursion is done, the expression is broken down into simpler and simpler pieces until the computer can evaluate the pieces properly.

A complex expression can use any number of literals, variables, operators, and functions in any sequence. Table 6.4 shows some complex expressions.

Table 6.4  Complex Perl Expressions

Complex Expression
(10 + 2) + 20 / (5 ** 2)
20 - (($numPages - 1) * 2)
(($numPages++ / numChapters) * (1.5 / log(10)) + 6)

There is an infinite number of expressions you can form with the Perl operator set. You can get extremely complicated in your use of operators and functions if you are not careful. I prefer to keep the expressions short, easy to document, and easy to maintain.

Tip
Sometimes it is difficult to tell whether you have enough closing parentheses for all of your opening parentheses. Starting at the left, count each open parenthesis, and when you find a closing parenthesis, subtract one from the total. If you reach zero at the end of the expression, the parentheses are balanced.

Now we'll go back to looking at statements.

Statement Blocks

A statement block is a group of statements surrounded by curly braces. Perl views a statement block as one statement. The last statement executed becomes the value of the statement block. This means that any place you can use a single statement-like the map function-you can use a statement block. You can also create variables that are local to a statement block. So, without going to the trouble of creating a function, you can still isolate one bit of code from another.

Here is how I frequently use a statement block:


$firstVar = 10;

{

    $secondVar >>= 2;

    $secondVar++;

}

$thirdVar = 20;

The statement block serves to emphasize that the inner code is set apart from the rest of the program. In this case, the initialization of $secondVar is a bit more complex than the other variables. Using a statement block does not change the program execution in any way; it simply is a visual device to mark sections of code and a way to create local variables.

Statement Blocks and Local Variables

Normally, it's a good idea to place all of your variable initialization at the top of a program or function. However, if you are maintaining some existing code, you may want to use a statement block and local variables to minimize the impact of your changes on the rest of the code-especially if you have just been handed responsibility for a program that someone else has written.

You can use the my() function to create variables whose scope is limited to the statement block. This technique is very useful for temporary variables that won't be needed elsewhere in your program. For example, you might have a complex statement that you'd like to break into smaller ones so that it's more understandable. Or you might want to insert some print statements to help debug a piece of code and need some temporary variables to accommodate the print statement.

Assign ten to $firstVar.
Start the statement block.
Create a local version of
$firstVar with a value of A.
Print
$firstVar repeated five times.
End the statement block.
Print the global
$firstVar.

$firstVar = 10;

{

   my($firstVar) = "A";

   print $firstVar x 5 . "\n";



}

print("firstVar = $firstVar\n");

This program displays:


AAAAA

firstVar = 10

You can see that the value of $firstVar has been unchanged by the statement block even though a variable called $firstVar is used inside it. This shows that the variable used inside the statement block does indeed have a local scope.

Tip
Statement blocks are also good to use when you temporarily need to send debugging output to a file. Then, when all the bugs have been found and the need for debugging is over, you can remove the statement block quickly and easily because all the code is in one spot.

Statement Types

Just as there were several types of expressions, there are also several types of statements. Table 6.5 lists seven different types of statements.

Table 6.5  Perl Statement Types

Statement TypeDescription
No-action statementsThese statements evaluate a value but perform no actions.
Action statementsThese statements perform some action.
Assignment statementsThese statements assign a value to one or more variables. They are discussed, along with the assignment operator, in Chapter 4 "Operators."
Decision statementsThese statements allow you to test a condition and choose among one or more actions. Decision statements are discussed in Chapter 7 "Control Statements."
Jump statementsThese statements let you unconditionally change the program flow to another point in your code. For instance, you could use the redo keyword to send your program flow back to the beginning of a statement block. Jump statements are discussed in Chapter 7 "Control Statements."
Loop statementsThese statements let you perform a series of statements repeatedly while some condition is true or until some condition is true. Loop statements are discussed in Chapter 7 "Control Statements."
Modified StatementsThese statements let you use the if, unless, until, and while keywords to change the behavior of a statement.

Note
A keyword is a word that is reserved for use by Perl. These words (if, elsif, else, while, unless, until, for, foreach, last, next, redo, and continue) are integral to the language and provide you with the ability to control program flow.

No-action statements are evaluated by Perl and have a value but perform no actions. For instance, the Perl statement 10 + 20; has a value of 30, but because no variables were changed, no work was done. The value of 20 is not stored anywhere, and it is quickly forgotten when the next statement is seen.

What good is a no-action statement if no work is done? A lot of Perl programmers use these simple statements as return values in functions. For instance:


sub firstSub {

    doSomething();

    condition == true ? "Success" : "Failure";

}

Because Perl returns the value of the last evaluated statement when leaving a function, you can use no-action statements to let Perl know what value should be returned to the main program. Notice that even though the ternary operator was used, because there are no function calls or unary operators, no work can be done.

Note
I still like to use the return() function to explicitly identify the return values. The previous example looks like this when using the return() function:


sub firstSub {

    doSomething();

    return(condition == true ? "Success" : "Failure");

}

Action statements use expressions to perform some task. They can increment or decrement a variable and call a function.

Modified statements use expressions in conjunction with a modifying keyword to perform some action. There are four modifying keywords: if, unless, until, and while. The basic syntax of a modified statement is


EXPRESSION modifier (CONDITION);

Let's look at some examples of modified statements.

Example: Using the if Modifier

The if modifier tells Perl that the expression should be evaluated only if a given condition is true. The basic syntax of a modified statement with the if modifier is


EXPRESSION if (CONDITION);

This is a compact way of saying


if (CONDITION) {

    EXPRESSION;

}

Let's prove that the if modifier works. Here's an example showing that the if modifier can prevent the evaluation of an expression.

Initialize the $firstVar and $secondVar variables to 20.
Increment
$firstVar if and only if $secondVar is equal to 10.
Print the values of
$firstVar and $secondVar.

$firstVar  = 20;

$secondVar = 20;



$firstVar++ if ($secondVar == 10);



print("firstVar  = $firstVar\n");

print("secondVar = $secondVar\n");

This program prints:


firstVar  = 20

secondVar = 20

The program doesn't increment $firstVar because the value of $secondVar is 20 at the time the condition is evaluated. If you changed the 10 to a 20 in the condition, Perl would increment $firstVar.

You can find out about the if statement-as opposed to the if modifier-in Chapter 7 "Control Statements."

Note
The condition expression can be as complex as you'd like. However, I believe that one of the goals of statement modifiers is to make programs easier to read and understand. Therefore, I use modifiers only with simple conditions. If complex conditions need to be met before an expression should be evaluated, using the if keyword is probably a better idea.

Example: Using the unless Modifier

The unless modifier is the opposite of the if modifier. This modifier evaluates an expression unless a condition is true. The basic syntax of a modified statement with the unless modifier is


EXPRESSION unless (CONDITION);

This is a compact way of saying


if (! CONDITION) {

    EXPRESSION;

}

This modifier helps to keep program code clearly understandable because you don't have to use the logical not operator to change the value of a condition so you can evaluate an expression. Let's look back at the example from a moment ago.

Initialize the $firstVar and $secondVar variables to 20.
Increment
$firstVar unless $secondVar is equal to 10.
Print the values of
$firstVar and $secondVar.

$firstVar  = 20;

$secondVar = 20;



$firstVar++ unless ($secondVar == 10);



print("firstVar  = $firstVar\n");

print("secondVar = $secondVar\n");

This program prints:


firstVar  = 21

secondVar = 20

If you were limited to using only the if modifier, the modified statement would read


$firstVar++ if ($secondVar != 10);

The unless modifier is more direct. All things being equal, the concept of $secondVar being equal to 10 is easier to grasp than the concept of $secondVar not being equal to 10. Of course, this is a trivial example. Let's look at something more substantial before we move on.

One of the drawbacks of associative arrays is that they quietly redefine the value of any key when that key is assigned a new value, thereby losing the old value. If you are reading from a list of key-value pairs, this might not be the behavior you need. The unless modifier can be used to prevent element assignment if the key has already been used. Listing 6.1 shows the unless modifier used in a program.

Call the assignElement() function to create two elements in the @array associative array.
Call the
printArray() function.
Try to redefine the value associated with the "A" key by calling
assignElement().
Print the array again to verify that no elements have changed.

Listing 6.1  06LST01.PL-Using the unless Modifier to Control Array Element Assignment

assignElement("A", "AAAA");

assignElement("B", "BBBB");

printArray();

assignElement("A", "ZZZZ");

printArray();





sub assignElement {

    my($key, $value) = @_;



    $array{$key} = $value unless defined($array{$key});

}



sub printArray {

    while (($key, $value) = each(%array)) {

        print("$key = $value\n");

    }

    print("\n");

}


This program displays:


A = AAAA

B = BBBB



A = AAAA

B = BBBB

These lines of code should look a little familiar to you. The while loop in the printArray() function was used in a Chapter 5example. The assignElement() function will make an assignment unless a key-value pair with the same key already exists. In that case, the assignment statement is bypassed.

Example: Using the until Modifier

The until modifier is a little more complex than the if or unless modifiers. It repeatedly evaluates the expression until the condition becomes true. The basic syntax of a modified statement with the until modifier is


EXPRESSION until (CONDITION);

This is a compact way of saying


until (CONDITION) {

    EXPRESSION;

}

The expression is evaluated only while the condition is false. If the condition is true when the statement is encountered, the expression will never be evaluated. The following example proves this:

Initialize $firstVar to 10.
Repeatedly evaluate
$firstVar++ until the condition $firstVar > 2 is true.
Print the value of
$firstVar.

$firstVar = 10;

$firstVar++ until ($firstVar > 2);



print("firstVar = $firstVar\n");

This program displays:


firstVar = 10

This shows that the expression $firstVar++ was never executed because the condition was true the first time it was evaluated. If it had been executed, the value of $firstVar would have been 11 when printed. In this case, the until modifier worked exactly like the unless modifier.

However, when the condition is false for the first evaluation, Perl executes the expression repeatedly until the condition is true. Here is an example:

Initialize $firstVar to 10.
Repeatedly evaluate
$firstVar++ until the condition $firstVar > 20 is true.
Print the value of
$firstVar.

$firstVar = 10;

$firstVar++ until ($firstVar > 20);



print("firstVar = $firstVar\n");

This program displays:


firstVar = 21

In this case, the $firstVar++ expression is executed 11 times. Each execution of the expression increments the value of $firstVar. When $firstVar is equal to 21, the statement ends because 21 is greater than 20, which means that the condition is true.

You can find out about the until statement-as opposed to the until modifier-in Chapter 7 "Control Statements."

Example: Using the while Modifier

The while modifier is the opposite of the until modifier. It repeatedly evaluates the expression while the condition is true. When the condition becomes false, the statement ends. The basic syntax of a modified statement with the while modifier is


EXPRESSION while (CONDITION);

This is a compact way of saying


while (CONDITION) {

    EXPRESSION;

}

The expression is evaluated only while the condition is true. If the condition is false when the statement is encountered, the expression will never be evaluated. Here is an example using the while modifier.

Initialize $firstVar to 10.
Repeatedly evaluate
$firstVar++ while the condition $firstVar < 20 is true.
Print the value of
$firstVar.

$firstVar = 10;

$firstVar++ while ($firstVar < 20);



print("firstVar = $firstVar\n");

This program displays:


firstVar = 21

You can compare this example directly to the last example given for the until modifier. Because the until modifier is the opposite of the while modifier, the operators in the conditions are also opposite in nature.

You can find out about the while statement-as opposed to the while modifier-in Chapter 7 "Control Statements."

Summary

This chapter discussed Perl statements and how they are built from expressions. You read about four types of expressions: simple, simple with side effects, simple with operators, and complex.

Next, you read about statement blocks. These program constructs are good to logically isolate one block of statements from the main program flow. You can also use statement blocks and the my() function to create local variables. This is mainly done for debugging reasons or to make small program changes that are guaranteed not to affect other portions of the program.

Then, seven types of statements were mentioned: no-action, action, assignment, decision, jump, loop, and modified. This chapter described no-action, action, and modified statements. Assignment statements were mentioned in Chapter 3"Variables" and again in Chapter 4 "Operators." Decision, jump, and loop statements are covered in Chapter 7 "Control Statements."

Modified statements use the if, unless, until, and while keywords to affect the evaluation of an expression. The if keyword evaluates an expression if a given condition is true. The unless keyword does the opposite: the expression is evaluated if a given condition is false. The until keyword repeatedly evaluates an expression until the condition is true. The while keyword is the opposite of until so that it repeatedly evaluates an expression until the condition is false.

The next chapter, "Control Statements," explores the decision, jump, and loop statements in detail.

Review Questions

Answers to Review Questions are in Appendix A.

  1. What is an expression?
  2. What is a statement?
  3. What are the four statement modifiers?
  4. What are two uses for statement blocks?
  5. What can non-action statements be used for?
  6. How is the if modifier different from the unless modifier?
  7. What will the following code display?

$firstVar = 10;

$secondVar = 20;



$firstVar += $secondVar++ if ($firstVar > 10);



print("firstVar = $firstVar\n");

print("firstVar = $secondVar\n");

Review Exercises

  1. Write a simple expression that uses the exponentiation operator.
  2. Write a complex expression that uses three operators and one function.
  3. Write a Perl program that uses a statement block inside a function call.
  4. Use the statement block from the previous exercise to create local variables.
  5. Write a Perl program that shows if the expression clause of a while modified statement will be evaluated when the condition is false.