
Hashes are quite useful as databases — you store key/value pairs and later look up the data associated with any key. Wouldn’t it be nice if we could connect a Perl hash directly to a DBM file on disk so we could easily have a persistent hash database? We can do exactly that by using the tie() function to tie a hash to a dbm file.
Perl ships with support for four types of DBM files (which ones will be compiled into your perl depend on what is available on your platform when you built perl). These are: NDBM, DB_File, GDBM, and SDBM. DB_File is the most flexible (so we will use it here), but NDBM is widespread (was used with perl 4) and SDBM libraries ship with perl so you always have at least one possibility to use.
Tieing a hash to a DBM is quite simple — you merely ‘use’ the appropriate DB module, declare a hash to tie, and call the tie() function to complete the process of associating the hash with the DBM file.
#!/usr/bin/perl -w
use strict;
use DB_File; # or NDBM_File, GDBM_File, SDBM_File, AnyDBM_File
my %dbase;
my $file = 'phones.db';
tie(%dbase, 'DB_File', $file) || die "can't open $file: $!";
$dbase{andrew} = '555-1234'; # not really
$dbase{john} = '555-4321';
foreach my $key (keys %dbase) {
print "$key: $dbase{$key}\n";
}
untie(%dbase);
__END__
The call to tie() takes 3 arguments: the hash to tie; the classname of the DB module, and the filename for the database (additional arguments can set flags and permissions on the database file — see the documentation for details).
The above example defines a hash and then tie()’s it to a DB_File DBM file. We then enter two key/value pairs (names and phone numbers) and iterate over the hash. The big deal is, if you run this program and then comment out the two lines assigning to the hash, you’ll find that it still prints out the same data because the data persists in the DBM file ‘phones.db’. We now have a persistent hash — it works just like any other hash, but it is stored on disk as well.
One thing that I need to mention is how we iterate over the hash. In the above example we simply used the keys() function to iterate over the list of keys in the hash. If this were a large database, this could take more memory than you desire. A better way to iterate over the hash is by using the each() function which returns key/value pairs sequentially (without building the entire list in memory):
while( my($k, $v) = each(%dbase) ) {
print "$k: $v\n";
}
You can use this mechanism for all sorts of persistent data. Netscape maintains its history list of recently visited web-sites between invocations by using such a mechanism. You could build an address book application using DBM files, or you store configuration information for your application.
The DB_File module also allows you to tie() a hash to a BTREE structure (which can maintain an order on your keys) or to tie a hash to a flat text file using line numbers as keys for each line (record) in the file.
For further information see the following documentation:
perldoc -f tie
perldoc AnyDBM_File
perldoc DB_File
*****