Chapter 5: Introducing Perl

Data types


[ Comments ] [ Copyright ] [ Chapter contents ] [ Book contents ]


We've seen simple, scalar variables like $newline; these are simply strings by any other name, although if they contain numeric data they can be treated as numbers. We have also seen simple arrays (vectors) like @line; these are simply arrays of scalars. $line[n] is the nth element of @line, and @line[1..4] is an array slice containing the 1st through 4th elements of @line.

Associative arrays are arrays where the subscript is not a number, increasing in sequential order, but a string. Associative arrays are named something like %array, while their elements are referred to as $array{"key"} -- this refers to the value associated with the subscript "key". (Note that the subscript here is a string, not an array position.)

You can use associative arrays to store a variety of information:

$dog{"small"}= "chihuahua"; 
$dog{"large"} = "rotweiller";
$dog{"medium"} = "labrador";
$bite{"chihuahua"} = "itsy";
$bite{"rotweiller"} = "grievous";
$bite{"labrador"}= "medium";

You can then find out how nasty the bite of a medium dog is by looking up the value of $dog{"medium"} and using it as a key in %bite:

foreach $fang ("small","medium","large"){ 
     $breed = $dog{$fang};      # work out the dog's breed from its teeth
     $pain  = $bite{$dog_size}; # from the size of the dog, derive it's bite
     print "A $breed has a $pain bite\n"; 
}

prints:

A chihuahua has a itsy bite
A labrador has a medium bite
A rotweiller has a grievous bite

You can use associative array entries as keys to other arrays: the following is a more compact but less readable version of the same program:

 
foreach $fang ("small","medium","large") { 
    print "A $dog{$fang} has a $bite{$dog{$fang}} bite\n";
}

This is an example of using an associative array to store pointers. In effect, you can emulate complex data structures (trees, directed graphs, linked lists, and so on) using an associative array. Each element of an associative array has a key and a value. The key is the subscript; the value is the value associated with it. The example above uses the value in the array %dog as a key into the array %bite.

Associative arrays can be interconverted with ordinary arrays, and initialised in the program. To all intents and purposes, they can be treated like arrays with an even number of entries grouped in "key","value" pairs:

%dog = ( # initialize an associative array 
         "small","chihuahua",
         "medium","labrador", 
         "large","rotweiller",
       );

In fact, associative arrays are extremely useful; they can be used to emulate databases, and indeed they can be bound to a disk file and retained for use in future sessions. UNIX pioneered the use of dbm files, hash tables on disk where a key:value tuple could be stored and retrieved efficiently. Perl permits you to associate a file with an associative array:

dbmopen(%dog, "dog-data",$permiss) 

opens a file, /usr/filename, with permissions $permiss (something of a UNIXism), and associates it with %dog. Thereafter, you can read the contents of dog-data as if they are an associative array, and data assigned to %dog is stashed in dog-data. If you execute a dbmclose(%dog) the file is closed (and %dog becomes useless). For example, suppose we want to store our array of canine attributes for use by another program at a later date:

#!/bin/perl

%dog = (	# initialize an associative array

	"small","chihuahua",
	"medium","labrador",
	"large","rotweiller",
};
# open the dbm file, or quit with an error message
dbmopen(%dog,"dog-data",0700) || 
	die "Couldn't open dog-data!\n";
# store data in dog-data
%dog = (
	"small","chihuahua",
	"medium","labrador",
	"large","rotweiller",
};
# close the dbm file
dbmclose (%dog);

exit 0;

Now a separate program reads the database file:

#!/bin/perl

# open the file, for reading

dbmopen(%dog,"dog-data",0400) || 
	die "Couldn't open dog-data!\n";
# now print its contents; note that keys(%assoc)
# fetches all the keys to the associative array %assoc
foreach $size (keys (%dog)) {
	print "My $size dog is a $dog{$size}\n";
}

dbmclose %dog;

The first program creates a dbm file called dog-data. The second file reads from it and prints:

My small dog is a chihuahua
My medium dog is a labrador
My large dog is a rotweiller

The main use of this is to allow programs to retain a "memory" of what a user is doing. You can store state-specific information from a CGI script in a dbm file, then take its name, and a key for the file, and pass them to a browser as a "cookie" embedded in an HTML form; on presenting the "cookie" back to a subsequent run of the CGI script, the script can retrieve its previous state information and generate some more output, giving the user the illusion that they are participating in a continuous interactive session rather than a disjoint series of transactions.

We will see some useful examples of associative arrays later.


[ Comments ] [ Copyright ] [ Chapter contents ] [ Book contents ]