Chapter 2

Basic Operators and Control Flow


CONTENTS

Today's lesson gives you the information you need to write some simple Perl programs. You'll learn the following:

Storing in Scalar Variables Assignment

In yesterday's lesson, you saw the following statement, which assigns a line of input from the keyboard to the variable $inputline:


$inputline = <STDIN>;

This section tells you more about variables such as $inputline and how to assign values to these variables.

The Definition of a Scalar Variable

The variable $inputline is an example of a scalar variable. A scalar variable stores exactly one item-a line of input, a piece of text, or a number, for example. Items that can be stored in scalar variables are called scalar values.

You'll learn more about scalar values on Day 3, "Understanding Scalar Values." For today, all you need to remember is that a scalar variable stores exactly one value, which is a scalar value.

Scalar Variable Syntax

The name of a scalar variable consists of the character $ followed by at least one letter, which is followed by any number of letters, digits, or underscore characters (that is, the _ character).

The following are examples of legal scalar variable names:


$x

$var

$my_variable

$var2

$a_new_variable

These, however, are not legal scalar variable names:


variable        # the $ character is missing

$               # there must be at least one letter in the name

$47x            # second character must be a letter

$_var           # again, the second character must be a letter

$variable!      # you can't have a ! in a variable name

$new.var        # you can't have a . in a variable name

Perl variables are case-sensitive. This means that the following variables are different:


$VAR

$var

$Var

Your variable name can be as long as you want.


$this_is_a_really_long_but_legal_name

$this_is_a_really_long_but_legal_name_that_is_different

The $ character is necessary because it ensures that the Perl interpreter can distinguish scalar variables from other kinds of Perl variables, which you'll see on later days.

TIP
Variable names should be long enough to be self-explanatory but short enough to be easy to read and type.

Assigning a Value to a Scalar Variable

The following statement contains the Perl assignment operator, which is the = character:


$inputline = <STDIN>;

Remember that this statement tells Perl that the line of text read from the standard input file, represented by <STDIN>, is to become the new value of the scalar variable $inputline.

You can use the assignment operator to assign other values to scalar variables as well. For example, in the following statement, the number 42 is assigned to the scalar variable $var:


$var = 42;

A second assignment to a scalar variable supersedes any previous assignments. In these two statements:


$var = 42;

$var = 113;

the old value of $var, 42, is destroyed, and the value of $var becomes 113.

Assignment statements can assign text to scalar variables as well. Consider the following statement:


$name = "inputdata";

In this statement, the text inputdata is assigned to the scalar variable $name.

Note that the quotation marks (the " characters) on either end of the text are not part of the text assigned to $name. This is because the " characters are just there to enclose the text.

Spaces or tabs contained inside the pair of " characters are treated as part of the text:


$name = "John Q Hacker";

Here, the spaces on either side of the Q are considered part of the text.

In Perl, enclosed text such as John Q Hacker is known as a character string, and the surrounding " characters are an example of string delimiters. You learn more about character strings on Day 3; for now, all you need to know is that everything inside the " characters is treated as a single unit.

Performing Arithmetic

As you've seen, the assignment operator = takes the value to the right of the = sign and assigns it to the variable on the left of the =:


$var = 42;

Here, the value 42 is assigned to the scalar variable $var.

In Perl, the assignment operator is just one of many operators that perform tasks, or operations. Each operation consists of the following components:

This might sound a little confusing, but it's really quite straightforward. To illustrate, Table 2.1 lists some of the basic arithmetic operators that Perl supports.

Table 2.1. Basic arithmetic operators.

Operator
Operation
+
Addition
-
Subtraction
*
Multiplication
/
Division

You use these operators in the same way you use +, -, and so on when you do arithmetic on paper. For example, the following statement adds 17 and 5 and then assigns the result, 22, to the scalar variable $var:


$var = 17 + 5;

You can perform more than one arithmetic operation in a single statement like this one, which assigns 19 to $var:


$var = 17 + 5 - 3;

You can use the value of a variable in an arithmetic operation, as follows:


$var1 = 11;

$var2 = $var1 * 6;

The second statement takes the value currently stored in $var1, 11, and multiplies it by 6. The result, 66, is assigned to $var2.

Now examine the following statements:


$var = 11;

$var = $var * 6;

As you can see, $var appears twice in the second statement. What Perl does in this case is straightforward:

  1. The first statement assigns the value 11 to $var.
  2. In the second statement, the Perl interpreter retrieves the current value of $var, 11, and multiplies it by 6, producing the result 66.
  3. This result, 66, is then assigned to $var (destroying the old value, 11).

As you can see, there is no ambiguity. Perl uses the old value of $var in the arithmetic operation, and then it assigns the result of the operation to $var.

NOTE
Perl always performs multiplication and division before addition and subtraction-even if the addition or subtraction operator appears first. Perl does this to conform to the rules of arithmetic. For example, in the following statement:
$var = 5 + 6 * 4;
$var is assigned 29: 6 is multiplied by 4, and then 5 is added to the result

Example of Miles-to-Kilometers Conversion

To see how arithmetic operators work, look at Listing 2.1, which performs a simple miles-to-kilometers and kilometers-to-miles conversion.


Listing 2.1. Miles-to-kilometers converter.

1:  #!/usr/local/bin/perl

2:  

3:  print ("Enter the distance to be converted:\n");

4:  $originaldist = <STDIN>;

5:  chop ($originaldist);

6:  $miles = $originaldist * 0.6214;

7:  $kilometers = $originaldist * 1.609;

8:  print ($originaldist, " kilometers = ", $miles,

9:         " miles\n");

10: print ($originaldist, " miles = ", $kilometers,

11:        " kilometers\n");



$ program2_1

Enter the distance to be converted:

10

10 kilometers = 6.2139999999999995 miles

10 miles = 16.09 kilometers

$

Line 3 of this program asks for a distance to convert. To do this, it prints the following text on your screen


Enter the distance to be converted:

Note that the \n at the end of the text is not printed. The \n is a special sequence of characters that represents the newline character; when the print library function sees \n, it starts a new line of output on your screen. (You'll learn more about special sequences of characters such as \n on Day 3.)

At this point, you can enter any number you want in response to the program's request for a distance. The input/output example shows an entry of 10.

Line 4 retrieves the line of input you entered and then assigns it to the variable named $originaldist.

Line 5 calls the library function chop, which gets rid of the closing newline character that is part of the input line you entered. The chop library function is described in the following section, "The chop Library Function."

Line 6 determines the number of miles that is equivalent to 10 kilometers and assigns this number to the variable $miles.

Line 7 determines the number of kilometers that is equivalent to 10 miles and assigns this number to the variable $kilometers.

Lines 8-11 print the values of the variables $miles and $kilometers.

NOTE
Different machines handle floating-point numbers (numbers containing a decimal point) in different ways. Because of this, the numbers displayed in your Listing 2.1 output might not be exactly the same as the numbers shown here. These minor differences will appear whenever a floating-point number is printed.
For more information on difficulties with floating-point numbers, refer to the discussion of round-off errors on Day 3, "Understanding Scalar Values.

The chop Library Function

The program shown in Listing 2.1 calls a special library function, chop. This function assumes that a line of text is stored in the variable passed to it; chop's job is to delete the character at the right end of the line of text. Consider this example:


$line = "This is my line";

chop ($line);

After chop is called, the value of $line becomes


This is my lin

Here's why Listing 2.1 uses chop. The statement


$originaldist = <STDIN>;

assigns a line of input from the standard input file to the variable $originaldist. When you type 10 and press Enter, the line of input assigned to $originaldist consists of three characters: the 1, the 0, and a newline character. When chop is called, the newline character is removed, and $originaldist now contains the value 10, which can be used in arithmetic operations.

You'll learn more about using lines of input in arithmetic operations and about conversions from lines of input to numbers on Day 3. For now, just remember to call chop after reading a number from the standard input file.


$originaldist = <STDIN>;

chop ($originaldist);

Expressions

Now that you know a little more about operators, operands, and how they both work, it's time to learn some more terminology as well as the details about exactly what Perl is doing when it evaluates operators such as the arithmetic operators and the assignment operator.

In Perl, a collection of operators and operands is known as an expression. Each expression yields a result, which is the value you get when the Perl interpreter evaluates the expression (that is, when the Perl interpreter performs the specified operations). For example, in the simple expression


4 * 5

the result is 20, or 4 times 5.

You can think of an expression as a set of subordinate expressions. Consider this example:


4 * 5 + 3 * 6

When the Perl interpreter evaluates this expression, it first evaluates the subexpressions 4 * 5 and 3 * 6, yielding the results 20 and 18. These results are then (effectively) substituted for the subexpressions, leaving the following:


20 + 18

The Perl interpreter then performs the addition operation, and the final result of the expression is 38.

Consider the following statement:


$var = 4 * 5 + 3;

As you can see, the Perl interpreter multiplies 4 by 5, adds 3, and assigns the result, 23, to $var. Here's what the Perl interpreter is doing, more formally, when it evaluates this expression ($var = 4 * 5 + 3):

  1. The subexpression 4 * 5 is evaluated, yielding the result 20. The expression being evaluated is now
    $var = 20 + 3
    because the multiplication operation has been replaced by its result.
  2. The subexpression 20 + 3 is evaluated, yielding 23. The expression is now
    $var = 23
  3. Finally, the value 23 is assigned to $var.

Here's one more example, this time using the value of a variable in an expression:


$var1 = 15;

$var2 = $var1 - 11;

When the Perl interpreter evaluates the second expression, it does the following:

  1. It retrieves the value currently stored in $var1, which is 15, and replaces the variable with its value. This means the expression is now
    $var2 = 15 - 11
    and $var1 is out of the picture.
  2. The Perl interpreter performs the subtraction operation, yielding
    $var2 = 4
  3. $var2 is thus assigned the value 4.

NOTE
An expression and a statement are two different things. A statement, however, can contain a Perl expression. For example, the statement
$var2 = 4;
contains the Perl expression
$var2 = 4
and is terminated by a semicolon (;).
The distinction between statements and expressions will become clearer when you encounter other places where Perl statements use expressions. For example, expressions are used in conditional statements, which you'll see later today.

Assignments and Expressions

The assignment operator, like all Perl operators, yields a result. The result of an assignment operation is the value assigned. For example, in the expression


$var = 42

the result of the expression is 42, which is the value assigned to $var.

Because the assignment operator yields a value, you can use more than one assignment operator in a single expression:


$var1 = $var2 = 42;

In this example, the subexpression


$var2 = 42

is performed first. (You'll learn why on Day 4, "More Operators," in the lesson about operator precedence.) The result of this subexpression is 42, and the expression is now


$var1 = 42

At this point, 42 is assigned to $var1.

Other Perl Operators

So far, you have encountered the following Perl operators, which are just a few of the many operators Perl supports:

You'll learn about additional Perl operators on Day 4.

Introduction to Conditional Statements

So far, the Perl programs you've seen have had their statements executed in sequential order. For example, consider the kilometer-to-mile conversion program you saw in Listing 2.1:


#!/usr/local/bin/perl



print ("Enter the distance to be converted:\n");

$originaldist = <STDIN>;

chop ($originaldist);

$miles = $originaldist * 0.6214;

$kilometers = $originaldist * 1.609;

print ($originaldist, " kilometers = ", $miles,

       " miles\n");

print ($originaldist, " miles = ", $kilometers,

       " kilometers\n");

When the Perl interpreter executes this program, it starts at the top of the program and executes each statement in turn. When the final statement is executed, the program is terminated.

All the statements in this program are unconditional statements-that is, they always are executed sequentially, regardless of what is happening in the program. In some situations, however, you might want to have statements that are executed only when certain conditions are true. These statements are known as conditional statements.

Perl supports a variety of conditional statements. In the following sections, you'll learn about these conditional statements:

StatementDescription
ifExecutes when a specified condition is true.
if-elseChooses between two alternatives.
if-elsif-else Chooses between more than two alternatives.
While and untilRepeats a group of statements a specified number of times.

Perl also has other conditional statements, which you'll learn about on Day 8, "More Control Structures."

The if Statement

The if statement is the simplest conditional statement used in Perl. The easiest way to explain how the if statement works is to show you a simple example:


if ($number) {

        print ("The number is not zero.\n");

}

The if statement consists of (closing brace character):

This statement consists of two parts:

The first part is known as a conditional expression; the second part is a set of one or more statements called a statement block. Let's look at each part in detail.

The Conditional Expression

The first part of an if statement-the part between the parentheses-is the conditional expression associated with the if statement. This conditional expression is just like any other expression you've seen so far; in fact, you can use any legal Perl expression as a conditional expression.

When the Perl interpreter sees a conditional expression, it evaluates the expression. The result of the expression is then placed in one of two classes:

The Perl interpreter uses the value of the conditional expression to decide whether to execute the statements between the { and } characters. If the conditional expression is true, the statements are executed. If the conditional expression is false, the statements are not executed.

In the example you have just seen,


if ($number) {

        print ("The number is not zero.\n");

}

the conditional expression consists of the value of the variable $number. If $number contains something other than zero, the conditional expression is true, and the statement


print ("The value is not zero.\n");

is executed. If $number currently is set to zero, the conditional expression is false, and the print statement is not executed.

Listing 2.2 is a program that contains this simple if statement.


Listing 2.2. A program containing a simple example of an if statement.

1:  #!/usr/local/bin/perl

2:  

3:  print ("Enter a number:\n");

4:  $number = <STDIN>;

5:  chop ($number);

6:  if ($number) {

7:          print ("The number is not zero.\n");

8:  }

9:  print ("This is the last line of the program.\n");



$ program2_2

Enter a number:

5

The number is not zero.

This is the last line of the program.

$

Lines 3, 4, and 5 of Listing 2.2 are similar to lines you've seen before. Line 3 tells you to enter a number; line 4 assigns the line you've entered to the variable $number; and line 5 throws away the trailing newline character

Lines 6-8 constitute the if statement itself. As you have seen, this statement evaluates the conditional expression consisting of the variable $number. If $number is not zero, the expression is true, and the call to print is executed. If $number is zero, the expression is false, and the call to print is skipped; the Perl interpreter thus jumps to line 9.

The Perl interpreter executes line 9 and prints the following regardless of whether the conditional expression in line 6 is true or false:


This is the last line of the program.

Now that you understand how an if statement works, you're ready to see the formal syntax definition for the if statement.

The syntax for the if statement is


if (expr) {

        statement_block

}

This formal definition doesn't tell you anything you don't already know. expr refers to the conditional expression, which evaluates to either true or false. statement_block is the group of statements that is executed when expr evaluates to true.

If you are familiar with the C programming language, you probably have noticed that the if statement in Perl is syntactically similar to the if statement in C. There is one important difference, however: In Perl, the braces ({ and }) must be present

The following statement is illegal in Perl because the { and } are missing:


if ($number)

        print ("The value is not zero.\n");

Perl does support a syntax for single-line conditional statements. This is discussed on Day 8.

The Statement Block

The second part of the if statement, the part between the { and the }, is called a statement block. A statement block consists of any number of legal Perl statements (including no statements, if you like).

In the following example, the statement block consists of one statement:


print ("The value is not zero.\n");

NOTE
A statement block can be completely empty. In this statement, for example:
if ($number == 21) {
}
there is nothing between the { and }, so the statement block is empty. This is perfectly legal Perl code, although it's not particularly useful

Testing for Equality Using ==

So far, the only conditional expression you've seen is an expression consisting of a single variable. Although you can use any expression you like and any operators you like, Perl provides special operators that are designed for use in conditional expressions. One such operator is the equality comparison operator, ==.

The == operator, like the other operators you've seen so far, requires two operands or subexpressions. Unlike the other operators, however, it yields one of two possible results: true or false. (The other operators you've seen yield a numeric value as a result.) The == operator works like this:

Because the == operator returns either true or false, it is ideal for use in conditional expressions, because conditional expressions are expected to evaluate to either true or false. For an example, look at Listing 2.3, which compares two numbers read in from the standard input file.


Listing 2.3. A program that uses the equality-comparison operator to compare two numbers entered at the keyboard.

1:  #!/usr/local/bin/perl

2:  

3:  print ("Enter a number:\n");

4:  $number1 = <STDIN>;

5:  chop ($number1);

6:  print ("Enter another number:\n");

7:  $number2 = <STDIN>;

8:  chop ($number2);

9:  if ($number1 == $number2) {

10:         print ("The two numbers are equal.\n");

11: }

12: print ("This is the last line of the program.\n");



$ program2_3

Enter a number:

17

Enter another number:

17

The two numbers are equal.

This is the last line of the program.

$

Lines 3-5 are again similar to statements you've seen before. They print a message on your screen, read a number into the variable $number1, and chop the newline character from the number

Lines 6-8 repeat the preceding process for a second number, which is stored in $number2.

Lines 9-11 contain the if statement that compares the two numbers. Line 9 contains the conditional expression


$number1 == $number2

If the two numbers are equal, the conditional expression is true, and the print statement in line 10 is executed. If the two numbers are not equal, the conditional expression is false, so the print statement in line 10 is not executed; in this case, the Perl interpreter skips to the first statement after the if statement, which is line 12.

Line 12 is executed regardless of whether or not the conditional expression in line 9 is true. It prints the following message on the screen:


This is the last line of the program.

Make sure that you don't confuse the = and == operators. Because any expression can be used as a conditional expression, Perl is quite happy to accept statements such as
if ($number = 5) {
print ("The number is five.\n");
}
Here, the if statement is evaluated as follows:
  1. The number 5 is assigned to $number, and the following expression yields the result 5:
    $number = 5
  2. The value 5 is nonzero, so the conditional expression is true.
  3. Because the conditional expression is true, this statement is executed:
print ("The number is five.\n");
Note that the print statement is executed regardless of what the value of $number was before the if statement. This is because the value 5 is assigned to $number by the conditional expression.
To repeat: Be careful when you use the == operator

Other Comparison Operators

The == operator is just one of many comparison operators that you can use in conditional expressions. For a complete list, refer to Day 4.

Two-Way Branching Using if and else

When you examine Listing 2.3 (shown previously), you might notice a problem. What happens if the two numbers are not equal? In this case, the statement


print ("The two numbers are equal.\n");

is not printed. In fact, nothing is printed.

Suppose you want to modify Listing 2.3 to print one message if the two numbers are equal and another message if the two numbers are not equal. One convenient way of doing this is with the if-else statement.

Listing 2.4 is a modification of the program in Listing 2.3. It uses the if-else statement to print one of two messages, depending on whether the numbers are equal.


Listing 2.4. A program that uses the if-else statement.

1:  #!/usr/local/bin/perl

2:  

3:  print ("Enter a number:\n");

4:  $number1 = <STDIN>;

5:  chop ($number1);

6:  print ("Enter another number:\n");

7:  $number2 = <STDIN>;

8:  chop ($number2);

9:  if ($number1 == $number2) {

10:         print ("The two numbers are equal.\n");

11: } else {

12:         print ("The two numbers are not equal.\n");

13: }

14: print ("This is the last line of the program.\n");



$ program2_4

Enter a number:

17

Enter another number:

18

The two numbers are not equal.

This is the last line of the program.

$

Lines 3-8 are identical to those in Listing 2.3. They read in two numbers, assign them to $number1 and $number2, and chop their newline characters

Line 9 compares the value stored in $number1 to the value stored in $number2. If the two values are equal, line 10 is executed, and the following message is printed:


The two numbers are equal.

The Perl interpreter then jumps to the first statement after the if-else statement-line 14.

If the two values are not equal, line 12 is executed, and the following message is printed:


The two numbers are not equal.

The interpreter then continues with the first statement after the if-else-line 14.

In either case, the Perl interpreter executes line 14, which prints the following message:


This is the last line of the program.

The syntax for the if-else statement is


if (expr) {

        statement_block_1

} else {

        statement_block_2

}

As in the if statement, expr is any expression (it is usually a conditional expression). statement_block_1 is the block of statements that the Perl interpreter executes if expr is true, and statement_block_2 is the block of statements that are executed if expr is false.

Note that the else part of the if-else statement cannot appear by itself; it must always follow an if.

TIP
In Perl, as you've learned, you can use any amount of white space to separate tokens. This means that you can present conditional statements in a variety of ways.
The examples in this book use what is called the one true brace style:
if ($number == 0) {
print ("The number is zero.\n");
} else {
print ("The number is not zero.\n");
}
In this brace style, the opening brace ({) appears on the same line as the if or else, and the closing brace (}) starts a new line.
Other programmers insist on putting the braces on separate lines:
if ($number == 0)
{
print ("The number is zero.\n");
}
else
{
print ("The number is not zero.\n");
}
Still others prefer to indent their braces:
if ($number == 0)
{
print ("The number is not zero.\n");
}
I prefer the one true brace style because it is both legible and compact. However, it doesn't really matter what brace style you choose, provided that you follow these rules:
  • The brace style is consistent. Every if and else that appears in your program should have its braces displayed in the same way.
  • The brace style is easy to follow.
  • The statement blocks inside the braces always should be indented in the same way.
If you do not follow a consistent style, and you write statements such as
if ($number == 0) { print ("The number is zero"); }
you'll find that your code is difficult to understand, especially when you start writing longer Perl programs

Multi-Way Branching Using elsif

Listing 2.4 (which you've just seen) shows how to write a program that chooses between two alternatives. Perl also provides a conditional statement, the if-elsif-else statement, which selects one of more than two alternatives. Listing 2.5 illustrates the use of elsif.


Listing 2.5. A program that uses the if-elsif-else statement.

1:  #!/usr/local/bin/perl

2:  

3:  print ("Enter a number:\n");

4:  $number1 = <STDIN>;

5:  chop ($number1);

6:  print ("Enter another number:\n");

7:  $number2 = <STDIN>;

8:  chop ($number2);

9:  if ($number1 == $number2) {

10:         print ("The two numbers are equal.\n");

11: } elsif ($number1 == $number2 + 1) {

12:         print ("The first number is greater by one.\n");

13: } elsif ($number1 + 1 == $number2) {

14:         print ("The second number is greater by one.\n");

15: } else {

16:         print ("The two numbers are not equal.\n");

17: }

18: print ("This is the last line of the program.\n");



$ program2_5

Enter a number:

17

Enter another number:

18

The second number is greater by one.

This is the last line of the program.

$

You already are familiar with lines 3-8. They obtain two numbers from the standard input file and assign them to $number1 and $number2, chopping the terminating newline character in the process

Line 9 checks whether the two numbers are equal. If the numbers are equal, line 10 is executed, and the following message is printed:


The two numbers are equal.

The Perl interpreter then jumps to the first statement after the if-elsif-else statement, which is line 18.

If the two numbers are not equal, the Perl interpreter goes to line 11. Line 11 performs another comparison. It adds 1 to the value of $number2 and compares it with the value of $number1. If the two values are equal, the Perl interpreter executes line 12, printing the message


The first number is greater by one.

The interpreter then jumps to line 18-the statement following the if-elsif-else statement.

If the conditional expression in line 11 is false, the interpreter jumps to line 13. Line 13 adds 1 to the value of $number1 and compares it with the value of $number2. If these two values are equal, the Perl interpreter executes line 14, which prints


The second number is greater by one.

on the screen. The interpreter then jumps to line 18.

If the conditional expression in line 13 is false, the Perl interpreter jumps to line 15 and executes line 16, which prints


The two numbers are not equal.

on the screen. The Perl interpreter continues with the next statement, which is line 18.

If you have followed the program logic to this point, you've realized that the Perl interpreter eventually reaches line 18 in every case. Line 18 prints this statement:


This is the last line of the program.

The syntax of the if-elsif-else statement is as follows:


if (expr_1) {

        statement_block_1

} elsif (expr_2) {

        statement_block_2

} elsif (expr_3) {

        statement_block_3

...

} else {

        default_statement_block

}

Here, expr_1, expr_2, and expr_3 are conditional expressions. statement_block_1, statement_block_2, statement_block_3, and default_statement_block are blocks of statements.

The ... indicates that you can have as many elsif statements as you like. Each elsif statement has the same form:


} elsif (expr) {

        statement_block

}

Syntactically, an if-else statement is just an if-elsif-else statement with no elsif parts.

If you want, you can leave out the else part of the if-elsif-else statement, as follows:


if (expr_1) {

        statement_block_1

} elsif (expr_2) {

        statement_block_2

} elsif (expr_3) {

        statement_block_3

...

}

Here, if none of the expressions-expr_1, expr_2, expr_3, and so on-are true, the Perl interpreter just skips to the first statement following the if-elsif-else statement.

NOTE
The elsif parts of the if-elsif-else statement must appear between the if part and the else part

Writing Loops Using the while Statement

The conditional statements you've seen so far enable the Perl interpreter to decide between alternatives. However, each statement in the Perl programs that you have seen is either not executed or is executed only once.

Perl also enables you to write conditional statements that tell the Perl interpreter to repeat a block of statements a specified number of times. A block of statements that can be repeated is known as a loop.

The simplest way to write a loop in Perl is with the while statement. Here is a simple example of a while statement:


while ($number == 5) {

        print ("The number is still 5!\n");

}

The while statement is structurally similar to the if statement, but it works in a slightly different way. Here's how:

The statement block in the while statement is repeated until the conditional expression becomes false. This means that the statement


while ($number == 5) {

        print ("The number is still 5!\n");

}

loops forever (which is referred to as going into an infinite loop) if the value of $number is 5, because the value of $number never changes and the following conditional expression is always true:


$number == 5

For a more useful example of a while statement-one that does not go into an infinite loop-take a look at Listing 2.6.


Listing 2.6. A program that demonstrates the while statement.

1:  #!/usr/local/bin/perl

2:  

3:  $done = 0;

4:  $count = 1;

5:  print ("This line is printed before the loop starts.\n");

6:  while ($done == 0) {

7:          print ("The value of count is ", $count, "\n");

8:          if ($count == 3) {

9:                  $done = 1;

10:         }

11:         $count = $count + 1;

12: }

13: print ("End of loop.\n");



$ program2_6

This line is printed before the loop starts.

The value of count is 1

The value of count is 2

The value of count is 3

End of loop.

$

Lines 3-5 prepare the program for looping. Line 3 assigns the value 0 to the variable $done. (As you'll see, the program uses $done to indicate whether or not to continue looping.) Line 4 assigns the value 1 to the variable $count. Line 5 prints the following line to the screen


This line is printed before the loop starts.

The while statement appears in lines 6-12. Line 6 contains a conditional expression to be tested. If the conditional expression is true, the statement block in lines 7-11 is executed. At this point, the conditional expression is true, so the Perl interpreter continues with line 7.

Line 7 prints the current value of the variable $count. At present, $count is set to 1. This means that line 7 prints the following on the screen:


The value of count is 1

Lines 8-10 test whether $count has reached the value 3. Because $count is 1 at the moment, the conditional expression in line 8 is false, and the Perl interpreter skips to line 11.

Line 11 adds 1 to the current value of $count, setting it to 2.

Line 12 is the bottom of the while statement. The Perl interpreter now jumps back to line 6, and the whole process is repeated. Here's how the Perl interpreter continues from here:

Line 13 prints the following message on the screen:


End of loop.

At this point, program execution terminates because there are no more statements to execute.

The syntax for the while statement is


while (expr) {

        statement_block

}

As you can see, the while statement is syntactically similar to the if statement. expr is a conditional expression to be evaluated, and statement_block is a block of statements to be executed while expr is true.

Nesting Conditional Statements

The if statement in Listing 2.6 (shown previously) is an example of a nested conditional statement. It is contained inside another conditional statement (the while statement). In Perl, you can nest any conditional statement inside another. For example, you can have a while statement inside another while statement, as follows:


while (expr_1) {

        some_statements

        while (expr_2) {

                inner_statement_block

        }

        some_more_statements

}

Similarly, you can have an if statement inside another if statement, or you can have a while statement inside an if statement.

You can nest conditional statements inside elsif and else parts of if statements as well:


if ($number == 0) {

        # some statements go here

} elsif ($number == 1) {

        while ($number2 == 19) {

                # here is a place for a statement block

        }

} else {

        while ($number2 == 33) {

                # here is a place for another statement block

        }

}

The braces ({ and }) around the statement block for each conditional statement ensure that the Perl interpreter never gets confused.

TIP
If you plan to nest conditional statements, it's a good idea to indent each statement block to indicate how many levels of nesting you are using. If you write code such as the following, it's easy to get confused:
while ($done == 0) {
print ("The value of count is", $count, "\n");
if ($count == 3) {
$done = 1;
}
$count = $count + 1;
}
Although this code is correct, it's not easy to see that the statement
$done = 1;
is actually inside an if statement that is inside a while statement. Larger and more complicated programs rapidly become unreadable if you do not indent properly.

Looping Using the until Statement

Another way to loop in Perl is with the until statement. It is similar in appearance to the while statement, but it works in a slightly different way.

Listing 2.7 contains an example of the until statement.


Listing 2.7. A program that uses the until statement.

1:  #!/usr/local/bin/perl

2:  

3:  print ("What is 17 plus 26?\n");

4:  $correct_answer = 43;     # the correct answer

5:  $input_answer = <STDIN>;

6:  chop ($input_answer);

7:  until ($input_answer == $correct_answer) {

8:          print ("Wrong! Keep trying!\n");

9:          $input_answer = <STDIN>;

10:         chop ($input_answer);

11: }

12: print ("You've got it!\n");



$ program2_7

What is 17 plus 26?

39

Wrong! Keep trying!

43

You've got it!

$

Lines 3 and 4 set up the loop. Line 3 prints the following question on the screen


What is 17 plus 26?

Line 4 assigns the correct answer, 43, to $correct_answer.

Lines 5 and 6 retrieve the first attempt at the answer. Line 5 reads a line of input and stores it in $input_answer. Line 6 chops off the newline character.

Line 7 tests whether the answer entered is correct by comparing $input_answer with $correct_answer. If the two are not equal, the Perl interpreter continues with lines 8-10; if they are equal, the interpreter skips to line 12.

Line 8 prints the following on the screen:


Wrong! Keep trying!

Line 9 reads another attempt from the standard input file and stores it in $input_answer.

Line 10 chops off the newline character. At this point, the Perl interpreter jumps back to line 7 and tests the new attempt.

The interpreter reaches line 12 when the answer is correct. At this point, the following message appears on the screen, and the program terminates:


You've got it!

The syntax for the until statement is


until (expr) {

        statement_block

}

As in the while statement, expr is a conditional expression, and statement_block is a statement block.

Summary

Today, you learned about scalar variables and how to assign values to them.

Scalar variables and values can be used by the arithmetic operators to perform the basic arithmetic operations of addition, subtraction, multiplication, and division. The chop library function removes the trailing newline character from a line, which enables you to read scalar values from the standard input file.

A collection of operations and their values is known as an expression. The values operated on by a particular operator are called the operands of the operator. Each operator yields a result, which then can be used in other operations.

An expression can be divided into subexpressions, each of which is evaluated in turn.

Today you were introduced to the idea of a conditional statement. A conditional statement consists of two components: a conditional expression, which yields a result of either true or false; and a statement block, which is a group of statements that is executed only when the conditional expression is true.

Some conditional expressions contain the == operator, which returns true if its operands are numerically equal, and returns false if its operands are not.

The following conditional statements were described today:

You also learned about nesting conditional statements, as well as about infinite loops and how to avoid them.

Q&A

Q:Which should I use, the while statement or the until statement?
A:It doesn't matter, really; it just depends on which, in your judgment, is easier to read.
Once you learn about the other comparison operators on Day 4, "More Operators," you'll be able to use the while statement wherever you can use an until statement, and vice versa.
Q:In Listing 2.7, you read input from the standard input file in two separate places. Is there any way I can reduce this to one?
A:Yes, by using the do statement, which you'll encounter on Day 8, "More Control Structures."
Q:Do I really need both a $done variable and a $count variable in Listing 2.6?
A:No. On Day 4 you'll learn about comparison operators, which enable you to test whether a variable is less than or greater than a particular value. At that point, you won't need the $done variable.
Q:How many elsif parts can I have in an if-elsif-else statement?
A:Effectively, as many as you like. (There is an upper limit, but it's so large that you are not likely ever to reach it.)
Q:How much nesting of conditional statements does Perl allow? Can I put an if inside a while that is inside an if that is inside an until?
A:Yes. You can nest as many levels deep as you like. Generally, though, you don't want to go too many levels down because your program will become difficult to read.
The logical operators, which you'll learn about on Day 4, make it possible to produce more complicated conditional expressions. They'll eliminate the need for too much nesting.

Workshop

The Workshop provides quiz questions to help you solidify your understanding of the material covered and exercises to give you experience in using what you've learned. Try and understand the quiz and exercise answers before you go on to tomorrow's lesson.

Quiz

  1. Define the following terms:
    a.     expression
    b.     operand
    c.     conditional statement
    d.     statement block
    e.     infinite loop
  2. When does a while statement stop looping?
  3. When does an until statement stop looping?
  4. What does the == operator do?
  5. What is the result when the following expression is evaluated?
    14 + 6 * 3 - 10 / 2
  6. Which of the following are legal scalar variable names?
    a.     $hello
    b.     $_test
    c.     $now_is_the_time_to_come_to_the_aid_of_the_party
    d.     $fries&gravy
    e.     $96tears
    f.     $tea_for_2

Exercises

  1. Write a Perl program that reads in a number, multiplies it by 2, and prints the result.
  2. Write a Perl program that reads in two numbers and does the following:
  3. Write a Perl program that uses the while statement to print out the first 10 numbers (1-10) in ascending order.
  4. Write a Perl program that uses the until statement to print out the first 10 numbers in descending order (10-1).
  5. BUG BUSTER: What is wrong with the following program? (Hint: there might be more than one bug!)
    #!/usr/local/bin/perl
    $value = <STDIN>;
    if ($value = 17) {
    print ("You typed the number 17.\n");
    else {
    print ("You did not type the number 17.\n");
  6. BUG BUSTER: What is wrong with the following program?
    #!/usr/local/bin/perl
    # program which prints the next five numbers after the
    # number typed in
    $input = <STDIN>;
    chop ($input);
    $input = $input + 1; # start with the next number;
    $input = $terminate + 5; # we want to loop five times
    until ($input == $terminate) {
    print ("The next number is ", $terminate, "\n");