The most common operation on a scalar variable is assignment, which is the way to give a value to a variable. The Perl assignment operator is the equal sign (much like other languages), which takes a variable name on the left side and gives it the value of the expression on the right. For example:
$fred = 17; # give $fred the value of 17 $barney = "hello"; #give $barney the five-character string 'hello' $barney = $fred + 3; # give $barney the current value of $fred plus 3 (20) $barney = $barney * 2; # $barney is now $barney multiplied by 2 (40)
Notice that last line uses the $barney variable twice: once to get its value (on the right side of the equals sign), and once to define where to put the computed expression (on the left side of the equals sign). This is legal, safe, and in fact, rather common. In fact, it's so common that we we can write it using a convenient shorthand, as we'll see in a minute.
A scalar assignment may be used as a value as well as an operation, as in C. In other words, $fred=3 has a value, just as $fred+3 has a value. The value is the value assigned, so the value of $fred=3 is 3. Although this may seem odd at first glance, using an assignment as a value is useful if you wish to assign an intermediate value in an expression to a variable, or if you simply wish to copy the same value to more than one variable. For example:
$barney = 4 + ($fred = 3); # assign 3 to $fred, then add 4 to that # resulting in $barney getting 7 $dilbert = ($charlie = 5); # copy 5 into $charlie, and then also into $dilbert $dilbert = $charlie = 5; # the same thing without parentheses
Expressions like $fred = $fred + 5 (where the same variable appears on both sides of an assignment) occur frequently enough that Perl has a shorthand for the operation of altering a variable: the binary assignment operator. Nearly all binary operators that compute a value have a corresponding binary assignment form with an appended equal sign. For example, the following two lines are equivalent:
$fred = $fred + 5; # without the binary assignment operator $fred += 5; # with the binary assignment operator
These are also equivalent:
$barney= $barney * 3; $barney *= 3;
In each case, the operator causes the existing value of the variable to be altered in some way, rather than simply overwriting the value with the result of some new expression.
Another common assignment operator is the string concatenate operator:
$str = $str . " "; # append a space to $str $str .= " "; # same thing with assignment operator
Nearly all binary operators are valid this way. For example, a raise to the power of operator is written as **=. So, $fred **= 3 means "raise the number in $fred to the third power, placing the result back in $fred".
Like the simple assignment operator, these operators have a value as well: the new value of the variable. For example:
$fred = 3; $barney = ($fred += 4); # $fred and $barney are both now 7
As if it weren't already easy enough to add one to $fred by saying $fred += 1, Perl goes one further and shortens even this up. The ++ operator (called the autoincrement operator) adds one to its operand, and returns the incremented value, like so:
$fred += 1; # with assignment operator ++$fred; # with prefix autoincrement $dilbert = 17; $ethel = ++$dilbert; # $ethel and $dilbert are both 18 now
Here, the ++ operator is being used as a prefix operator; that is, the operator appears to the left of its operand. The autoincrement may also be used in a suffix form (to the right of its operand). In this case, the result of the expression is the old value of the variable before the variable is incremented. For example:
$charlie = 17; $dilbert = $charlie++; # $dilbert is 17, but $charlie is now 18
Because the value of the operand changes, the operand must be a scalar variable, not just an expression. You cannot say ++16 to get 17, nor can you say ++($fred+$barney) to somehow get one more than the sum of $fred and $barney.
The autodecrement operator (--) is similar to the autoincrement operator, but subtracts one rather than adding one. Like the autoincrement operator, the autodecrement operator has a prefix and suffix form. For example:
$xray = 12; --$xray; # $xray is now 11 $yahoo = $xray--; # $yahoo is 11, and $xray is now 10
The autoincrement and autodecrement operators also work on floating-point values. So autoincrementing a variable with the value 4.2 yields 5.2 as expected.[1]
Operator precedence determines which operations in a complex group of operations happen first. For example, in the expression 2+3*4, do we perform the addition first or the multiplication first? If we did the addition first, we'd get 5*4, or 20. But if we did the multiplication first (as we were taught in math class) we'd get 2+12, or 14. Fortunately, Perl chooses the common mathematical definition, performing the multiplication first. Because of this, we say multiplication has a higher precedence than addition.
You can override the order defined by precedence using parentheses. Anything in parentheses is completely computed before the operator outside of the parentheses is applied (just as you learned in math class). So if you really want the addition before the multiplication, you can say (2+3)*4, yielding 20. Also, if you want to demonstrate that multiplication is performed before addition, you could add a decorative but functionless set of parentheses in 2+(3*4).
While precedence is simple for addition and multiplication, we start running into problems when faced with, say, string concatenation compared with exponentiation. The proper way to resolve this is to consult the official, accept-no-substitutes Perl operator precedence chart, shown in Table 2.3. (Note that some of the operators have not yet been described, and in fact, may not even appear anywhere in these lessons, but don't let that scare you from reading about them in the perlop manpage.) And C programmers: Rejoice! Operators that are available in both Perl and C have the same precedence and associativity in both.
| Associativity | Operators |
|---|---|
| Left | parentheses and arguments to list operators |
| Left |
->
(method call, dereference)
|
| Nonassociative |
++
--
(autoincrement, autodecrement)
|
| Right |
**
(exponentiation)
|
| Right |
!
~
\
+
-
(logical not, bit-not, reference operator, unary plus, unary minus)
|
| Left |
=~
!~
(matches, doesn't match)
|
| Left |
*
/
%
x
(multiply, divide, modulus, string replicate)
|
| Left |
+
-
.
(add, subtract, string concatenate)
|
| Left | << >> |
| Nonassociative |
Named unary operators (like chomp, -X filetests,
rand) |
| Nonassociative | < > <= >= lt gt le ge |
| Nonassociative | == != <=> eq ne cmp |
| Left |
&
(bit-and)
|
| Left |
|
^
(bit-or, bit-xor)
|
| Left |
&&
(logical and)
|
| Left |
||
(logical or)
|
| Nonassociative |
.. ...
(noninclusive and inclusive range)
|
| Right |
?:
(ternary if-then-else)
|
| Right |
=
+=
-=
*=
, etc. (assignment and binary-assignment)
|
| Left |
,
=>
(comma and comma-arrow)
|
| Nonassociative | List operators (rightward) |
| Right |
not
(logical not)
|
| Left |
and
(logical and)
|
| Left |
or
xor
(logical or, logical xor)
|
In the chart, any given operator has higher precedence than those listed below it, and lower precedence than all of the operators listed above it. Operators at the same precedence level resolve according to rules of associativity instead.
Just like precedence, associativity resolves the order of operations when two operators of the same precedence compete for three operands:
2 ** 3 ** 4 # 2 ** (3 ** 4), or 2 ** 81, or approx 2.41e24 (right associative)
72 / 12 / 3 # (72 / 12) / 3, or 6/3, or 2 (left associative)
30 / 6 * 3 # (30/6)*3, or 15
In the first case, the ** operator has right associativity, so the parentheses are implied on the right. Comparatively, the * and / operators have left associativity, yielding a set of implied parentheses on the left.
So should you just memorize the precedence chart? No! Nobody actually does that. Instead, just use parentheses when you don't remember the order of operations, or when you're too busy to look in the chart. After all, if you can't remember it without the parentheses, your maintenance programmer is going to have the same trouble. So be nice to your maintenance programmer.
Next: Scalar Functions
[1]
Autoincrement even works on strings. See Programming Perl or
perlop (1) for that.
Return to the page from whence you came
[2]
Unless you are using the sanity-saving -w switch
Return to the page from whence you came
[3]
Or whatever the input record separator $/is set to.
Return to the page from whence you came
[4]
Normally, there's no "end-of-file" when the input comes from the keyboard, but input
may have been redirected to come from a file. Or the user may have pressed the
key that the system recognizes to indicate end-of-file.
Return to the page from whence you came