http://paperlined.org/src/pl/jollies/backend/dbm/edhashstorable.pl

#!/usr/bin/perl

# allows the user to edit a value in a Berkeley DB, given its key

    use strict;
    use warnings;

    use BerkeleyDB;
    use Storable;
    use File::Temp qw/ tempfile tempdir /;
    use Safe;


    use Data::Dumper;


@ARGV >= 2
    or die "Syntax: $0 <db_file> <key>\n";

my $filename = shift;
my $key = shift;

#-e $filename or die "Please specify a valid db file.\n";




my $env = new BerkeleyDB::Env;

my %hash;
my $db  = tie %hash, 'BerkeleyDB::Btree',
            -Filename => $filename,
            -Flags    => DB_CREATE
    or die "Cannot open file $filename: $! $BerkeleyDB::Error\n" ;



my $contents;
my $contents_txt;
if (! exists $hash{$key}) {
    print "Key '$key' did not exist.  Creating.\n";
    sleep(2);
    $contents_txt = '';
} else {
    $contents = Storable::thaw($hash{$key});
    $Data::Dumper::Terse++;
    $contents_txt = Data::Dumper::Dumper($contents);
}



my ($fh, $tempfilename) = tempfile();
print $fh $contents_txt;
close $fh;


while (1) {
    system "vim", $tempfilename;


    open FIN, "<$tempfilename" or die "Unable to read temporary file back in ('$filename'): $!\n";
    $contents_txt = do {local $/=undef; <FIN>};
    close FIN;

    #print "Got:\n$contents_txt\n";


    # find out whether it compiles okay
    my $cpt = new Safe;
    $cpt->permit(qw( :base_core :base_mem :base_loop  ));
    my @contents = $cpt->reval($contents_txt);
    if ($@) {
        print "Unable to compile.\n$@\n\nPress enter to edit again, Ctrl-C to cancel.\n";
        my $linein = <STDIN>;
    } else {
        if (scalar(@contents) == 1) {
            $contents = $contents[0];
        } else {
            print "Got[*]:\n", Dumper \@contents;
            $contents = \@contents;
        }

        if (!ref($contents)) {
            print "Error, value must be a reference.\n";
            next;
        }
    
        last;
    }
}
unlink $tempfilename;


print "Got:\n", Dumper($contents);

$hash{$key} = Storable::freeze($contents);

Generated by GNU enscript 1.6.4.