home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam  

2.6 Scalar Operators and Functions

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 (as in C or FORTRAN), which takes a variable name on the left side and gives it the value of the expression on the right, like so:

$a = 17;     # give $a the value of 17
$b = $a + 3; # give $b the current value of $a plus 3 (20)
$b = $b * 2; # give $b the value of $b multiplied by 2 (40)

Notice that the last line uses the $b variable twice: once to get its value (on the right side of the = ), and once to define where to put the computed expression (on the left side of the = ). This is legal, safe, and in fact, rather common. In fact, the practice is so common that we'll see in a minute that we can write this expression using a convenient shorthand.

You may have noticed that scalar variables are always specified with the leading $ . In batch files, Java, or C, you don't need the $ at all. If you bounce back and forth a lot, you'll find yourself typing the wrong things occasionally. This is expected. (Our solution was to stop writing batch files and C programs, but that may not work for you.)

You may use a scalar assignment as a value as well as an operation, as in C. In other words, $a=3 has a value, just as $a+3 has a value. The value is the value assigned, so the value of $a=3 is 3 . Although this usage 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:

$b = 4 + ($a = 3);      # assign 3 to $a, then add 4 to that
                        # resulting in $b getting 7
$d = ($c = 5);          # copy 5 into $c, and then also into $d
$d = $c = 5;            # the same thing without parentheses

That last example works because assignment is right-associative.

2.6.1 Binary Assignment Operators

Expressions like $a = $a + 5 (in which the same variable appears on both sides of an assignment) occur so frequently 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:

$a = $a + 5;  # without the binary assignment operator

+= 5;      # with the binary assignment operator

And so are these:

$b = $b * 3;
$b *= 3;

In each case, the operator causes the existing value of the variable to be altered in some way, not 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

.= " ";        # same thing with assignment operator

Nearly all binary operators are valid in this way. For example, a raise to the power of operator is written as **= . So, $a **= 3 means "raise the number in $a to the third power, placing the result back in $a ."

Like the simple assignment operator, each of these operators has a value as well: the new value of the variable. For example:

$a = 3;
$b = ($a += 4); # $a and $b are both now 7

2.6.2 Autoincrement and Autodecrement

As if it weren't already easy enough to add one to $a by saying $a += 1 , Perl goes one step further and shortens even this method. The ++ operator (called the autoincrement operator) adds one to its operand, and returns the incremented value, like so:

$a += 1;   # with assignment operator
++$a;      # with prefix autoincrement
$d = 17;
$e = ++$d; # $e and $d 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. You may also use the autoincrement 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:

$c = 17;
$d = $c++; # $d is 17, but $c is now 18

Because the value of the operand changes, the operand must be a real scalar variable, not just an expression. You cannot say ++16 to get 17 , nor can you say ++($a+$b) to somehow get one more than the sum of $a and $b .

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:

$x = 12;
--$x; # $x is now 11
$y = $x--; # $y is 11, and $x 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.[ 10 ]

[10] Autoincrement even works on strings. See Programming Perl or perlop for related information.

2.6.3 The chop( ) and chomp( ) Functions

A useful built-in function is chop() . This prefix function takes a single argument within its parentheses - the name of a scalar variable - and removes the last character from the string value of that variable. For example:

$x = "hello world";
chop($x); # $x is now "hello worl"

Note that the value of the argument is altered here, hence the requirement for a scalar variable, rather than simply a scalar value. It would not make sense, for example, to write chop('suey') to change it to 'sue' , because there is no place in which to save the value. Besides, you could have just written 'sue' instead.

The value returned is the discarded character (the letter d in world above). As a result, the following code is probably wrong:

$x = chop($x);  # WRONG: replaces $x with its last character
chop($x);       # RIGHT: as above, removes the last character

If you give chop() an empty string, it does nothing, returns nothing, and doesn't raise an error or even whimper a bit.[ 11 ] Most operations in Perl have sensible boundary conditions; in other words, you can use them right up to the edges (and beyond), frequently without complaint. Some have argued that this is one of Perl's fundamental flaws, while others write screaming programs without having to worry about the fringes. You decide which camp you wish to join.

[11] Unless you are using the sanity-saving -w switch.

When you chop a string that has already been chopped, another character disappears off into "bit heaven." For example:

$a = "hello world\n";
chop $a; # $a is now "hello world"
chop $a; # oops! $a is now "hello worl"

If you're not sure whether the variable has a newline on the end, you can use the slightly safer chomp() function, which removes only a newline character,[ 12 ] like so:

[12] Or whatever the input record separator $\ is set to.

$a = "hello world\n";
chomp ($a); # $a is now "hello world"
chomp ($a); # aha! no change in $a

2.6.4 Interpolation of Scalars into Strings

When a string literal is double quoted, it is subject to variable interpolation (besides being checked for backslash escapes). This means that the string is scanned for possible scalar variable[ 13 ] names - namely, a dollar sign followed by letters, digits, and underscores. When a variable reference is found, it is replaced with its current value (or an empty string if the variable has not yet been assigned a value). For example:

[13] The string is actually scanned for array variables as well, but we won't know about those until Chapter 3, Arrays and List Data .

$a = "fred";
$b = "some text $a";             # $b is now "some text fred"
$c = "no such variable $what";   # $c is "no such variable "

The text that replaces the variable is not rescanned; even if there are dollar signs in the replaced value, no further replacement occurs:

$x = '$fred';  # literally a dollar sign followed by "fred"
$y = "hey $x"; # value is 'hey $fred': no double substitution

To prevent the substitution of a variable with its value, you must either alter that part of the string so that it appears in single quotes, or precede the dollar sign with a backslash, which turns off the dollar sign's special significance:

$fred    = 'hi';
$barney  = "a test of " . '$fred';# literally: 'a test of $fred'
$barney2 = "a test of \$fred";    # same thing

The variable name will be the longest possible variable name that makes sense at that part of the string. This can be a problem if you want to follow the replaced value immediately with some constant text that begins with a letter, digit, or underscore. As Perl scans for variable names, it would consider those characters to be additional name characters, and this result is not what you want. Perl provides a delimiter for the variable name. Simply enclose the name of the variable in a pair of curly braces. Or, you can end that part of the string and start another part of the string with a concatenation operator:

$fred = "pay"; $fredday = "wrong!";
$barney = "It's $fredday";          # not payday, but "It's wrong!"
$barney = "It's ${fred}day";        # now, $barney gets "It's payday"
$barney2 = "It's $fred"."day";      # another way to do it
$barney3 = "It's " . $fred . "day"; # and another way

You can use the case-shifting string escapes to alter the case of letters that are brought in with variable interpolation.[ 14 ] For example:

[14] You may find the uc , ucfirst , lc , and lcfirst operators easier to use.

$bigfred = "\Ufred";                  # $bigfred is "FRED"
$fred = "fred"; $bigfred = "\U$fred"; # same thing
$capfred = "\u$fred";                 # $capfred is "Fred"
$barney = "\LBARNEY";                 # $barney is now "barney"
$capbarney = "\u\LBARNEY";            # $capbarney is now "Barney"
$bigbarney = "BARNEY"; $capbarney = "\u\L$bigbarney"; # same

As you can see, the case-shifting string escapes are remembered within a string until they are used, so even though the first letter of BARNEY doesn't follow the \u , it remains uppercase because of the \u .

The term variable interpolation is often used interchangeably with double-quote interpolation , because strings that are double quoted are subject to variable interpolation. So too, are backquoted strings, as described in Chapter 14 .