This text is excerpted from CGI Programming 101 (2nd edition). Click here to order the book.

Text copyright © 2004 by Jacqueline Hamilton. All rights reserved. You may print one copy of this page for your personal use. You may not copy this material onto another website or into any other medium.

Chapter 2: Perl Variables

Before you can proceed much further with CGI programming, you'll need some understanding of Perl variables and data types. A variable is a place to store a value, so you can refer to it or manipulate it throughout your program. Perl has three types of variables: scalars, arrays, and hashes.

Scalars

A scalar variable stores a single (scalar) value. Perl scalar names are prefixed with a dollar sign ($), so for example, $x, $y, $z, $username, and $url are all examples of scalar variable names. Here's how variables are set:

In this example $foo, $name, and $pi are scalars. You do not have to declare a variable before using it, but its considered good programming style to do so. There are several different ways to declare variables, but the most common way is with the my function:

my simultaneously declares the variables and limits their scope (the area of code that can see these variables) to the enclosing code block. (We'll talk more about scope later.) You can declare a variable without giving it a value:

You can also declare several variables with the same my statement:

You can omit the parentheses if you are declaring a single variable, however a list of variables must be enclosed in parentheses.

A scalar can hold data of any type, be it a string, a number, or whatnot. You can also use scalars in double-quoted strings:

Now if you print $blee, you will get "The magic number is 23." Perl interpolates the variables in the string, replacing the variable name with the value of that variable.

Let's try it out in a CGI program. Start a new program called scalar.cgi:

Program 2-1: scalar.cgi Print Scalar Variables Program


Source code: http://www.cgi101.com/book/ch2/scalar-cgi.html
Working example: http://www.cgi101.com/book/ch2/scalar.cgi

You may change the $email and $url variables to show your own e-mail address* and website URL. Save the program, chmod 755 scalar.cgi, and test it in your browser.

You'll notice a few new things in this program. First, there's use strict. This is a standard Perl module that requires you to declare all variables. You don't have to use the strict module, but it's considered good programming style, so it's good to get in the habit of using it.

You'll also notice the variable declarations:

Notice that the @-sign in the e-mail address is escaped with (preceded by) a backslash. This is because the @-sign means something special to Perl — just as the dollar sign indicates a scalar variable, the @-sign indicates an array, so if you want to actually use special characters like @, $, and % inside a double-quoted string, you have to precede them with a backslash (\).

A better way to do this would be to use a single-quoted string for the e-mail address:

Single-quoted strings are not interpolated the way double-quoted strings are, so you can freely use the special characters $, @ and % in them. However this also means you can't use a single-quoted string to print out a variable, because

will print the actual string "$fnord" . . . not the value stored in the variable named $fnord.

Arrays

An array stores an ordered list of values. While a scalar variable can only store one value, an array can store many. Perl array names are prefixed with an @-sign. Here is an example:

Each individual item (or element) of an array may be referred to by its index number. Array indices start with 0, so to access the first element of the array @colors, you use $colors[0]. Notice that when you're referring to a single element of an array, you prefix the name with $ instead of @. The $-sign again indicates that it's a single (scalar) value; the @-sign means you're talking about the entire array.

If you want to loop through an array, printing out all of the values, you could print each element one at a time:

A much easier way to do this is to use a foreach loop:

For each iteration of the foreach loop, $i is set to an element of the @colors array. In this example, $i is "red" the first time through the loop. The braces {} define where the loop begins and ends, so for any code appearing between the braces, $i is set to the current loop iterator.

Notice we've used my again here to declare the variables. In the foreach loop, my $i declares the loop iterator ($i) and also limits its scope to the foreach loop itself. After the loop completes, $i no longer exists.

We'll cover loops more in Chapter 5.

Getting Data Into And Out Of Arrays

An array is an ordered list of elements. You can think of it like a group of people standing in line waiting to buy tickets. Before the line forms, the array is empty:

Then Howard walks up. He's the first person in line. To add him to the @people array, use the push function:

Now Sara, Ken, and Josh get in line. Again they are added to the array using the push function. You can push a list of values onto the array:

This pushes the list containing "Sara", "Ken" and "Josh" onto the end of the @people array, so that @people now looks like this: ("Howard", "Sara", "Ken", "Josh")

Now the ticket office opens, and Howard buys his ticket and leaves the line. To remove the first item from the array, use the shift function:

This sets $who to "Howard", and also removes "Howard" from the @people array, so @people now looks like this: ("Sara", "Ken", "Josh")

Suppose Josh gets paged, and has to leave. To remove the last item from the array, use the pop function:

This sets $who to "Josh", and @people is now ("Sara", "Ken")

Both shift and pop change the array itself, by removing an element from the array.

Finding the Length of Arrays

If you want to find out how many elements are in a given array, you can use the scalar function:

This prints "There are 4 people in line." Of course, there's always more than one way to do things in Perl, and that's true here — the scalar function is not actually needed. All you have to do is evaluate the array in a scalar context. You can do this by assigning it to a scalar variable:

This sets $linelen to 4.

What if you want to print the name of the last person in line? Remember that Perl array indices start with 0, so the index of the last element in the array is actually length-1:

Perl also has a handy shortcut for finding the index of the last element of an array, the $# shortcut:

$#arrayname is equivalent to scalar(@arrayname)-1. This is often used in foreach loops where you loop through an array by its index number:

This will print out "color 0 is cyan, color 1 is magenta", etc.

The $#arrayname syntax is one example where an #-sign does not indicate a comment.

Array Slices

You can retrieve part of an array by specifying the range of indices to retrieve:

This example sets @slice to ("magenta", "yellow").

Finding An Item In An Array

If you want to find out if a particular element exists in an array, you can use the grep function:

/pattern/ is a regular expression for the pattern you're looking for. It can be a plain string, such as /Box kite/, or a complex regular expression pattern.

/pattern/ will match partial strings inside each array element. To match the entire array element, use /^pattern$/, which anchors the pattern match to the beginning (^) and end ($) of the string. We'll look more at regular expressions in Chapter 13.

grep returns a list of the elements that matched the pattern.

Sorting Arrays

You can do an alphabetical (ASCII) sort on an array of strings using the sort function:

@colors2 becomes the @colors array in alphabetically sorted order ("black", "cyan", "magenta", "yellow" ). Note that the sort function, unlike push and pop, does not change the original array. If you want to save the sorted array, you have to assign it to a variable. If you want to save it back to the original array variable, you'd do:

You can invert the order of the array with the reverse function:

@colors is now ("black", "yellow", "magenta", "cyan").

To do a reverse sort, use both functions:

@colors is now ("yellow", "magenta", "cyan", "black").

The sort function, by default, compares the ASCII values of the array elements (see http://www.cgi101.com/book/ch2/ascii.html for the chart of ASCII values). This means if you try to sort a list of numbers, you get "12" before "2". You can do a true numeric sort like so:

{ $a <=> $b; } is actually a small subroutine, embedded right in your code, that gets called for each pair of items in the array. It compares the first number ($a) to the second number ($b) and returns a number indicating whether $a is greater than, equal to, or less than $b. This is done repeatedly with all the numbers in the array until the array is completely sorted.

We'll talk more about custom sorting subroutines in Chapter 12.

Joining Array Elements Into A String

You can merge an array into a single string using the join function:

This joins @colors into a single string variable ($colorstring), with each element of the @colors array combined and separated by a comma and a space. In this example $colorstring becomes "cyan, magenta, yellow, black".

You can use any string (including the empty string) as the separator. The separator is the first argument to the join function:

The opposite of join is split, which splits a string into a list of values. See Chapter 7 for more on split.

Array or List?

In general, any function or syntax that works for arrays will also work for a list of values:

Hashes

A hash is a special kind of array — an associative array, or paired list of elements. Each pair consists of a string key and a data value.

Perl hash names are prefixed with a percent sign (%). Here's how they're defined:

This particular example creates a hash named %colors which stores the RGB HEX values for the named colors. The color names are the hash keys; the hex codes are the hash values.

Remember that there's more than one way to do things in Perl, and here's the other way to define the same hash:

The => operator automatically quotes the left side of the argument, so enclosing quotes around the key names are not needed.

To refer to the individual elements of the hash, you'll do:

Here, "red" is the key, and $colors{'red'} is the value associated with that key. In this case, the value is "#ff0000".

You don't usually need the enclosing quotes around the value, either; $colors{red} also works if the key name doesn't contain characters that are also Perl operators (things like +, -, =, * and /).

To print out all the values in a hash, you can use a foreach loop:

This example uses the keys function, which returns a list of the keys of the named hash. One drawback is that keys %hashname will return the keys in unpredictable order — in this example, keys %colors could return ("red", "blue", "green", "black", "white") or ("red", "white", "green", "black", "blue") or any combination thereof. If you want to print out the hash in exact order, you have to specify the keys in the foreach loop:

Let's write a CGI program using the colors hash. Start a new file called colors.cgi:

Program 2-2: colors.cgi - Print Hash Variables Program


Source code: http://www.cgi101.com/book/ch2/colors-cgi.html
Working example: http://www.cgi101.com/book/ch2/colors.cgi

Save it and chmod 755 colors.cgi, then test it in your web browser.

Notice we've had to add backslashes to escape the quotes in this double-quoted string:

A better way to do this is to use Perl's qq operator:

qq creates a double-quoted string for you. And it's much easier to read without all those backslashes in there.

Adding Items to a Hash

To add a new value to a hash, you simply do:

Using our colors example again, here's how to add a new value with the key "purple":

If the named key already exists in the hash, then an assignment like this overwrites the previous value associated with that key.

Determining Whether an Item Exists in a Hash

You can use the exists function to see if a particular key/value pair exists in the hash:

This returns a true or false value. Here's an example of it in use:

This checks to see if the key "purple" is already in the hash; if not, it adds it.

Deleting Items From a Hash

You can delete an individual key/value pair from a hash with the delete function:

If you want to empty out the entire hash, do:

Values

We've already seen that the keys function returns a list of the keys of a given hash. Similarly, the values function returns a list of the hash values:

As with keys, values returns the values in unpredictable order.

Determining Whether a Hash is Empty

You can use the scalar function on hashes as well:

This returns true or false value — true if the hash contains any key/value pairs. The value returned does not indicate how many pairs are in the hash, however. If you want to find that number, use:

Here's an example:

This will print out "There are 5 colors in this hash."

Resources

Visit http://www.cgi101.com/book/ch2/ for source code and links from this chapter.

Previous Contents Next

 


Table of Contents | Order the Book | CGI101 Home