| |||
Links Sections Double Quoted Strings Revisited 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 |
In the last chapter, you learned about literals - values that don't change while your program runs because you represent them in your source code exactly as they should be used. Most of the time, however, you will need to change the values that your program uses. To do this, you need to set aside pieces of computer memory to hold the changeable values. And you need to keep track of where all these little areas of memory are so that you can refer to them while your program runs.
Perl, like all other computer languages, uses variables to keep track of the usage of computer memory. Every time you need to store a new piece of information, you assign it to a variable.
You've already seen how Perl uses numbers, strings, and arrays. Now, you'll see how to use variables to hold this information. Perl has three types of variables:
Variable Type | Description |
---|---|
Scalars | Holds one number or string value at a time. Scalar variable names always begin with a $. |
Arrays | Holds a list of values. The values can be numbers, strings, or even another array. Array variable names always begin with a @. |
Associative Arrays | Uses any value as an index into an array. Associative array variable names always begin with a %. |
The different beginning characters help you understand how a variable is used when you look at someone else's Perl code. If you see a variable called @Value, you automatically know that it is an array variable.
They also provide a different namespace for each variable type. Namespaces separate one set of names from another. Thus, Perl can keep track of scalar variables in one table of names (or namespace) and array variables in another. This lets you use $name, @name, and %name to refer to different values.
Tip |
I recommend against using identical variable names
for different data types unless you have a very good reason to do so. And
if you do need to use the same name, try using the plural of it for the
array variable. For example, use $name for the scalar variable name and
@names for the array variable name. This might avoid some confusion about
what your code does in the future. |
Note |
Variable names in Perl are case-sensitive. This
means that $varname, $VarName, $varName, and $VARNAME all refer to
different variables. |
Each variable type will be discussed in its own section. You'll see how to name variables, set their values, and some of the uses to which they can be put.
Tip |
If you have programmed in Visual Basic, you need to
be especially careful when naming variables. Just remember that all
scalars begin with a $, not just strings, and that the $ starts the name;
it doesn't end it. |
Let's jump right in a look at some variable names.
Pseudocode |
This scalar variable will hold the number of rooms. This scalar variabe will hold the title of a book. This scalar variable conflicts with a Perl special variable that you'll learn about in Chapter 11, "Using Special Variables." |
$numberOfRooms
$bookTitle
$0
Note |
It is generally a good idea to stay away from short
variable names. Longer variable names are more descriptive and aid in
understanding programs.
Let me say a quick word about variable names. I always start my
variable names with a lower case letter and then make the first letter of
each "word" in the name upper case. Some programmers like to separate each
word with an underscore. For example, $numberOfRooms would look like
$number_of_rooms. Choose a method that you feel comfortable with and then
stick with it. Being consistent will make your program more
understandable. |
Most programmers try to use descriptive names for their variables. There is no practical limit to the length of a Perl variable name, but I like to keep them under 15 characters. Anything longer than that means that it will take a while to type them and increases the chances of spelling errors.
Pseudocode |
Assign a value of 23 to a variable called $numberOfRooms. Assign a value of Perl by Example to a variable called $bookTitle. |
$numberOfRooms = 23;
$bookTitle = "Perl by Example";
Notice that you are assigning literal
values to the variables. After assigning the values you can then change them.
Pseudocode |
Assign a value of 23 to a variable called $numberOfRooms. Add 5 to the $numberOfRooms variable. |
$numberOfRooms = 23;
$numberOfRooms = $numberOfRooms + 5;
Note |
In Perl, you never have to declare, define, or
allocate simple data types (for example: scalars, arrays, or associative
arrays). When you use the variable for the first time, Perl either assigns
it a zero if you need a number, or an empty list if you need an array.
Using a variable name is equivalent to defining
it. |
Tip |
Letting Perl automatically initialize variables is
fine for small programs. However, if you write professional programs that
need to be maintained, you'll want to explicitly declare variables using
the my() function. Explicitly declaring functions will reduce errors and
improve the internal documentation of your programs. The my() function is
discussed in Chapter 5, "Functions."
|
Tip |
I remember that the @ sign starts array variables
because "at" and "array" start with the same letter. Simple...but it works
for me. |
The rules for naming array variables are the same as those for scalar variables. There are no rules. Well, none that you need to worry about. In fact, let's skip looking at variable names and get right to assigning arrays to variables, instead.
We'll use one of the examples from Chapter 2, "Numeric and String Literals" - reworked a little - here so that you'll already be familiar with part of the example.
Caution |
The printing of the newline character is separated from
the printing of the array for a reason. It has to do with how Perl
interprets variables in different contexts. If you tried to use print
@numberArray . "\n"; Perl thinks that you want to use @numberArray in a
scalar context and won't print the elements of the array. It will print
the number of elements instead. See the section called "Example: Determine
the Number of Elements in an Array" later in this
chapter. |
Pseudocode |
Assign values to array variables. Print the array variables. |
Listing 3.1 - 03LST01.PL - Assigning Values to Array Variables. |
|
This program will display
Here is an empty array:0<-- Nothing there!
12121234.340.0233
Thisisanarrayofstrings
This30isamixed arrayof8items
In this example, we assign literal values to array variables and then display them using the print command. This is very similar to what we did in Chapter 1, "Getting Your Feet Wet," except that we are temporarily storing the array values into variables before printing them.
Suppose that you want to create one array from two smaller ones. You can do this by using the sub-arrays inside the assignment statement.
Pseudocode |
Create two small arrays using the range operator. Create an array that consists of the two small arrays. Print the array. |
@smallArrayOne = (5..10);
@smallArrayTwo = (1..5);
@largeArray = (@smallArrayOne, @smallArrayTwo);
print @largeArray;
When run, this program prints the array (5, 6, 7, 8,
9, 10, 1, 2, 3, 4, 5). Notice that the 5 is duplicated in the new array and that
the elements are still in the same order as the sub-arrays. When you concatenate
arrays in this manner, Perl does not sort them or modify their contents in any
way.
Listing 3.2 creates an array of five elements and then prints each individual element.
Pseudocode |
Create an array with five elements. Print the array. Print each element of the array. |
Listing 3.2 - 03LIST02.PL - Accessing Array Elements |
|
Listing 3.2 will print the following:
12345
1
2
3
4
5
Perl array indexes start at 0 - well, they actually start at $[ - but
for the moment zero is good enough. Almost every Perl program uses zero as the
base array subscript.
Note |
The special variable, $[, is used to hold the base
array subscript; usually it is zero. However, it can be changed to any
integer you want. Even negative ones. Using a negative base array
subscript will probably make your programs hard to understand and I
recommend against it. Other special variables are mentioned in Chapter 11,
"Using Special
Variables." |
You can replace the numeric literal indexes in the above example with scalar variables. You can say:
$index = 2;
@array = (1..5);
print $array[$index]; print "\n";
which would print 3.
Tip |
Using a negative subscript may come in handy if you
need a fast way to get the value of the last element in an
array. |
The program in Listing 3.3 assigns a five element array to @array. Then, it uses print statement and negative subscripts to print each array element in reverse order.
Listing 3.3 - 03LIST03.PL - Accessing Array Elements Using Negative Subscripts |
|
Listing 3.3 will print the following:
12345
5
4
3
2
1
In fact, any time that an array is used when a scalar is needed, the value used will be the number of array elements.
Pseudocode |
Create an array with five elements Assign the array size to the $numberOfElements scalar variable. Multiply the array size by 2 and assign that value to $doubleTheSize. Print the scalar variables. |
@array = (1..5);
$numberOfElements = @array;
$doubleTheSize = 2 * @array;
print "The number of array elements is: " . $numberOfElements . "\n";
print "Double the number of array elements is: " . $doubleTheSize . "\n";
When
this program runs, it will assign a value of 5 to $numberOfElements and 10 to
$doubleTheSize.
Tip |
Perl has the powerful ability to return the number
of array elements when the array variable is used in a scalar context.
However, this ability can be confusing while looking at someone else's
program if you don't remember that there is a difference between scalar
contexts and array contexts. |
Pseudocode |
Create a four element array and assign it to
@array. Use an array slice to assign the first and third elements to $first and $third. Use an array slice to assign the second half of the array to @half. Print @array, $first, $third and @half to verify their values. Tranpose the first and last elements in @array. Print @array to verify that the elements have been switched. |
@array = ("One", "Two", "Three", "Four");
($first, $third) = @array[0, 2];
@half = @array[2, 3];
print("\@array=@array\n");
print("\$first=$first \$third=$third\n");
print("\@half=@half\n");
@array[0, 3] = @array[3, 0];
print("\@array=@array\n");
This program will display
@array=One Two Three Four
$first=One $third=Three
@half=Three Four
@array=Four Two Three One
The array elements are displayed separated by
spaces because the array variable was enclosed in double quotes. The section, Example:
Variable Interpolation discusses this issue in more detail. You won't really
understand the power of array slices until you learn about functions in Chapter
5. At that point, you'll see that functions (sub programs that you invoke using
a function name) can return a value. And that the return value might be an
array. When calling a function that returns the time and date in an array, a
slice can be used to "grab" just those elements that you are interested in. For
example, just the year or just the hour.
You will see associative arrays called hashes at times. The term "Hash" refers to how associative array elements are stored in memory. "Hash" is also much shorter than "associative array" and therefore much easier to type and talk about.
Pseudocode |
Create an associative array with three elements. Each element consists of two values: the lookup key and its associated value. Add a single element to the associative array. |
%associativeArray = ("Jack A.", "Dec 2", "Joe B.",
"June 2", "Jane C.", "Feb 13");
$associativeArray{"Jennifer S."} = "Mar 20";
print "Joe's birthday is: " . $associativeArray{"Joe B."} . "\n";
print "Jennifer's birthday is: " . $associativeArray{"Jennifer S."} . "\n";
This
program will print the following:
Joe's birthday is: June 2
Jennifer's birthday is: Mar 20
Perl will extend the associative array
as needed when you assign values to keys. An internal table is used to keep
track of which keys are defined. If you try to access an undefined key, Perl
will return a null or blank string.
You can do a lot with associative arrays, but first you need more background in operators, functions, and statements. We'll handle these topics in future chapters. In the next section, we look at string literals and how they interact with variables.
Tip |
Until this time, each time you printed an array all
of the elements were mashed together (concatenated). Having the array
element printed without delimiting spaces made determining the individual
items very difficult. If, when printing, you enclose the array in quotes
Perl will automatically separate the array elements with a
space. |
Pseudocode |
Create a five element array. Print the element with spaces between the elements. |
@array = (1..5);
print "@array\n";
This program will print:
1 2 3 4 5
Perl runs into a problem when you want to use a variable
and then append some letters to the end. Let's illustrate this with scalar
variables.
Pseudocode |
Assign the value large to a scalar variable. Print a string with an embedded variable. |
$word = "large";
print "He was a $wordr fellow.";
This program will print:
He was a fellow.
In this example, Perl looks for the variable
$wordr - obviously not what I intended to do. I meant for the string "He was a
larger fellow" to print. This problem can be corrected by doing the following:
$word = "large";
print "He was a " . $word . "r fellow.";
Because the variable is
separate, Perl sees the correct variable name. Then the string concatenation
operator joins the three strings together. This method of programming makes it
very easy to see where the variable is.
Remember when I said that Perl enables you to do something in many different ways? You could also do the following:
print "He was a ${word}r fellow.";
The curly braces around the
variable name tell Perl where the name starts and ends.
Note |
If you're ever on IRC and see longhair_ or
Kirby Hughes (khughes@netcom.com) tell him I said "thanks." He
remembered that curly braces can be used in this
manner. |
At times, you may need to print array elements separated by commas or another character. The $" variable controls which separator Perl uses when printing your array. The variable is normally set equal to the space character. However, you may set it to any characters you'd like.
Pseudocode |
Set the $" special variable to the comma character. Create a five element array. Print the element with commas between the elements. |
$" = ",";
@array = (1..5);
print "@array\n";
This program will print:
1,2,3,4,5
Of course, since $" is a scalar variable you could also
assign a longer string to it. For instance, you could use $" = ", " to add both
a comma and a space between the array elements.
You read about three types of variables: Scalars, arrays, and associative arrays. Each variable type has its own unique character that is used to begin a variable names. Scalars use a $. Arrays use an @. And associative arrays use a %.
Tip |
When I first started to learn Perl, I found it
difficult to remember which character begins which variable type. Then, I
saw this chart on the Internet and things became clearer:
$ = "the" (singular) @ = "those" (plural) % = "relationship" |
Each variable type must start with a different character that uses a separate namespace. This means that $varName and @varName are different variables. Remember too that variable names in Perl are case-sensitive.
A lot of this chapter looked at assigning values to variables using the equal (=) sign. We also reviewed how to use positive and negative subscripts (such as $array[1]) to access array elements. Associative array elements are accessed a little differently, curly braces are used instead of square brackets (for example, $associativeArray{"Jack B."}).
And finally, we took another look at double quoted strings to see how variable interpolation works. You saw that Perl automatically replaces variables inside double quoted strings. When arrays are printed inside strings their elements are separated by the value of $" - which is usually a space.