Example 19-5. mldbm.pl
use strict;
use MLDBM qw(DB_File);
use DB_File;
use Data::Dumper ( );
use Fcntl qw(O_RDWR O_CREAT);
my $r = shift;
$r->send_http_header("text/plain");
my $rh = {
bar => ['a'..'c'],
tar => { map {$_ => $_**2 } 1..4 },
};
my $dbfile = "/tmp/foo.db";
tie my %dbm, 'MLDBM', $dbfile, O_RDWR|O_CREAT,
0600, $DB_HASH or die $!;
# assign a reference to a Perl datastructure
$dbm{foo} = $rh;
untie %dbm;
# read the assigned value
tie %dbm, 'MLDBM', $dbfile, O_RDWR|O_CREAT,
0600, $DB_HASH or die $!;
my $foo = exists $dbm{foo} ? $dbm{foo} : 'undefined';
untie %dbm;
print Data::Dumper::Dumper($foo);
As you can see, this example is very similar to the normal use of
DB_File; we just use MLDBM
instead, and tell it to use DB_File as an
underlying DBM implementation. You can choose any other available
implementation instead. If you don't specify one,
SDBM_File is used.
The script creates a complicated nested data structure and stores it
in the $rhscalar. Then we open the database and
store this value as usual.
$VAR1 = {
'bar' => [
'a',
'b',
'c'
],
'tar' => {
'1' => '1',
'2' => '4',
'3' => '9',
'4' => '16'
}
};
That's exactly what we inserted into the DBM file.
There is one important note, though. If you want to modify a value
that is a reference to a data structure, you cannot modify it
directly. You have to retrieve the value, modify it, and store it
back.
For example, in the above example you cannot do:
tie my %dbm, 'MLDBM', $dbfile, O_RDWR|O_CREAT,
0600, $DB_HASH or die $!;
# update the existing key
$dbm{foo}->{bar} = ['a'..'z']; # this doesn't work
untie %dbm;
if the key bar existed before. Instead, you should
do the following:
tie my %dbm, 'MLDBM', $dbfile, O_RDWR|O_CREAT,
0600, $DB_HASH or die $!;
# update the existing key
my $tmp = $dbm{foo};
$tmp->{bar} = ['a'..'z'];
$dbm{foo} = $tmp; # this works
untie %dbm;
This limitation exists because the perl TIEHASH
interface currently has no support for multidimensional ties.
By default, MLDBM uses
Data::Dumper to serialize the nested data
structures. You may want to use the FreezeThaw or
Storableserializer instead. In fact,
Storable is the preferred one. To use
Storable in our example, you should do:
use MLDBM qw(DB_File Storable);
at the beginning of the script.
Refer to the MLDBM manpage to find out more
information about it.