http://www.perlmonks.org?node_id=998600

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

Hello!

I have faced rather strange issue when working with DB_File module.

Please see the two sample scripts below:

writedb.pl

readdb.pl

. The situation is the following:

- writedb.pl script creates a DB file tied to perl array (not hash) with fixed length records.

- than it puts there two records

- after that readdb.pl opens test.db file with the same parameters as writedb.pl and ties it also to an array

- readdb.pl reports the number of records existing in queue

This works fine on debian linux amd64 (perl 5.14.2). But fails on NetBSD amd64 (perl 5.14.2 too), OpenBSD amd64 (perl 5.12.2), FreeBSD amd64 (perl 5.12.4). On *BSDs it reports doubled DB size, for scripts attached it should be 2, but readdb.pl reports 4. I checked it under debugger and it seems that perl treats DB as tied to hash, not array (e.g. array with pairs of key and value). It creates array of doubled size, where each first value is data from file and each second value is empty.

Could you please advise whether I am doing anything wrong (maybe I am missing some important parameters) or it is bug in BSD implementation.

Thanks in advance.

--

Victor

Replies are listed 'Best First'.
Re: DB_File recno treats array like a hash
by Anonymous Monk on Oct 12, 2012 at 08:25 UTC
    Try this
    #!/usr/bin/perl -- use strict; use warnings; use File::Temp (); use DB_File; Main( @ARGV ); exit( 0 ); sub Main { my $temp = File::Temp->new()->filename; HitAndQuit( $temp, $_ ) for 1,2,3,4; HitAndQuit( $temp ) for 1 .. 1 + rand 12; unlink $temp or die "unlink $temp: $!"; } sub HitAndQuit { my $file = shift; my $recno = DB_File::RECNOINFO->new(); $recno->{flags} |= R_FIXEDLEN; $recno->{reclen} = 100; my $ofoo = tie my(@foo), 'DB_File', $file, O_RDWR|O_CREAT, 0600, $recno or die "Cannot tie ($file): $!"; @_ and push @foo, @_; print "length ", $ofoo->length, " scalar ", scalar @foo, "\n"; undef $ofoo; untie @foo; return; }
Re: DB_File recno treats array like a hash
by Anonymous Monk on Oct 12, 2012 at 06:29 UTC

    On *BSDs it reports doubled DB size, for scripts attached it should be 2, but readdb.pl reports 4.

    push adds to an array, so its quite possible to get to four by pushing two values -- there is no problem

      length() method right after push reports correct length. Issue occurs only when tie'ing existing database after untieing.

        length() method right after push reports correct length. Issue occurs only when tie'ing existing database after untieing.

        There is no issue. You loop twice, you push two items to the same database twice, and you end up with four items after the second time.

        2 + 2 = 4

Re: DB_File recno treats array like a hash
by Anonymous Monk on Oct 12, 2012 at 06:25 UTC

    I checked it under debugger and it seems that perl treats DB as tied to hash, not array (e.g. array with pairs of key and value).

    Not likely