| |||
Links Sections Chapters Part I: Basic Perl 02-Numeric and String
Literals Part II: Intermediate Perl Part III: Advanced Perl 13-Handling Errors and
Signals Part IV: Perl and the Internet 21-Using Perl with Web
Servers Appendixes |
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 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. |
Operator | Description |
---|---|
op1 + op2 | Addition |
op1 - op2 | Subtraction |
op1 * op2 | Multiplication |
op1 ** op2 | Exponentiation |
op1 / op2 | Division |
op1 % op2 | Modulus |
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
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 |
|
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.
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.
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 |
|
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.
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 |
|
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.
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 |
|
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.
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.
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.
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!"); }; |
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:
zeroYou could replace the 10 in the first line with "ten", 'ten', or any non-zero, non-null value.
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.
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;
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:
32Let'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:
16Since 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:
1024The 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.
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. |
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.
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 1The -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).
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.
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 1Notice 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
1which means that "AA" is greater than " A" according to the criteria used by the cmp operator.
CONDITION-PART ? TRUE-PART : FALSE-PARTwhich 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.
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. |
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. |
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
AAABBBNotice 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.
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:
1111111The 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 11You 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. |
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.
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.
| ||
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.
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 10And 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 10An 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 10Notice 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 10Figure 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
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, ARThe 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.
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.
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."
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:
1The 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
39This 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 16From 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.
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.