I've searched for a simple answer to whether or not there is an easy way to use a tied hash (e.g., to NDBM_File) to store a complex data structure. Unfortunately,
MLDBM is not an option and potentially overkill. I have a couple of questions about the following in which I basically use dbmfilters to serialize and unserialize the data:
#!/usr/bin/perl -w
use strict;
use NDBM_File;
use Fcntl;
use Data::Dumper;
$Data::Dumper::Indent = 0;
$Data::Dumper::Purity = 1;
$Data::Dumper::Terse = 1;
my %hash;
my $filename = "test_ndbm";
my $db = tie(%hash, 'NDBM_File', $filename, O_RDWR|O_CREAT, 0640)
or die "Cannot open $filename: $!\n";
$db->filter_store_value( sub { $_ = Dumper($_); } );
$db->filter_fetch_value( sub { $_ = eval($_) } );
my %to_be_stored = (
this_is => { some_test => 'data' },
which_is => 'fairly',
complex => [0, 1, 2],
);
my @keys = keys %hash;
my $new_id = scalar(@keys);
$hash{$new_id} = \%to_be_stored;
foreach my $key (keys %hash) {
foreach (keys %{$hash{$key}}) {
print "hash{$key}{$_} = " . Dumper($hash{$key}{$_}) . "\n";
}
}
undef $db;
untie $hash;
First, is there something I'm missing about the above that will come back to haunt me? Secondly, this method apparently requires the use of an intermediate hash (
%to_be_stored in the above). For example, something like the following:
$hash{a_key} = { b_key => 2 };
$hash{a_key}{b_key} = 3;
results in
$hash{a_key}{b_key} being equal to 2. I believe this is because the filters (and the tying in general) only fire off when actually updating the value directly, i.e.,
$hash{a_key}. Is there any way to work around this?