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

Hi

Basically I'm attaempting to store some complex perl data structures in a DBM hash flatfile database using the DBM::Deep module from CPAN.

A simplified version of the problem is this. Imagine a script:

#!/usr/bin/perl use strict; use warnings; use DBM::Deep; my $db = new DBM::Deep "db.file"; $db->{hash}->{key}->[0] = 10; print $db->{hash}->{key}->[0]; exit;

Basically, the first time the script runs, the db file is created but the variable isn't printed. It has to be run a second time before the value is allocated to the variable and the print occurs. After the second run it works fine. This may not seem like a problem in the above script but it is a serious problem in the actual script I'm trying to implement which is using incrementing counts and autovivification.

Any suggestions?

Cheers in advance,

tb34

Replies are listed 'Best First'.
Re: DBM::Deep Problem
by holli (Abbot) on May 18, 2005 at 08:40 UTC
    Warning: This is a hipshot.

    From what I recall about DBM-like databases, they recognize changes only when you set the first level key. So your snippet should be.
    #!/usr/bin/perl use strict; use warnings; use DBM::Deep; my $db = new DBM::Deep "db.file"; $db->{hash} = { key => [10] }; print $db->{hash}->{key}->[0]; exit;
    completely untested.


    holli, /regexed monk/
      That seems to work - it definitely prints the value first time at least. Thanks :-)

      One other question though (I'm pretty new to the OO syntax) - how would I cahnge the second element (index value 1) in the same anonymous array?

        my %h = %{$db->{hash}}; #get hash from db $h{key}->[0]=99; #alter value $db->{hash} = \%h; #put hash back in print $db->{hash}->{key}->[0]; #99
        Yes. This is ugly. This weird sysntax is caused by the tie-mechanism, which cannot handle deep structures.
        If you do $db->{hash}->{key}->[0] = 99 you change the data, but the change is not reported to the underlying (tied) object. see perltie for more.


        holli, /regexed monk/
Re: DBM::Deep Problem
by astroboy (Chaplain) on May 18, 2005 at 10:22 UTC
      Yeah, I had read that.
      The author seemed to believe it was a rare problem though, and the autovivification I was attempting wasn't that complex.
      Also, I didn't want to believe it wouldn't work because I desperately needed it to :-)
      It's working a treat now though.
      Cheers again guys (and gals)

        IMO the author is being highly optimistic in his description. This problem is well known and wont go away any time soon.

        ---
        $world=~s/war/peace/g

        I tried using DBM::Deep for a full text search engine. The autovivification problem popped up quite a bit, so I gave up. Still use DBM::Deep for other applications, though. It's pretty nice.
Re: DBM::Deep Problem
by thcsoft (Monk) on May 18, 2005 at 08:24 UTC
    without taking a deeper look at DBM::Deep, but: since it is written in pure perl, as the documentation says, i assume that you've run into a trap, that is my favourite too. ;)
    try:
    $| = 1;
    right on top of your code, maybe after 'user strict'.

    language is a virus from outer space.
      I have just tried that but to no avail. The script is still behaving exactly as it was before.