Store Object Class in DBM Hash

Discussion in 'Perl Misc' started by michael.shnitzer@gmail.com, May 16, 2007.

  1. Guest

    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
     
    , May 16, 2007
    #1
    1. Advertising

  2. Mumia W. Guest

    On 05/16/2007 11:41 AM, wrote:
    > 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.
     
    Mumia W., May 16, 2007
    #2
    1. Advertising

  3. On 16 May 2007 09:41:44 -0700,
    <> wrote:
    > 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
    --
    |
    Martien Verbruggen | There are only 10 types of people in the
    | world; those who understand binary and those
    | who don't.
     
    Martien verbruggen, May 17, 2007
    #3
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. rp
    Replies:
    1
    Views:
    544
    red floyd
    Nov 10, 2011
  2. Colvin
    Replies:
    3
    Views:
    172
    Colvin
    Dec 30, 2003
  3. Storing Object in DBM Hash

    , May 16, 2007, in forum: Perl Misc
    Replies:
    2
    Views:
    153
    -berlin.de
    Jun 21, 2007
  4. PerlFAQ Server
    Replies:
    0
    Views:
    102
    PerlFAQ Server
    Jan 23, 2011
  5. PerlFAQ Server
    Replies:
    0
    Views:
    110
    PerlFAQ Server
    Apr 9, 2011
Loading...

Share This Page