HoH and MLDBM problems

B

Brian Greenfield

I've got a HoH which I'm trying to store using MLDBM and DB_File. The
following minimal script demonstrates the problem I've got.

Using an untied hash works ok:

|zippy:~/scripts$ ./test 0 # untied
|$VAR1 = {
| 'fruit' => {
| 'banana' => 1,
| 'apple' => 1,
| 'orange' => 1
| }
| };

But,

|zippy:~/scripts$ ./test 1 # tied
|Using tie
|$VAR1 = {
| 'fruit' => {}
| };

And the script:

|zippy:~/scripts$ cat test
|#!/usr/bin/perl
|
|use strict;
|use warnings FATAL=>'all';
|use Data::Dumper;
|use MLDBM qw/DB_File/;
|
|unlink "my.db";
|my $use_tie = shift || 0;
|my %db;
|
|if ($use_tie)
|{
| print "Using tie\n";
| tie %db, "MLDBM", 'my.db' or die "can't tie: $!";
|}
|
|$db{fruit}{$_} = 1 for qw/apple orange banana/;
|print Dumper \%db;
|untie %db;

Perl is 5.8.0 running on Debian/testing.
MLDBM is 2.01
DB_File is 1.804
and please don't ask which version of libdb I'm using :(

Any input appreciated.
 
T

Tassilo v. Parseval

Also sprach Brian Greenfield:
I've got a HoH which I'm trying to store using MLDBM and DB_File. The
following minimal script demonstrates the problem I've got.
[...]

|zippy:~/scripts$ cat test
|#!/usr/bin/perl
|
|use strict;
|use warnings FATAL=>'all';
|use Data::Dumper;
|use MLDBM qw/DB_File/;
|
|unlink "my.db";
|my $use_tie = shift || 0;
|my %db;
|
|if ($use_tie)
|{
| print "Using tie\n";
| tie %db, "MLDBM", 'my.db' or die "can't tie: $!";
|}
|
|$db{fruit}{$_} = 1 for qw/apple orange banana/;

You can't store those data like that. When working with a tied hash, you
can only store something in the top-level and not somewhere nested
below. The above would have to read:

my %subhash;
$subhash{ $_ } = 1 for qw/apple orange banana/;
$db{ fruit } = \%subhash;

This is a known limitation of the tied interface. See also the "BUGS"
section in 'perldoc MLDBM'.

Tassilo
 
B

Brian Greenfield

Also sprach Brian Greenfield:
[snip]
|if ($use_tie)
|{
| print "Using tie\n";
| tie %db, "MLDBM", 'my.db' or die "can't tie: $!";
|}
|
|$db{fruit}{$_} = 1 for qw/apple orange banana/;

You can't store those data like that. When working with a tied hash, you
can only store something in the top-level and not somewhere nested
below. The above would have to read:

my %subhash;
$subhash{ $_ } = 1 for qw/apple orange banana/;
$db{ fruit } = \%subhash;

This is a known limitation of the tied interface. See also the "BUGS"
section in 'perldoc MLDBM'.

I know:(

I just read the docs *again* (although with a little more care), and
saw this limitation.

Thanks for the help and my apologies for wasting your time.
 
T

Tom

I have been trying to get the following to work for weeks and it just does
not.
No data gets stored like this as long as it is tied via tie or dbmopen.
You can't store those data like that. When working with a tied hash, you
can only store something in the top-level and not somewhere nested
below. The above would have to read:

my %subhash;
$subhash{ $_ } = 1 for qw/apple orange banana/;
$db{ fruit } = \%subhash;


Any clues?
Thanks,
Tom
 
B

Bob Walton

Tom said:
I have been trying to get the following to work for weeks and it just does
not.
No data gets stored like this as long as it is tied via tie or dbmopen.




Any clues?


Yes. Look at the MLDBM module. If the docs are mystifying, read the
relevant recipies in Perl Cookbook, which has an excellent discussion.
Recognize that the fundamental problem is that while a "regular" hash
(not tied to a DBM-type file) can store any scalar value including a
reference, a hash which is tied to a DBM-type file can only store one
kind of thing: a string. MLDBM functions by automagically stringifying
the item to be stored and unstringifying it when it is fetched. It
works fine, but you must bear in mind the fact that if you want to
change something in the stored structure, you must retrieve the entire
stored structure, make your modification to that, and then store the
entire structure back again.

HTH.


....
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,818
Latest member
Brigette36

Latest Threads

Top