Title

Previous Chapter
Next Chapter

Links
Sections
Chapters
Copyright

Sections

Operator Types

Binary Arithmetic Operators

Unary Arithmetic Operators

Logical Operators

Bitwise Operators

Numeric Relational Operators

String Relational Operators

Ternary Operator

Range Operator (..)

String Operators (. and x)

Assignment Operators

Order of Precedence

Summary

Review Questions

Review Exercises

Chapters

ERRATA

Welcome!

Introduction

Part I: Basic Perl

01-Getting Your Feet Wet

02-Numeric and String Literals

03-Variables

04-Operators

05-Functions

06-Statements

07-Control Statements

08-References

Part II: Intermediate Perl

09-Using Files

10-Regular Expressions

11-Creating Reports

Part III: Advanced Perl

12-Using Special Variables

13-Handling Errors and Signals

14-What Are Objects?

15-Perl Modules

16-Debugging Perl

17-Command line Options

Part IV: Perl and the Internet

18-Using Internet Protocols

ftplib.pl

19-What is CGI?

20-Form Processing

21-Using Perl with Web Servers

22-Internet Resources

Appendixes

A-Review Questions

B-Glossary

C-Function List

D-The Windows Registry

E-What's On the CD?

     

04 - Operators

The operators in a computer language tell the computer what actions to perform. Perl has more operators than most languages. You've already seen some operators - like the equals or assignment operator(=) - in this book. As you read about the other operators, you'll undoubtedly realize that you are familiar with some of them. Trust your intuition; the definitions that you already know will probably still be true.

Operators are instructions you give to the computer so that it can perform some task or operation. All operators cause actions to be performed on operands. An operand can be anything that you perform an operation on. In practical terms, any particular operand will be a literal, a variable, or an expression. You've already been introduced to literals and variables. A good working definition of expression is some combination of operators and operands that are evaluated as a unit. Chapter 6, "Statements," has more information about expressions.

Operands are also recursive in nature. In Perl, the expression 3 + 5 (two operands and a plus operator) can be considered as one operand with a value of 8. For instance, (3 + 5) - 12 is an expression that consists of two operands subtracted from each other. The first operand is (3 + 5) and the second operand is 12.

This chapter will discuss most of the operators available to you in Perl . You'll find out about many operator types and how to determine their order of precedence. And, of course, you'll see many examples.

Precedence is very important in every computer language and Perl is no exception. The order of precedence indicates which operator should be evaluated first.

I like to think about operators in the same way I would give instructions to the driver of a car. I might say "turn left" or "turn right." These commands could be considered directional operators in the same way that + and mathematical operators that say "add this" or "subtract this." If I yell "stop" while the car is moving, on the other hand, it should supersede the other commands. This means that "stop" has precedence over "turn left" and "turn right." The "Order of Precedence" section later in this chapter will discuss precedence in more detail.

Operator Types

Perl supports many types of operators. Table 4.1 shows all of the operator types in the Perl language. This chapter discusses the more commonly used types in detail. You can learn about any type not discussed in this chapter by looking in the chapter referenced in that type's description in Table 4.1.

Table 4.1-The Perl Operator Types
Operator Types Number Page or Chapter Description
Arithmetic
These operators mirror those you learned in grade school. Addition, Subtraction, and multiplication are the bread and butter of most mathematical statements.
Assignment
These operators are used to assign a value to a variable. Algebra uses assignment operators. For example, in the statement X = 6, the equal sign is the assignment operator.
Binding
These operators are used during string comparisons and are explained in Chapter 10, "Regular Expressions."
Bitwise
These operators affect the individual bits that make up a value. For example, the value 3 is also 11 in binary notation or ((1 * 2) + 1). Each character in binary notation represents a bit which is smallest piece of a computer's memory that you can modify.
Comma Chapter 6 The comma operator has two functions. It serves to separate array or list elements (see Chapter 2, "Numeric and String Literals") and it serves to separate expressions (see Chapter 6, "Statements").
File Test Chapter 9 These operators are used to test for various conditions associated with files. You can test for file existence, file type, and file access rights among other things. See Chapter 9, "Using Files," for more information.
List Chapter 5 List operators are funny things in Perl. They resemble function calls in other languages. List operators are discussed in Chapter 5, "Functions."
Logical Chapter 13 These operators implement Boolean or true/false logic. In the sentence "If John has a fever AND John has clogged sinuses OR an earache AND John is NOT over 60 years old, then John has a cold," the AND, OR and NOT are acting as logical operators. The low precedence logical operators will be discussed separately in Chapter 13, "Handling Errors and Signals," on.
Numeric Relational
These operators allow you to test the relationship of one numeric variable to another. For example, is 5 GREATER THAN 12?
Postfix Chapter 5 A member of this group of operators - (), [], {} - appears at the end of the affected objects. You've already seen them used in Chapter 3, "Variables" for arrays and associative arrays. The parentheses operators are also used for list operators as discussed in Chapter 5, "Functions."
Range
The range operator is used to create a range of elements in arrays. It can also be used in a scalar context.
Reference Chapter 8 The reference operators are used to manipulate variables. For more information, see Chapter 8, "References."
String
The string concatenation operator is used to join two strings together. The string repetition operator is used to repeat a string.
String Relational
These operators allow you to test the relationship of one string variable to another. For example, is "abc" GREATER THAN "ABC"?
Ternary
The ternary operator is used to choose between two choices based on a given condition. For instance: If the park is within one mile, John can walk, otherwise he must drive.

The Binary Arithmetic Operators

There are six binary arithmetic operators: addition, subtraction, multiplication, exponentiation, division, and modulus. While you may be unfamiliar with the modulus operator, the rest act exactly as you would expect them to. Table 4.2 lists the arithmetic operators that act on two operands - the binary arithmetic operators. In other words, the addition (+) operator can be used to add two numbers together like this: 4 + 5. The other binary operators act in a similar fashion.

Table 4.2-The Binary Arithmetic Operators
Operator Description
op1 + op2 Addition
op1 - op2 Subtraction
op1 * op2 Multiplication
op1 ** op2 Exponentiation
op1 / op2 Division
op1 % op2 Modulus

Example: The Exponentiation Operator

The exponentiation operator is used to raise a number to a power. For instance, 2 ** 4 is equivalent to 2 * 2 * 2 * 2 which equals 16. You'll occasionally see a reference to exponentiation when the discussion turns to how efficient a given algorithm is but I've never needed it for my everyday programming tasks. In any case, here's a quick look at how it works.

This example shows how to raise the number 4 to the 3rd power which is equivalent to 4 * 4 * 4 or 64.

Pseudocode

Assign $firstVar the value of 4.

Raise 4 to the 3rd power using the exponentiation operator and assign the new value to $secondVar.

Print $secondVar.

$firstVar = 4;
$secondVar = $firstVar ** 3;
print("$secondVar\n");
This program produces the following output:
64

Example: The Modulus Operator

The modulus operator is used to find the remainder of the division between two integer operands. For instance, 10 % 7 equals 3 because 10 / 7 equals 1 with 3 left over.

I've found the modulus operator to be useful when my programs need to run down a list and do something every few items. This example shows you how to do something every 10 items.

Pseudocode

Start a loop that begins with $index equal to zero.

If the value of $index % 10 is equal to zero then the print statement will be executed.

Print the value of $index followed by space.

The program will increase the value of $index by one and then loop back to the start of the if statement.

Listing 4.1-04LST01.PL - How to Display a Message Every Ten Items


for ($index = 0; $index <= 100; $index++) { if ($index % 10 == 0) { print("$index "); } }

When this program is run, the output should look like the following:

0 10 20 30 40 50 60 70 80 90 100
Notice that every 10th item is printed. By changing the value on the right side of the modulus operator you can affect how many items are processed before the message is printed. Changing the value to 15 means that a message will be printed every 15 items. Chapter 7, "Control Statements," describes the if and for statement in detail.

The Unary Arithmetic Operators

The unary arithmetic operators act on a single operand. They are used to change the sign of a value; to increment a value or to decrement a value. Incrementing a value means to add one to its value. Decrementing a value means to subtract one from its value. Table 4.3 lists Perl's unary operators.

Table 4.3-The Unary Arithmetic Operators
Operator Description
Changing the sign of op1
+op1 Positive operand
-op1 Negative operand
Changing the value of op1 before usage
++op1 Pre-increment operand by one
--op1 Pre-decrement operand by one
Changing the value of op1 after usage
op1++ Post-increment operand by one
op1-- Post-decrement operand by one

Arithmetic operators start to get complicated when unary operators are introduced. Just between you and me, I didn't get the hang of negative numbers until someone said: "If you have five pieces of chocolate, and add negative two pieces..."

You might think that adding negative numbers is strange. Not so. I know that you will never write a mathematics statement like the following: 345 + -23. However, you might use 354 + $gasBill, where $gasBill represents a 23-dollar debit - in other words, a negative number.

Using the unary plus operator does nothing, and Perl ignores it. The unary negative operator, however, changes the meaning of a value from positive to negative or vice versa. For instance, if you had a variable called $firstVar equal to 34. Then printing -$firstVar would display -34.

The ++ and -- operators are examples of the Perl shorthand notation. If the ++ or -- operators appear in front of the operand, the operand is incremented or decremented before its value is used. If the ++ or -- operators appear after the operand, then the value of the operand is used and then the operand is incremented or decremented as required.

Example: The Pre-increment Operator

This example shows how to use the pre-increment operator (++).

Pseudocode

Original Way

The $numPages variable is assigned a value of 5.

The $numPages variable is incremented by 1.

The $numPages variable is printed.

New Way

The $numPages variable is assigned a value of 5.

The $numPages variables is incremented using the pre-increment operator and then printed.

Listing 4.2-04LST02.PL - Using Pre-increment Operator


# Original Way $numPages = 5; $numPages = $numPages + 1; print($numPages, "\n"); # New Way $numPages = 5; print(++$numPages, "\n");

This program produces the following output:

6
6
You can see that the new way of coding is shorter than the original way. The statement print(++$numPages, "\n"); will first increment the $numPages variable and then allow the print command to use it.

Example: The Pre-Decrement Operator

This example shows how to use the pre-decrement operator (--).

Pseudocode

Original Way

The $numPages variable is assigned a value of 5.

The $numPages variable is decremented by 1.

The $totalPages variable is assigned the value of $numPages + 5.

The $numPages and $totalPages variables are printed.

New Way

The $numPages variable is assigned a value of 5.

The $numPages variable is decremented and then $numPages + 5 is assigned to $totalPages.

The $numPages and $totalPages variables are printed.

Listing 4.3-04LST03.PL - Using Pre-decrement Operator


# Original Way $numPages = 5; $numPages = $numPages - 1; $totalPages = $numPages + 5; print("$numPages $totalPages \n"); # New Way $numPages = 5; $totalPages = --$numPages + 5; print("$numPages $totalPages \n");

This program produces the following output:

4 9
4 9
The statement $totalPages = --$numPages + 5; will first decrement the $numPages variable and then allow the plus operator to use it.

Example: The Post-increment Operator

This example shows how to use the ++ and -- post-increment operators.

Pseudocode

Original Way

The $numPages variable is assigned a value of 5.

The $totalPages variable is assigned the value of $numPages.

The $numPages variable is incremented by one.

The $numPages and $totalPages variables are printed.

New Way

The $numPages variable is assigned a value of 5.

The $totalPages variable is assigned the value of $numPages and then the $numPages variable is incremented.

The $numPages and $totalPages variables are printed.

Listing 4.4-04LST04.PL - Using Post-increment Operator


# Original Way $numPages = 5; $totalPages = $numPages; $numPages = $numPages + 1; print("$numPages $totalPages \n"); # New Way $numPages = 5; $totalPages = $numPages++; print("$numPages $totalPages \n");

The program produces the following output:

6 5
6 5
The statement $totalPages = $numPages++; will first assign the value of $numPages to $totalPages and then increment the $numPages variable. It may help to know that post-increment and post-decrement operators do not affect the value of the variable on the left side of the assignment operator. If you see post-increment or post-decrement operators, evaluate the statement by ignoring them. Then, when done, apply the post-increment and post-decrement operators as needed.

Tip
The Perl programming language has many ways of achieving the same objective. You will become a more efficient programmer if you decide on one approach to incrementing/decrementing and use it consistently.

The Logical Operators

Logical operators are mainly used to control program flow. Usually you will find them as part of an if, a while or some other control statement. Control statements are discussed in Chapter 7, "Control Statements."

Table 4.4-The Logical Operators
Operator Description
op1 && op2 Performs a logical AND of the two operands
op1 || op2 Performs a logical OR of the two operands.
!op1 Performs a logical NOT of the operand.

The concept of logical operators is simple. They allow a program make a decision based on multiple conditions. Each operand is considered a condition that can be evaluated to a true or false value. Then the value of the conditions are used to determine the overall value of the op1 operator op2 or !op1 grouping. The following examples demonstrate different ways that logical conditions can be used.

Example: The "AND" Operator (&&)

The && operator is used to determine if both operands or conditions are true. Table 4.5 shows the results of using the && operator on the four sets of true/false values.

Table 4.5-The && Result Table
Op1 Op2 Op1 && Op2
0 0 0
1 0 0
0 1 0
1 1 1

Pseudocode

If the value of $firstVar is 10 AND the value of $secondVar is 9 then print the error message.

if ($firstVar == 10 && $secondVar == 9) {
    print("Error!");
};
If either of the two conditions is false or incorrect then the print command is bypassed.

Example: The "OR" Operator (||)

The || operator is used to determine if either of the conditions is true. Table 4.6 shows the results of using the || operator on the four sets of true/false values.

Table 4.6-The || Result Table
Op1 Op2 Op1 || Op2
0 0 0
1 0 1
0 1 1
1 1 1

Pseudocode

If the value of $firstVar is 9 OR the value of $firstVar is 10 then print the error message.

if ($firstVar == 9 || $firstVar == 10) {    print("Error!");
};
If either of the two conditions is true then the print command is run.

Caution
If the first operand of the || operator evaluates to true, the second operand will not be evaluated. This could be a source of bugs if you are not careful. For instance, in the following code fragment
if ($firstVar++ || $secondVar++) { print("\n"); }
variable $secondVar will not be incremented if $firstVar++ evaluates to true.

Note
You might be tempted to try the following

if ($firstVar == (9 || 10)) {
    print("Error!");
};
to determine if $firstVar is equal to either 9 or 10. Don't do it. Perl doesn't work this way. First, the expression (9 || 10) will be evaluated to be equal to 9. And then, Perl will evaluate $firstVar == 9. The correct method for testing $firstVar is to explicitly state each sub-condition that needs to be met in order for the entire condition to return true. The correct way is:
if ($firstVar == 9 || $firstVar == 10) {
    print("Error!");
};

Example: The "NOT" Operator (!)

The ! operator is used to convert true values to false and false values to true. In other words, it inverts a value. Perl considers any non-zero value to be true - even string values. Table 4.7 shows the results of using the ! operator on true and false values.

Table 4.7-The ! Result Table
Op1 !Op1
0 1
1 0

Pseudocode

Assign a value of 10 to $firstVar.

Negate $firstVar - !10 is equal to 0 - and assign the new value to $secondVar.

If the $secondVar variable is equal to zero then print the string "zero."

$firstVar = 10;
$secondVar = !$firstVar;
if ($secondVar == 0) {
   print("zero\n");
};
The program produces the following output:
zero
You could replace the 10 in the first line with "ten", 'ten', or any non-zero, non-null value.

The Bitwise Operators

The bitwise operators, listed in Table 4.8, are similar to the logical operators, except that they work on a smaller scale.

Table 4.8-The Bitwise Operators
Operator Description
op1 & op2 The AND operator compares two bits and generates a result of 1 if both bits are 1; otherwise it returns 0.
op1 | op2 The OR operator compares two bits and generates a result of 1 if either or both bits are 1; otherwise it returns 0.
op1 ^ op2 The EXCLUSIVE-OR operator compares two bits and generates a result of 1 if the bits are complementary; otherwise it returns 0.
~op1 The COMPLEMENT operator is used to invert all of the bits of the operand. I've never found this useful, so we'll skip looking at an example of it.
op1 >> op2 The SHIFT RIGHT operator moves the bits to the right, discards the far right bit, and assigns the left-most bit a value of 0. Each move to right effectively divides op1 in half.
op1 << op2 The SHIFT LEFT operator moves the bits to the left, discards the far left bit, and assigns the rightmost bit a value of 0. Each move to the left effectively multiplies op1 by 2.

Note
Both operands associated with the bitwise operator must be integers.

Bitwise operators are used to change individual bits in an operand. A single byte of computer memory - when viewed as a 8 bits - can signify the true/false status of 8 flags because each bit can be used as a boolean variable that can hold one of two values: true or false. A flag variable is typically use to indicate the status of something. For instance, computer files can be marked as read-only. So you might have a $fReadOnly variable who job would be to hold the read-only status of a file. This variable is called a flag variable because when $fReadOnly has a true value it's equivalent to a football umpire throwing a flag. The variable says, "Whoa!, don't modify this file."

When you have more than one flag variable, if might be more efficient to use a single variable to indicate the value of more than one flag. The next example shows you how to do this.

Example: Using the &, |, and ^ Operators

The first step to using bitwise operators to indicate more than one flag in a single variable is to define the meaning of the bits that you'd like to use. Figure 4.1 shows an example of 8 bits that could be used to control the attributes of text on a display.

Fig. 04.1 - The bit definition of a text attribute control variable.

If you assume that $textAttr is used control the text attributes, then you could set the italic attribute by setting $textAttr equal to 128 like this.

$textAttr = 128;
because the bit pattern of 128 is 10000000. The bit that is turned on corresponds to the italic position in $textAttr.

Now let's set both the italic and underline attributes on at the same time. The underline value is 16, which has a bit pattern of 00010000. You already know the value for italic is 128. So we call on the OR operator to combine the two values.

$textAttr = 128 | 16;
or using the bit patterns (this is just an example - you can't do this in Perl)
$textAttr = 10000000 | 00010000;
If you look back at Table 4.8 and evaluate each bit, you will see that $textAttr gets assigned a value of 144 (or 10010000 as a bit pattern). This will set both italic and underline attributes on.

The next step might be to turn the italic attribute off. This is done with the EXLUSIVE-OR operator, like so:

$textAttr = $textAttr ^ 128;

Example: Using the >> and << Operators

The bitwise shift operators are used to move all of the bits in the operand left or right a given number of times. They come in quite handy when you need to divide or multiply integer values.

This example will divide by 4 using the >> operator.

Pseudocode

Assign a value of 128 to the $firstVar variable.

Shift the bits inside $firstVar two places to the right and assign the new value to $secondVar.

Print the $secondVar variable.

$firstVar = 128;
$secondVar = $firstVar >> 2;
print("$secondVar\n");
The program produces the following output:
32
Let's look at the bit patterns of the variables before and after the shift operation. First, $firstVar is assigned 128 or 1000000. Then the value in $firstVar is shifted left by 2 places. So the new value is 00100000 or 32 which is assigned to $secondVar.

The right-most bit of a value is lost when the bits are shifted right. You can see this in the next example.

This example will divide by 8 using the >> operator.

Pseudocode

Assign a value of 129 - a bit pattern of 10000001 - to $firstVar. Every odd value has the right-most bit set.

Shift the bits inside $firstVar three places to the right and assign the new value to $secondVar.

Print the $secondVar variable.

$firstVar = 129;
$secondVar = $firstVar >> 3;
print("$secondVar\n");
The program produces the following output:
16
Since the bit value of 16 is 00010000, you can tell that the right-most bit has disappeared.

Here's a quick example using the << operator. We'll multiply 128 by 8.

Pseudocode

Assign a value of 128 to the $firstVar variable.

Shift the bits inside $firstVar three places to the left and assign the new value to $secondVar.

Print the $secondVar variable.

$firstVar = 128;
$secondVar = $firstVar << 3;
print $secondVar;
The program produces the following output:
1024
The value of 1024 is beyond the bounds of the 8 bits that the other examples used. This was done to show you that the number of bits available for your use is not limited to one byte. You are really limited by however many bytes Perl uses for one scalar variable - probably 4. You'll need to read the Perl documentation that came with the interpreter to determine how many bytes your scalar variables use.

The Numeric Relational Operators

The numeric relational operators, listed in Table 4.9, are used to test the relationship between two operands. You can see if one operand is equal to another, if one operand is greater than another, or if one operator is less than another.

Note
It is important to realize that the equality operator is a pair of equals sign and not just one. Quite a few bugs are introduced into programs because people forget this rule and use a single equals sign when testing conditions.

Table 4.9-The Numeric Relational Operators
Operator Description
The Equality Operators
op1 == op2 This operator returns true if op1 is equal to op2. For example, 6 == 6 is true.
op1 != op2 This operator returns true if op1 is not equal to op2. For example, 6 != 7 is true.
The Comparison Operators
op1 < op2 This operator returns true if op1 is less than op2. For example, 6 < 7 is true.
op1 <= op2 This operator returns true if op1 is less than or equal to op2. For example, 7 <= 7 is true.
op1 > op2 This operator returns true if op1 is greater than op2. For example, 6 > 5 is true.
op1 >= op2 This operator returns true if op1 is greater than or equal to op2. For example, 7 >= 7 is true.
op1 <=> op2 This operator returns 1 if op1 is greater than op2, 0 if op1 equals op2, and -1 if op1 is less than op2.

You will see many examples of these operators when you read about controlling program flow in Chapter 7, "Control Statements." Therefore, I'll only show an example of the <=> comparison operator here.

Example: Using the <=> Operator

The number comparison operator is used to quickly tell the relationship between one operand and another. It is frequently used during sorting activities.

Tip
You may sometimes see the <=> operator called the spaceship operator because of the way that it looks.

Pseudocode

Set up three variables.

Print the relationship of each variable to the variable $midVar.

$lowVar =  8;
$midVar = 10;
$hiVar  = 12;

print($lowVar <=> $midVar, "\n");
print($midVar <=> $midVar, "\n");
print($hiVar  <=> $midVar, "\n");
The program produces the following output:
-1
0
1
The -1 indicates that $lowVar (8) is less than $midVar (10). The 0 indicates that $midVar is equal to itself. And the 1 indicates that $hiVar (12) is greater than $midVar (10).

The String Relational Operators

The string relational operators, listed in Table 4.10, are used to test the relationship between two operands. You can see if one operand is equal to another, if one operand is greater than another, or if one operator is less than another.

Table 4.10-The String Relational Operators
Operator Description
The Equality Operators
op1 eq op2 This operator returns true if op1 is equal to op2. For example, "b" eq "b" is true.
op1 ne op2 This operator returns true if op1 is not equal to op2. For example, "b" ne "c" is true.
The Comparison Operators
op1 lt op2 This operator returns true if op1 is less than op2. For example, "b" lt "c" is true.
op1 le op2 This operator returns true if op1 is less than or equal to op2. For example, "b" le "b" is true.
op1 gt op2 This operator returns true if op1 is greater than op2. For example, "b" gt "a" is true.
op1 ge op2 This operator returns true if op1 is greater than or equal to op2. For example, "b" ge "b" is true.
op1 cmp op2 This operator returns 1 if op1 is greater than op2, 0 if op1 equals op2, and -1 if op1 is less than op2.

String values are compared using the ASCII values of each character in the strings. You will see examples of these operators when you read about control program flow in Chapter 7, "Control Statements." So, we'll only show an example of the cmp comparison operator here.

Example: Using the cmp Operator

The string comparison operator acts exactly like the <=> operator except that it is designed to work with string operands. This example will compare the values of three different strings.

Pseudocode

Set up three variables.

Print the relationship of each variable to the variable $midVar.

$lowVar = "AAA";
$midVar = "BBB";
$hiVar  = "CCC";

print($lowVar cmp $midVar, "\n");
print($midVar cmp $midVar, "\n");
print($hiVar  cmp $midVar, "\n");
The program produces the following output:
-1
0
1
Notice that even though strings are being compared, a numeric value is returned. You may be wondering what happens if the strings have spaces in them. Let's explore that for a moment.
$firstVar = "AA";
$secondVar = " A";
print($firstVar cmp $secondVar, "\n");
The program produces the following output
1
which means that "AA" is greater than " A" according to the criteria used by the cmp operator.

The Ternary Operator

The ternary is actually a sequence of operators. The operator is used like this:
CONDITION-PART ? TRUE-PART : FALSE-PART
which is shorthand for the following statement:
if (CONDITION-PART) {
    TRUE-PART
} else {
    FALSE-PART
}
You can find more information about if statements in Chapter 7, "Control Statements."

The value of the entire operation depends on the evaluation of the CONDITION-PART section of the statement. If the CONDITION-PART evaluates to true, then the TRUE-PART is the value of the entire operation. If the CONDITION-PART evaluates to false, then the FALSE-PART is the value of the entire operation.

Tip
The ternary operator is also referred to as the conditional operator by some references.

Example: Using the Ternary Operator to Assign Values

I frequently use the ternary operator to assign a value to a variable when it can take one of two values. This use of the operator is fairly straightforward.

Pseudocode

If $firstVar is zero, then assign $secondVar a value of zero. Otherwise, assign $secondVar the value in the first element in the array @array.

$secondVar = ($firstVar == 0) ? 0 : $array[0];
The ternary operator can also be used to control which code sections are performed. However, I recommend against this use because it makes program harder to read. I believe that operators should affect variables, not program flow.

Pseudocode

The CONDITION-PART evaluates to true so the $firstVar variable is incremented.

1 ? $firstVar++ : $secondVar++;
Pseudocode

The CONDITION-PART evaluates to false so the $secondVar variable is incremented.

0 ? $firstVar++ : $secondVar++;

In this example, You get a chance to see how the language can be abused. When there are more than two actions to consider you can nest ternary operators inside each other. However, as you can see, the result is confusing code.

Pseudocode

Assign one of four values to $firstVar depending on the value of $temp.

$
firstVar = $temp == 0 ?
                $numFiles++ :
                ($temp == 1 ?
                    $numRecords++ :
                    ($temp == 3 ? $numBytes++ : $numErrors++));
Tip
Abusing the language in this manner will make your programs difficult to understand and maintain. You can use the if statement for better looking and more maintainable code. See Chapter 7, "Control Statements," for more information.

If you'd like to see a really strange use of the ternary operator, take a look at this next example. It uses the ternary operator to determine which variable gets assigned a value.

$firstVar = 1;
$secondVar = 1;
$thirdVar = 1;

($thirdVar == 0 ? $firstVar : $secondVar) = 10;

print "$firstVar\n";
print "$secondVar\n";
print "$thirdVar\n";
The program produces the following output:
1
10
1
The line ($thirdVar == 0 ? $firstVar : $secondVar) = 10; is equivalent to the following control statement.
if ($thirdVar ==0) {
    $firstVar = 10;
} else {
    $secondVar = 10;
}
This use of the ternary operator works because Perl lets you use the results of evaluations as lvalues. An lvalue is anything that you can assign a value to. It called an lvalue because it goes on the left side of an assignment operator.

Note
Some programmers might think that this use of the ternary operator is as bad as using it to control program flow. However, I like this ability because it gives you the ability to concisely determine which variable is the target of an assignment.

The Range Operator (..)

The range operator was already introduced to you in Chapter 3, "Variables," when you read about arrays. I review its use here - in an array context - in a bit more detail.

Example: Using the Range Operator

When used with arrays, the range operator simplifies the process of creating arrays with contiguous sequences of numbers and letters. We'll start with an array of the numbers one through ten.

Pseudocode

Create an array with ten elements that include 1, 2, 3, 4, 5, 6, 7, 8, 9, and 10.

@array = (1..10);
You can also create an array of contiguous letters.

Pseudocode

Create an array with ten elements that include A, B, C, D, E, F, G, H, I , and J.

@array = ("A".."J");
And of course, you can have other things in the array definition besides the range operator.

Pseudocode

Create an array that includes AAA, 1, 2, 3, 4, 5, A, B, C, D, and ZZZ.

@array = ("AAA", 1..5, "A".."D", "ZZZ");
You can use the range operator to create a list with zero filled numbers.

Pseudocode

Create an array with ten elements that include the strings 01, 02, 03, 04, 05, 06, 07, 08, 09, and 10.

@array = ("01".."10");
And you can use variables as operands for the range operator.

Pseudocode

Assign a string literal to $firstVar.

Create an array with ten elements that include the strings 01, 02, 03, 04, 05, 06, 07, 08, 09, and 10.

$firstVar = "10";
@array = ("01"..$firstVar);
If you use strings of more than one character as operands, the range operator will increment the rightmost character by one and perform the appropriate carry operation when the number 9 or letter z is reached. You'll probably need to see some examples before this makes sense. I know that I had trouble figuring it out. So here goes.

You've already seen "A".."Z" which is pretty simple to understand. Perl counts down the alphabet until Z is reached.

Caution
The two ranges "A".."Z" and "a".."Z" are not identical. And the second range does not contain all lower-case letters and all upper-case letters. Instead, Perl creates an array that just contains the lower-case letters. Apparently, when Perl reaches the end of the alphabet - whether lower-case or upper-case - the incrementing stops.

What happens when a two-character string is used as an operand for the range operator? Let's find out.

Pseudocode

Create an array that includes the strings aa, ab, ac, ad, ae, and af.

@array = ("aa" .. "af");
This behaves as you'd expect, incrementing along the alphabet until the f letter is reached. However, if you change the first character of one of the operands watch what happens.

Pseudocode

Create an array that includes the strings ay, az, ba, bb, bc, bd, be, and bf.

@array = ("ay" .. "bf");
When the second character is incremented to z, then the first character is incremented to b and the second character is set to a.

Note
If the right-hand side of the range operator is less than the left-hand side, an empty array is created.

Errata Note
In the printed version of this book the previous note was incorrect.

Note
Mark Pettigrew sent me a email message to let me know what an empty array is only created when numbers are involved. For exampl, @array = (5...1) creates an ampty array. However, @array = ('bf'..'ay') actually creates an array with the elements bf, bg, bh ... zz. The array creation stops when the z character is reached.

The String Operators (. and x)

Perl has two different string operators - the concatenation (.) operator and the repetition (x) operator. These operators make it easy to manipulate strings in certain ways. Let's start with the concatenation operator.

Example: Using the Concatenation Operator

The concatenation operator is used to join two strings together. If you have a numeric value as one of the two operands, Perl will quietly convert it to a string.

Here is an example that shows Perl converting a number into a string.

Pseudocode

Assign a string value to $firstVar. The string will be three values concatenated into one string.

$firstVar = "This box can hold " . 55 . " items.";
print("$firstVar\n");
The program produces the following output:
This box can hold 55 items.
The number 55 is automatically converted to a string and then combined with the other strings. Notice that the string literals have spaces in them so that when the final string is created, the number will be surrounded with spaces making the sentence readable.

You can also use variables as operands with the concatenation operator.

Pseudocode

Assign string values to $firstVar and $secondVar.

Assign the concatenation of $firstVar and $secondVar to $thirdVar.

Print $thirdVar.

$firstVar = "AAA";
$secondVar = "BBB";
$thirdVar = $firstVar . $secondVar;
print("$thirdVar\n");
The program produces the following output
AAABBB
Notice that Perl concatenates the strings together without adding any spaces or other separating characters. If you want a space between the string after they are concatenated, you must ensure that one of original strings has the space character - either at the end of the first string or the start of the second.

Example: Using the Repetition Operator

The repetition operator is used to repeat any string a given number of times. Like the concatenation operator, any numbers will be quietly converted to strings so that they can be repeated.

Here is an example that how to repeat a string 7 times.

Pseudocode

Assign $firstVar the value of "1".

Assign $secondVar the value of $firstVar repeated seven times.

Print $secondVar.

$firstVar = "1";
$secondVar = $firstVar x 7;
print("$secondVar\n");
The program produces the following output:
1111111
The string that gets repeated can be longer than one character.

Pseudocode

Assign $firstVar the value of "11 ".

Assign $secondVar the value of $firstVar repeated seven times.

Print $secondVar.

$firstVar = "11 ";
$secondVar = $firstVar x 7;
print("$secondVar\n");
The program produces the following output:
11 11 11 11 11 11 11
You can also use the repetition operator on arrays or lists. However, the array gets evaluated in a scalar context so that the number of elements is returned. This number gets converted to a string and then repeated.

Pseudocode

Assign the elements "A" through "G" to @array.

Get the number of elements in @array, convert that number to a string, repeat it twice and then assign the new string to $firstVar.

Print the @array and $firstVar variables.

@array = ('A'..'G');
$firstVar = @array x 2;
print("@array\n");
print("$firstVar\n");
This program produces the following output:
A B C D E F G
77
Tip
If you want the repeat an array element, explicitly say which element you want to repeat using an array index.

The Assignment Operators

The last type of operators that we'll look at are assignment operators. You've already used the basic assignment operator (=) to value variables in some of the examples earlier in this chapter. In addition, Perl has shortcut assignment operators that combine the basic assignment operator with another operator. For instance, instead of saying $firstVar = $firstVar + $secondVar; you could say $firstVar += $secondVar. The advantage of the using shortcut operators - besides having less to type - is that your intentions regarding assignment are made clear.

Table 4.11 lists all of Perl's assignment operators. After reading the other sections in this chapter about the various operator types, you should be familiar with all of the operations described in the table.

Table 4.11-The Assignment Operators
Operator Description
var = op1; This operator assigns the value of op1 to var.
var += op1; This operator assigns the value of var + op1 to var.
var -= op1; This operator assigns the value of var - op1 to var.
var *= op1; This operator assigns the value of var * op1 to var.
var /= op1; This operator assigns the value of var / op1 to var.
var %= op1; This operator assigns the value of var % op1 to var.
var .= op1; This operator assigns the value of var . op1 to var.
var **= op1; This operator assigns the value of var ** op1 to var.
var x= op1; This operator assigns the value of var x op1 to var.
var <<= op1; This operator assigns the value of var << op1 to var.
var >>= op1; This operator assigns the value of var >> op1 to var.
var &= op1; This operator assigns the value of var & op1 to var.
var |= op1; This operator assigns the value of var | op1 to var.
var ||= op1; This operator assigns the value of var || op1 to var.
Note
This assignment operator was erroneously left out of the printed edition of the book. Randal Schwartz was kind enough to point out this problem.

var ^= op1; This operator assigns the value of var ^ op1 to var.

The examples in this section will not describe the different assignment operators. Their use is straightforward. However, when assigning values to arrays there are some special situations. The first is assigning values to array slices and the second is assign array elements to scalars. Let's start with array slices.

Example: Assignment Using Array Slices

If you recall from Chapter 3, "Variables," array slices let you directly access multiple elements of an array using either the comma or range operators. For instance, the variable @array[10, 12] refers to both the tenth and the twelfth elements of the @array array.

You can use the assignment operator in conjunction with array slices to assign values to multiple array elements in one statement. If you have an array with 10 elements and you need to change elements 4 and 7 you can do so like this:

Pseudocode

Create an array with 11 elements.

Assign values to elements 4 and 7.

Print the array.

@array = (0..10);
@array[4, 7] = ("AA","BB");
print("@array\n");
This program produces the following output:
0 1 2 3 AA 5 6 BB 8 9 10
Tip
The elements that an array slice refers to do not have to be in consecutive order.

You can look at the array slice assignment in the following way. The array on the left is the target and the array on the right is the source. So, the target array gets assigned the values in the source array.

There are a number of variations on the basic idea of using array slices in assignment statements. You can use scalar variables in place of the literals as operands for the range operator.

Pseudocode

Create an array with 11 elements.

Assign values to elements 4 and 7.

Print the array.

$firstVar = "AA";
@array = (0..10);
@array[4, 7] = ($firstVar, $firstVar);
print("@array\n");
This program produces the following output:
0 1 2 3 AA 5 6 AA 8 9 10
And you can use array variables also.

Pseudocode

Create an array with 11 elements and an array with 2 elements.

Assign values to elements 4 and 7 of the @array1 array.

Print @array1.

@array1 = (0..10);
@array2 = ("AA", "BB");
@array1[4, 7] = @array2;
print("@array1\n");
This program produces the following output
0 1 2 3 AA 5 6 BB 8 9 10
An array slice assignment is a quick and convenient way to swap two array elements from the same array.

Pseudocode

Create an array with 11 elements.

Swap elements 4 and 7.

Print the array.

@array = (0..10);
@array[4, 7] = @array[7, 4];
print "@array\n";
This program produces the following output:
0 1 2 3 7 5 6 4 8 9 10
Notice that the 4th element and the 7th element have swapped places. You can also use the range operator when using array slice assignment.

Pseudocode

Create an array with 11 elements.

Assign the 23rd, 24th, and 25th elements from @array2 to @array1 as elements 1, 2, and 3.

Print the array.

@array1 = (0..10);
@array2 = ("A".."Z");
@array1[1..3] = @array2[23..25];
print "@array1\n";
This program produces the following output:
0 X Y Z 4 5 6 7 8 9 10
Figure 4.2 shows a depiction of which array elements in @array2 are being assigned to which array elements in @array1.

Fig. 04.2 - Assigning array Elements using an array slice and the range operator.

If you only need certain elements from an array, you can use the array slice to select and create a new array in one step.

Pseudocode

Create an array with 10 elements.

Assign the 2nd, 4th, and 6th elements from @array2 to @array1 as elements 0, 1, and 2.

Print the arrays.

@array1 = ("A".."J");
@array2 = @array1[2, 4, 6];
print("@array1\n");
print("@array2\n");
This program produces the following output:
A B C D E F G H I J
C E G

Example: Assigning an Array to Scalar Variables

At times, you may want to take array elements and assign them to scalar variables. The ability is especially useful inside functions and you'll read about that usage in Chapter 5,"Functions" .

It's also useful when you want to make your code more readable. So that instead of referring to the 3rd element of an array as $array[3], you can refer to the value as $town or whatever variable name you use.

In this next example, we'll take an array that holds an address and separate the elements into four scalar variables.

Pseudocode

Create an array with Tom Jones' address.

Assign each element of the array to a separate scalar variable.

Print the scalar variables.

@array = ("Tom Jones", "123 Harley Lane", "Birmingham", "AR");
($name, $street, $town, $state) = @array;
print("$name, $street, $town, $state\n");
This program prints:
Tom Jones, 123 Harley Lane, Birmingham, AR
The first element of @array is assigned to the first scalar on the left side of the assignment operator. Because the scalars are surrounded by parentheses, Perl sees them as another list. If you couldn't do this type of multiple array element to multiple scalar assignment, you would have to do this:
@array = ("Tom Jones", "123 Harley Lane", "Birmingham", "AR");
$name   = $array[0];
$street = $array[1];
$town   = $array[2];
$state  = $array[3];
print("$name, $street, $town, $state\n");
I think that the first example is easier to understand, don't you? If the array has more elements than scalars, the extra elements are ignored. Conversely, if there are not enough elements, some of the scalar variables will have an undefined value.

Tip
You can also use the array slice and range operators with this type of assignment also.

Order of Precedence

We briefly touched on the order of precedence concept at the beginning of the chapter. Now that you are familiar with most of Perl's operators we can explore the subject in more detail. Table 4.12 is an exhaustive list of operators and how they rank in terms of precedence - the higher the level, the higher their precedence. Operators at the same level have same precedence and are evaluated from left to right. Otherwise, higher precedence levels are evaluated first.

Perl uses associativity to decide which operators and operators belong together. For instance, the unary minus operator has an associativity of right to left because it affects the operand immediately to its right.

Table 4.12-The Order of Precedence and Associativity for Perl Operators
Level Operator Description Associativity
22 (), [], {} Function Calls, Parentheses, Array subscripts Left to right
21 > infix dereference operator Left to right
20 ++, -- Auto increment, Auto decrement None
19 ** Exponentiation Right to left
18 !, ~, +, -, \ Logical not, bitwise not, unary plus, unary minus, reference Right to left
17 =~, !~ Match, Not match - These operators are described in Chapter 10. Briefly, they tell Perl to do pattern matching, substitution or translation on a specific variable instead of the $_ special variable. Left to right
16 *, /, % x Multiply, Divide, Modulus, Repetition Left to right
15 +, -, . Add, Subtract, String concatenation Left to right
14 <<, >> Bitwise left shift, Bitwise right shift Left to right
13
File test operators None
12
Relational Operators None
11
Equality Operators None
10 & Bitwise and Left to right
9 |, ^ Bitwise or, Bitwise xor Left to right
8 && Logical and Left to right
7 || Logical or Left to right
6 .. Range operator None
5 ?: Ternary or conditional operator Right to left
4
Assignment Operators Right to left
3 , Comma operator Left to right
2 not Low precedence logical operators Left to right
1 and Low precedence logical operators Left to right
0 or, xor Low precedence logical operators Left to right

Note
The printed version of this book listed the not, and, or, and xor operators at the same precedence level. Randal Schwartz was kind enough to point out this problem.

Operators that are not discussed in this chapter are discussed elsewhere in this book. Table 4.1, at the beginning of the chapter, points out where you can get more information on those operators. In addition, you can read about the low precedence logical operators in Chapter 13, "Handling Exceptions and Signals."

Example: Order of Precedence

While it is not possible to show examples of all the ramifications of operator precedence, we can look at one or two so that you can get a feel for the concept.

First, an example using the ternary operator and various arithmetic operators.

Pseudocode

Assign values to $firstVar and $secondVar.

Assign either a 1 or 0 to $thirdVar based on the evaluation of the condition 34 + $firstVar-- + $secondVar ? 1 : 0.

Print $thirdVar.

$firstVar = 4;
$secondVar = 1;
$thirdVar = 34 + $firstVar-- + $secondVar ? 1 : 0;
print("$thirdVar\n");
The program produces the following output:
1
The ternary operator has a precedence level of 5, every other operator has a higher precedence level and will be evaluated first.

Pseudocode

Assign values to $firstVar and $secondVar.

Assign either a 1 or 0 to $thirdVar based on the evaluation of the condition 34 + $firstVar-- + ($secondVar ? 1 : 0).

Print $thirdVar.

$firstVar = 4;
$secondVar = 1;
$thirdVar = 34 + $firstVar-- + ($secondVar ? 1 : 0);
print "$thirdVar\n";
The program produces the following output
39
This program results in a value of 39 for $thirdVar because the parentheses operators have a precedence level of 22. They serve to isolate regions of the statements and tell Perl to evaluate the stuff inside before evaluating the rest of the statement.

Caution
Remember that these examples are contrived to show a point. I don't program in this manner. I recommend using parentheses to tell Perl exactly how you want your code to be evaluated. So I would normally do the following:

$thirdVar = 34 + $firstVar + ($secondVar ? 1 : 0);
$firstVar--;
The decrementing of $firstVar has been pulled out the first line because using the post-decrement operator has no effect on the first line and make it harder to understand.

Here is a example of operator precedence using the exponentiation operator. This also shows you how to determine operator precedence on your own.

Pseudocode

Assign an expression to $firstVar.

Assign an expression to $secondVar using parenthesis to indicate a preferred precedence order.

Assign an expression to $thirdVar using parenthesis in a different manner to indicate a preferred precedence order.

Print the variables.

$firstVar = -2 ** 4;
$secondVar = -(2 ** 4);
$thirdVar = (-2) ** 4;

print "$firstVar\n";
print "$secondVar\n";
print "$thirdVar\n";
The program produces the following output:
-16
-16
16
From this example, you can see the precedence level for exponentiation is higher than unary minus because the first and second variables are equal.

Tip
If you always use parentheses to indicate how you want the operators to be evaluated, you'll never need to worry about operator precedence in your code.

Summary

This chapter was pretty long and you've seen quite a few examples of how operators can be used. Let's review.

You learned that operators are used to tell Perl what actions to perform. Some operators take precedence over others so that they and their operands will be evaluated first. An operand can be as simple as the number 10 or very complex - involving variables, literals, and other operators. This means that they are recursive in nature.

Perl has many different types of operators: arithmetic, assignment, binding, bitwise, comma, file test, list, logical, postfix, range, reference, relational (both numeric and sting), string, and ternary. Most of these operator types were discussed in this chapter, and the rest are scattered throughout the rest of the book. Table 4.1 lists the page numbers where more information can be found on those operators not covered in this chapter.

The bulk of the chapter talked about various types of operators. Starting with binary arithmetic operators, and then unary arithmetic operators. You were introduced to the pre- and post-increment and pre- and post-decrement operators. Next, came the logical operators and the bitwise operators. Sometimes, the bitwise shift operators are used when fast integer multiplication and division is needed.

Then, came numeric and string relational operators. Followed by the ternary operator. The ternary operator was used to show you what an lvalue is. An lvalue is the value on the left sign of an assignment operator. It must evaluate to some variable that Perl can use to hold a value.

The range operator was used to create sequential elements of an array, the concatenation operator was used to join two strings together, and the string repetition operator was used to repeat a string a given number of times.

Then you looked at the list of assignment operators, most of which were shortcuts to reduce typing and clarify the meaning of the assignment.

And finally, you saw a detailed list of Perl's operators and their order of precedence. Several examples were given to illustrate how precedence worked. My recommendation is to use parentheses to explicitly tell Perl how which order to evaluate operators.

The next chapter, "Functions," will look at how functions and list operators are the same thing. And you will be introduced to subroutines and parameters.

Review Questions

  1. What are three arithmetic operators?

  2. What does the x operator do?

  3. What does it mean to pre-decrement a variable?

  4. What is the value of 1 ^ 1?

  5. What is the value of 1 << 3?

  6. What is the ternary operator used for?

  7. Can the x operator be used with arrays?

  8. What is the precedence level of the range operator?

  9. What is the value of 2 * 5 + 10?

  10. What is the value of 65 >> 1?

  11. What is the spaceship operator used for?

  12. If an array were defined with ("fy".."gb"), what would its elements be?

Review Exercises

  1. Assign a value to $firstVar using both division and subtraction.

  2. Using the post-decrement operator, subtract one from $firstVar.

  3. Write a program that assigns values to $firstVar and $secondVar and uses the >= operator to test their relationship to each other. Print the resulting value.

  4. Use the **= assignment operator to assign a value to $firstVar.

  5. Use the ternary operator to decide between to different value.

  6. Write a program that assigns values to $firstVar and $secondVar and uses the <=> operator to test their relationship to each other. Print the resulting value.

  7. Use the concatenation operator to join the following values together: "A" x 4 and "B" x 3.

  8. Use the exponentiation operator to find the value of 2 to the 5th power.

  9. Write an assignment statement that uses the && and || and ! operators.

  10. Write a program that prints the value of the fifth bit from the right in a scalar variable.

  11. Write a program that uses a bitwise assignment to set the fifth bit from the right in a scalar variable.

  12. Write a program that shows the difference in operator precedence between the % operator and the && operator.

Top of Page | Sections | Chapters | Copyright