1.2 Perl Variables
Perl does not have a strict type system, although there is a distinction between three different kinds of variables. A scalar variable must begin with $. A scalar may hold a single value. An array variable must begin with @. An array is a collection of scalars. A hash variable must begin with %. A hash, sometimes called an associative array, holds pairs of values.
Perl variables are case-sensitive. They may be composed of any number of characters. It is also allowable, albeit confusing to programmers, to have a scalar variable with the same name as an array variable, both of which have the same name as a hash. In other words, each of the following is a different variable:
$names scalar named names @names array named names %names hash named names
1.2.1 Scalars
Depending on the language with which you are most familiar, the following Perl code may seem a little strange to you, since the same variable, $data, is used to store an integer value and then a string value.
#!/usr/bin/perl # # scalars.pl # print "input a number "; $data = <STDIN>; chomp($data); print "$data * $data is "; print $data * $data; print "\n"; print "input your name "; $data = <STDIN>; print "Your name is $data\n"; % scalars.pl input a number 25 25 * 25 is 625 input your name Michael your name is Michael %
This is not a problem in Perl because $data is a scalar and as such may contain any single value. That value may be a string or any kind of number. In any expression concerning $data, it is the operator which determines how to treat the value held in the variable, that is, as a string or as a number. For now, the important item is that $data is a scalar and thus may hold a single value.
1.2.2 Arrays
An array is an ordered list of elements typically separated by commas. Here are a few examples of arrays:
@names = (Mike, "Susan Smyth", "Erin\nFlanagan"); @bas = (.324, .298, .245); @record = ("Mike", 27, .324, "Columbia, Md"); $data = 6; # a scalar @numbers = (1,2,3,4,5, $data); # an array
The @numbers array contains a series of numbers. The @names array contains a series of strings. If any of these strings contains a blank, a newline, or a tab, it needs to be protected by using quotes. Note also that an array, such as @record, may contain disparate types since each of them is a scalar. The important thing is that an array is a list of scalars. If you need to know the size of an array, simply assign the array to a scalar.
$size = @record; # size = 4 $size = @numbers # size = 6 $size = @names; # size = 3
An important property of Perl arrays is that they are dynamic. This is a departure from other languages, but it is a very useful feature.
@numbers = (80, @numbers, 90); $size = @numbers; # size = 8
If you need to access a particular scalar in an array, then you must index the element with a subscript using square bracket notation, [ ]. Perl indices begin with 0. Here are a few examples:
@record = ("Mike", 27, .324, "Columbia, Md"); print "$record[0]\n"; # Mike print "$record[1]\n"; # 27
An entire array can be printed by placing double quotes around the array's name. This prints each element of the array with a space separating the elements. This is generally the way you will want to see array values displayed:
print "@record\n"; # mike 27 .324 Columbia, Md
If you want the array elements adjacent to one another, simply omit the quotes:
print @record; # mike27.324Columbia, Md
Note also that anything in single quotes will print literally::
print '@record'; # @record
The simple program below, arrays.pl, demonstrates these introductory concepts about arrays:
#!/usr/bin/perl # # arrays.pl # @values = (10, 20, 15); $size = @values; print 'For @values array', "\n"; print "Size is $size\n"; print "Elements (with spaces) are @values\n"; print "Elements (no spaces) are "; print @values; print "\nElements one by one\n"; print "$values[0]\n"; print "$values[1]\n"; print "$values[2]\n"; % arrays.pl For @values array Size is 3 Elements (with spaces) are 10 20 15 Elements (no spaces) are 102015 Elements one by one 10 20 15 %
1.2.3 Array functions
Perl contains many array functions. Some of the more common ones are shown here. pop returns the last element of an array and also removes this element from the array.
@values = ( 1,2,8,14 ); $result = pop(@values); # result = 14 print "@values \n"; # 1 2 8 print pop(@values),"\n"; # 8 print "@values\n"; # 1 2
push pushes a value onto the bottom of an array. You may push as many elements onto an array as you wish.
push(@values,10); # 1 2 10 print "@values \n"; # 1 2 10 push(@values, 11,8); # 1 2 10 11 8 push(@values, @values); # 1 2 10 11 8 1 2 10 11 8
The shift and unshift functions behave like pop and push, except that they operate on the beginning of an array, not the end of an array.
shift(@values); # 2 10 11 8 1 2 10 11 8 unshift(@values, 1, 15) # 1 15 2 10 11 8 1 2 10 11 8
reverse returns a list in reverse order, leaving the original list unchanged.
@back = reverse(@values); print "@back\n"; # 8 11 10 2 1 8 11 10 2 15 1 print "@values\n"; # 1 15 2 10 11 8 1 2 10 11 8
sort sorts a list in dictionary order, returning the sorted list and leaving the original list unchanged.
@names = (Jo, Pete, Bill, Bob, Zeke, Al); @sorted = sort(@names); print "@names\n"; # Jo Pete Bill Bob Zeke Al print "@sorted\n"; # Al Bill Bob Jo Pete Zeke
join takes a separator string and an array and produces a scalar consisting of all array elements with the separator between them. split is the opposite of join. It takes a string and splits it into an array based on a delimiter given as the first argument. Here is an example to demonstrate split and join:
#!/usr/bin/perl # # splitjoin.pl # print "enter your favorite colors "; $colors = <STDIN>; @colors = split(" ", $colors); $size = @colors; print "You entered $size colors\n"; $colors = join("&", @colors); print "They are:\n$colors\n"; % splitjoin.pl enter your favorite colors red green blue orange You entered 4 colors They are: red&green&blue&orange %
The program prompts you for your favorite colors. When you respond, the program splits your answers into an array and then determines the size of the array, which is the number of colors. Then these colors are joined into a single scalar separated by the & character.
1.2.4 Arrays and STDIN
Recall that the following code reads a line from the standard input:
$name = <STDIN>;
If the variable above had been an array rather than a scalar, then Perl would have read the entire file into the array. Each line of the file would have become the next element of the array.
@data = <STDIN>; # read entire file
This makes copying a file (STDIN to STDOUT) as easy as:
@data = <STDIN>; # read all lines from STDIN print @data; # print each element (i.e. each line)
Of course, the key issue here is the fact that the variable at the left of the = is an array. Thus, we could read all the lines from any file as long as we have a filehandle associated with that file.
open(INPUT, "< mydata"); # open file named 'mydata' @lines = <INPUT>; # read all lines from file
Many files have header information in the first line and the actual data in succeeding lines. Using the concept in this section, we can use the script justdata.pl to read such a file.
#!/usr/bin/perl # # jastdata.pl # open(DATAFILE, "< datafile"); # open file $head = <DATAFILE>; # read first line @remainder = <DATAFILE>; # read rest of lines print @remainder;
The first line of code opens the file datafile. The next line of Perl code reads the first line of datafile. Since the next line of Perl code has an array on the left of the assignment operator, all the remaining lines of the datafile are read.
1.2.5 Associative arrays
An associative array is a collection of pairs where the first element of the pair is called the key and the second element of each pair is called the value associated with the key. The idea behind associative arrays is that the key can be used to retrieve the value. Associative arrays are often called hashes. This data type is used to implement table lookups. There are many problems that can be solved using hashes. The key is usually string data. Thus, you could look up a capital city by its state or you could look up a bank balance by the name of the account. Associative arrays save the programmer the actual programming of the lookup. If you need to define an associative array, remember that its name must begin with the % symbol. Beyond that, the pairs must be specified.
%accounts = ( Mike => 100, Sue => 200, Erin => 150, Patti => 250, );
The symbol => can be used to make the associations clear. However, the following notation may be used as well. In this case, the associations are made in terms of the orderings; that is, the first two entries represent the first pair, the next two elements represent the second pair, etc.
%accounts = (Mike, 100, Sue, 200, Erin, 50, Patti, 250);
Since an associative array and a regular array may have the same name, to extract a particular value from an associative array, you must use the curly brace form of the subscript operator. The key that acts as the subscript may be quoted or not. Of course, if the key contains embedded blanks, then the key must be quoted.
$accounts{Mike} # yields 100 $accounts{Sue} # yields 200
Here's a small example of declaring an associative array and then seeing if a value entered by the user is present in the array:
#!/usr/bin/perl # # hash.pl # %accounts = ( Mike => 100, Sue => 200, Erin => 150, Patti => 250 ); print "enter a name "; $name = <STDIN>; # read a name chomp($name); # remove newline character print "$name has balance: $accounts{$name}\n"; % hash.pl enter a name Mike Mike has balance: 100 %
Besides using a key to retrieve a value, a common activity on hashes is to get a list of all the keys or a list of all the values. These last two activities are accomplished through the use of two functions: keys and values. The keys function returns a list of keys and the values function returns a list of values.
@allthekeys = keys(%accounts); @allthevalues = values(%accounts);
Like normal arrays, associative arrays are also dynamic, and thus it is a simple matter to add or delete pairs. The delete function deletes a (key, value) pair.
delete $accounts{Mike};
You may grow an associative array by adding elements as shown here:
$accounts{Maria} = 100; $accounts{Dave} = 100;
Hashes are extremely important in Perl; thus, we will devote an entire chapter to them later in this book. Just remember that a hash is a collection of names, value pairs, and that a value may be retrieved by its key. Any attempt to add an already seen key with a new value will replace the original value for the key.