mast has asked for the wisdom of the Perl Monks concerning the following question:

I wish to push multiple values into a tie'd hash of the DB_File verity. For memory-based hashes, my toilings seem to work. However, the following chokes:
#!/usr/pkg/bin/perl -w unlink("revmap_check_deleteme"); $myhashinfo=new DB_File::HASHINFO; $myhashinfo->{bsize}=8192; # The amount of data I intend to store is quite large. I # had to increase the bsize as a result.. tie(%revmap, "DB_File", "revmap_check_deleteme", O_CREAT|O_RDWR, 0666, + $myhashinfo) or die "Unable to create database tie.\n"; # So here we create duplicate values for every item in # the memory hash. for ($counter=0; $counter<10; $counter++) { push @{$memrevmap{$counter}}, "somefile$counter"; push @{$memrevmap{$counter}}, "somefile$counter"; } # Now, here's my (lame) attempt to copy the normal hash to # the tie'd disk hash. foreach $key (keys %memrevmap) { foreach $val (@{$memrevmap{$key}}) { print "pushing into $key, $val\n"; @{$revmap{$key}}=(@{$revmap{$key}}, $val); } } # And here's my attempt to verify that the values were # in fact written to disk. If I change the item below to # memrevmap, it works. foreach $key (keys %revmap) { print "key = $key\n"; print "Data values: "; foreach $val (@{$revmap{$key}}) { print "subval: $val\n"; } } untie %revmap; print "Done.";
How should I better stuff, to-disk, the complete hash I built? Thank you.

Replies are listed 'Best First'.
Re: pushing into a tie'd hash
by Roy Johnson (Monsignor) on Oct 24, 2005 at 18:57 UTC
    The tied hash will only do its magic if you do an operation that calls one of the magic functions. You're not doing any kind of hash-store, you're just operating on values that are referenced. This should (IMO) work:
    foreach $val (@{$memrevmap{$key}}) { print "pushing into $key, $val\n"; $revmap{$key}=[@{$revmap{$key}}, $val]; }

    Caution: Contents may have been coded under pressure.
      Interesting, but running it appears to fail. :( I've tried a few combinations including the [] square braces, to no effect. For some reason that I'm not aware of, the tie'd hash seems to only accept a single value, and not an array. Each additional push, or assignment, seems to overwrite the previous value.

      Something tells me I'm bumping into a limitation of the DB_File module. :(

        From DB_File's docs:

        "How do I store complex data structures with DB_File? Although DB_File cannot do this directly... [suggestion for a layer on top of DB_File]."

        May I instead recommend DBM::Deep?