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 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 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, it's so common that we'll see in a minute that we can write this using a convenient shorthand.
You may have noticed that scalar variables are always specified with the leading $
. In shell programming, you use $
to get the value, but leave the $
off to assign a new value. In Java or C, you leave the $
off entirely. 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 shell, awk, and C programs, but that may not work for you.)
A scalar assignment may be used 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 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.
Expressions like $a = $a + 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:
$a = $a + 5; # without the binary assignment operator $a += 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, 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, $a **= 3
means "raise the number in $a
to the third power, placing the result back in $a
".
Like the simple assignment operator, these operators have a value as well: the new value of the variable. For example:
$a = 3; $b = ($a += 4); # $a and $b are both now 7
As if it weren't already easy enough to add one to $a
by saying $a += 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:
$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. 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:
$c = 17; $d = $c++; # $d is 17, but $c 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 ++($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 (1) for that.
A useful built-in function is chop
. This 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). This means that 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 chop
is given an empty string, it does nothing, and 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
operator, which removes only a newline character,[12] like so:
$a = "hello world\n"; chomp ($a); # $a is now "hello world" chomp ($a); # aha! no change in $a
[12] Or whatever the input record separator $/is set to.
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:
$a = "fred"; $b = "some text $a"; # $b is now "some text fred" $c = "no such variable $what"; # $c is "no such variable "
[13] And array variables, but we won't discuss those until Chapter 3, Arrays and List Data.
The text that replaces the variable is not rescanned; that is, 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, which 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
The case-shifting string escapes can be used to alter the case of letters brought in with variable interpolation.[14] For example:
$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
[14] You may find the
uc
,ucfirst
,lc
, andlcfirst
functions easier to use.
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, described in Chapter 14.