Store Object Class in DBM Hash

M

michael.shnitzer

It was my understanding that once a DBM hash was tied to a file, it
can be accessed using the same methods as a regular hash. For
simplicities sake I created a small perl program to demonstrate what I
am trying to do:

***********************************
#! /usr/bin/perl -w
use warnings;

my %hash = ( );
dbmopen(%hash, ".data/documents", 0777);
$hash{mike} = new Document;

print $hash{mike}->docno;

package Document;

sub new
{
my $self = {
document_number => "DOC123",
};
bless $self;
}

sub docno
{
my $self = shift;
return $self->{document_number};
}
**************************************

If I run this program with the DBM hash it returns "Can't locate
object method "docno" via package "Document=HASH(0x4001d0cc)" (perhaps
you forgot to load "Document=HASH(0x4001d0cc)"?) at read.pl line 11."

But if I run this program without opening the DBM hash, then the
program returns the expected result of DOC123.

Obviously there is a difference in accessing the hash data when it is
being read from a DBM hash that I am missing.

Any suggestions would be appreciated.

Thanks,

--Mike
 
M

Mumia W.

It was my understanding that once a DBM hash was tied to a file, it
can be accessed using the same methods as a regular hash. For
simplicities sake I created a small perl program to demonstrate what I
am trying to do:

***********************************
#! /usr/bin/perl -w
use warnings;

my %hash = ( );
dbmopen(%hash, ".data/documents", 0777);
$hash{mike} = new Document;

print $hash{mike}->docno;

package Document;

sub new
{
my $self = {
document_number => "DOC123",
};
bless $self;
}

sub docno
{
my $self = shift;
return $self->{document_number};
}
**************************************

If I run this program with the DBM hash it returns "Can't locate
object method "docno" via package "Document=HASH(0x4001d0cc)" (perhaps
you forgot to load "Document=HASH(0x4001d0cc)"?) at read.pl line 11."

But if I run this program without opening the DBM hash, then the
program returns the expected result of DOC123.

Obviously there is a difference in accessing the hash data when it is
being read from a DBM hash that I am missing.

Any suggestions would be appreciated.

Thanks,

--Mike

A couple of limitations in Perl and dbmopen expose the fact that
DBM-hashes are not real hashes; to store objects in a DBM, you'd
probably have to Serialize the data. You can either serialize it
yourself, or you can let MLDBM serialize it for you:

#!/usr/bin/perl
use strict;
use warnings;

my $use_mldbm = 1;

if (! $use_mldbm)
{
use Storable qw(freeze thaw);
my $file = 'dfiles/documents';
my %hash;
dbmopen %hash, $file, 0644 or die("Oops: $!");

my $obj = Document->new;
$obj->increment_docno;
$obj->increment_docno;
$obj->increment_docno;
$obj->increment_docno;
$hash{mike} = freeze($obj);
print thaw($hash{mike})->docno, "\n"; # prints "DOC127"

dbmclose %hash;
exit;
}

if ($use_mldbm)
{
use MLDBM qw(DB_File Storable);
my $file = 'dfiles/docs.db';
my %hash;

tie %hash, 'MLDBM', $file;

my $obj = Document->new;
$obj->increment_docno;
$obj->increment_docno;
$obj->increment_docno;
$obj->increment_docno;
$hash{mike} = $obj;
print $hash{mike}->docno, "\n";

untie %hash;
exit;
}

package Document;

sub new
{
my $self = {
document_number => "DOC123",
};
bless $self;
}

sub docno
{
my $self = shift;
return $self->{document_number};
}

sub increment_docno {
my $self = shift;
$self->{document_number} =~ s/(\d+)$/$1 + 1/e;
$self->{document_number};
}

__END__

Be sure to read the admonition in the BUGS section of MLDBM's pod; it
indirectly applies to dbmopen also.
 
M

Martien verbruggen

On 16 May 2007 09:41:44 -0700,
It was my understanding that once a DBM hash was tied to a file, it
can be accessed using the same methods as a regular hash. For
simplicities sake I created a small perl program to demonstrate what I
am trying to do:

[snip code trying to store a blessed reference in a dbm file]

At the end of the perltie doucmentation you'll find the information
you're probably looking for:

BUGS
You cannot easily tie a multilevel data structure (such as a hash
of hashes) to a dbm file. The first problem is that all but GDBM
and Berkeley DB have size limitations, but beyond that, you also
have problems with how references are to be represented on
disk.

You need to manually serialise your data before storing it, or use a
module that does it for you. MLDBM is one possibility.

Martien
 

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

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top