Perl Cookbook

Perl CookbookSearch this book
Previous: 14.8. Storing Complex Data in a DBM FileChapter 14
Database Access
Next: 14.10. Executing an SQL Command Using DBI and DBD
 

14.9. Persistent Data

Problem

You want your variables to retain their values between calls to your program.

Solution

Use a MLDBM to store the values between calls to your program:

use MLDBM 'DB_File';

my ($VARIABLE1,$VARIABLE2);
my $Persistent_Store = '/projects/foo/data';
BEGIN {
    my %data;
    tie(%data, 'MLDBM', $Persistent_Store)
        or die "Can't tie to $Persistent_Store : $!";
    $VARIABLE1 = $data{VARIABLE1};
    $VARIABLE2 = $data{VARIABLE2};
    # ...
    untie %data;
}
END {
    my %data;
    tie (%data, 'MLDBM', $Persistent_Store)
        or die "Can't tie to $Persistent_Store : $!";
    $data{VARIABLE1} = $VARIABLE1;
    $data{VARIABLE2} = $VARIABLE2;
    # ...
    untie %data;
}

Discussion

An important limitation of MLDBM is that you can't add to or alter the structure in the reference without assignment to a temporary variable. We do this in the sample program in Example 14.6, assigning to $array_ref before we push. You simply can't do this:

push(@{$db{$user}}, $duration);

For a start, MLDBM doesn't allow it. Also, $db{$user} might not be in the database (the array reference isn't automatically created as it would be if %db weren't tied to a DBM file). This is why we test exists $db{$user} when we give $array_ref its initial value. We're creating the empty array for the case where it doesn't already exist.

Example 14.6: mldbm-demo

#!/usr/bin/perl -w
# mldbm_demo - show how to use MLDBM with DB_File

use MLDBM "DB_File";

$db = "/tmp/mldbm-array";

tie %db, 'MLDBM', $db
  or die "Can't open $db : $!";

while(<DATA>) {
    chomp;
    ($user, $duration) = split(/\s+/, $_);
    $array_ref = exists $db{$user} ? $db{$user} : [];
    push(@$array_ref, $duration);
    $db{$user} = $array_ref;
}

foreach $user (sort keys %db) {
    print "$user: ";
    $total = 0;
    foreach $duration (@{ $db{$user} }) {
        print "$duration ";
        $total += $duration;
    }
        print "($total)\n";
    }

__END__
gnat        15.3
tchrist     2.5
jules       22.1
tchrist     15.9
gnat        8.7

Newer versions of MLDBM allow you to select not just the database module (we recommend DB_File), but also the serialization module (we recommend Storable). Previous versions limited you to Data::Dumper for serializing, which is slower than Storable. Here's how you use DB_File with Storable:

use MLDBM qw(DB_File Storable);

See Also

The documentation for the Data::Dumper, MLDBM, and Storable modules from CPAN; Recipe 11.13; Recipe 14.8


Previous: 14.8. Storing Complex Data in a DBM FilePerl CookbookNext: 14.10. Executing an SQL Command Using DBI and DBD
14.8. Storing Complex Data in a DBM FileBook Index14.10. Executing an SQL Command Using DBI and DBD