Persistent Data (Perl Cookbook, 2nd Edition)

## 14.7. Persistent Data

### 14.7.1. Problem

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

### 14.7.2. 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;
>     }

### 14.7.3. 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-4, assigning to `$array_ref` before we `push`. You can't simply 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-4. 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). Early 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);

### 14.7.4. See Also

The documentation for the standard Data::Dumper and Storable modules; the documentation for the FreezeThaw and MLDBM modules from CPAN; Recipe 11.13; Recipe 14.6

Copyright © 2003 O'Reilly & Associates. All rights reserved.