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

The following code is providing inconsistent output. After the code is some output from runs: the first run with 200 records yields what I expect; the second, with 250 records, yields something I cant explain. Is it not permitted to change the value of a tied hash in an each iteration?

use strict; print "$^V\n"; my $records=shift; unlink "test_tie_hash"; use BerkeleyDB; my %MAIN; tie %MAIN, "BerkeleyDB::Hash", -Filename => "test_tie_hash", -Flags => + DB_CREATE, or die "Cannot open file: $! $BerkeleyDB::Error\n"; my $key="AAAAAAA"; my $store="LLLL"; foreach (1 .. $records){ ++$key; $MAIN{$key}= $store; } untie %MAIN; tie %MAIN, "BerkeleyDB::Hash", -Filename => "test_tie_hash", -Flags => + DB_CREATE; my %count=(); while ((my $key,my $value)=each (%MAIN)){ $count{$value}++; } untie(%MAIN); foreach(keys(%count)){ print "INITIAL LOAD\n$_ $count{$_} records\n\n"; } %count=(); $key=""; tie %MAIN, "BerkeleyDB::Hash", -Filename => "test_tie_hash", -Flags => + DB_CREATE; while ((my $key,my $value)=each (%MAIN)){ if($key=~m/U/){ $value .= "-YYYYYYYYYYYYYYYYYYYYYYYYYYYY"; $MAIN{$key}=$value } elsif($key=~m/L/){ $value .= "-ZZZZZZ"; $MAIN{$key}=$value; } else{ $value .= "-WWWWWWWWWWWWWWWWW"; $MAIN{$key}=$value; } } untie(%MAIN); tie %MAIN, "BerkeleyDB::Hash", -Filename => "test_tie_hash", -Flags => + DB_CREATE; while((my $key,my $value)=each (%MAIN)){ #print "$key $value\n"; $count{$value}++; } untie(%MAIN); foreach(keys(%count)){ print "$_ $count{$_}\n"; }

OUTPUT

$ perl -w test_each_tie 200 v5.10.0 INITIAL LOAD LLLL 200 records LLLL-WWWWWWWWWWWWWWWWW 185 LLLL-YYYYYYYYYYYYYYYYYYYYYYYYYYYY 7 LLLL-ZZZZZZ 8

$ perl -w test_each_tie 250 v5.10.0 INITIAL LOAD LLLL 250 records LLLL-WWWWWWWWWWWWWWWWW 101 LLLL-YYYYYYYYYYYYYYYYYYYYYYYYYYYY-YYYYYYYYYYYYYYYYYYYYYYYYYYYY 5 LLLL-ZZZZZZ-ZZZZZZ 6 LLLL-YYYYYYYYYYYYYYYYYYYYYYYYYYYY 4 LLLL-WWWWWWWWWWWWWWWWW-WWWWWWWWWWWWWWWWW 114 LLLL 16 LLLL-ZZZZZZ 4

It seems that some values in the tied hash are unaltered and some are altered more than once. Thanks.

Replies are listed 'Best First'.
Re: altering value in tied hash
by choroba (Cardinal) on Jun 26, 2016 at 07:21 UTC
    each says:

    > Tied hashes may have a different ordering behaviour to perl's hash implementation.

    The documentation of BerkeleyDB doesn't mention anything, so if you really want to know, you should study the source, probably these six thousand lines of XS.

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,

      The documentation of BerkeleyDB doesn't mention anything, so if you really want to know, you should study the source, probably these six thousand lines of XS.

      :) thats funny choroba but no

      First thing to try is to clean up the code so each tie/untie is in its own scope, and try that

        perl 5.10.0 $BerkeleyDB::db_version 4.6

        When I put the four operations (load tied hash, assess hash, modify hash, reassess hash) in separate files and run them sequentially, I get the same results.

Re: altering value in tied hash
by Anonymous Monk on Jun 26, 2016 at 10:21 UTC

    inconsistent output ... Is it not permitted to change the value of a tied hash in an each iteration? ... It seems that some values in the tied hash are unaltered and some are altered more than once. ..

    What versions do you have?

    print " perl $] BerkeleyDB $BerkeleyDB::VERSION db_version $BerkeleyDB::db_version ";

    This is what i see, double dashes means the iterator goes back sometimes and repeats keys already seen, its a bug you should report it

    $ perl berkeleydb-hash-bug-1166570.pl 1901 perl 5.014001 BerkeleyDB 0.49 db_version 5.1 INITIAL LOAD LLLL 1901 records LLLL-WWWWWWWWWWWWWWWWW 895 LLLL-YYYYYYYYYYYYYYYYYYYYYYYYYYYY 73 LLLL-WWWWWWWWWWWWWWWWW-WWWWWWWWWWWWWWWWW 1 LLLL-ZZZZZZ 76 LLLL 856 $ perl berkeleydb-hash-bug-1166570.pl 1902 perl 5.014001 BerkeleyDB 0.49 db_version 5.1 INITIAL LOAD LLLL 1902 records LLLL-YYYYYYYYYYYYYYYYYYYYYYYYYYYY 93 LLLL-WWWWWWWWWWWWWWWWW-WWWWWWWWWWWWWWWWW 494 LLLL-WWWWWWWWWWWWWWWWW-WWWWWWWWWWWWWWWWW-WWWWWWWWWWWWWWWWW 1 LLLL-WWWWWWWWWWWWWWWWW 1099 LLLL-YYYYYYYYYYYYYYYYYYYYYYYYYYYY-YYYYYYYYYYYYYYYYYYYYYYYYYYYY 37 LLLL-ZZZZZZ-ZZZZZZ 46 LLLL-ZZZZZZ 95 LLLL 37 $ perl berkeleydb-hash-bug-1166570.pl 1901 perl 5.012002 BerkeleyDB 0.43 db_version 5.1 INITIAL LOAD LLLL 1901 records LLLL-WWWWWWWWWWWWWWWWW 895 LLLL-YYYYYYYYYYYYYYYYYYYYYYYYYYYY 73 LLLL-WWWWWWWWWWWWWWWWW-WWWWWWWWWWWWWWWWW 1 LLLL-ZZZZZZ 76 LLLL 856 $ perl berkeleydb-hash-bug-1166570.pl 1902 perl 5.012002 BerkeleyDB 0.43 db_version 5.1 INITIAL LOAD LLLL 1902 records LLLL-YYYYYYYYYYYYYYYYYYYYYYYYYYYY 93 LLLL-WWWWWWWWWWWWWWWWW-WWWWWWWWWWWWWWWWW 494 LLLL-WWWWWWWWWWWWWWWWW-WWWWWWWWWWWWWWWWW-WWWWWWWWWWWWWWWWW 1 LLLL-WWWWWWWWWWWWWWWWW 1099 LLLL-YYYYYYYYYYYYYYYYYYYYYYYYYYYY-YYYYYYYYYYYYYYYYYYYYYYYYYYYY 37 LLLL-ZZZZZZ-ZZZZZZ 46 LLLL-ZZZZZZ 95 LLLL 37
      hehe even on "newer" versions
      $ perl berkeleydb-hash-bug-1166570.pl 1901 perl 5.018002 BerkeleyDB 0.54 db_version 6.0 INITIAL LOAD LLLL 1901 records LLLL-WWWWWWWWWWWWWWWWW-WWWWWWWWWWWWWWWWW 1 LLLL-ZZZZZZ 76 LLLL-WWWWWWWWWWWWWWWWW 895 LLLL 856 LLLL-YYYYYYYYYYYYYYYYYYYYYYYYYYYY 73 $ perl berkeleydb-hash-bug-1166570.pl 1902 perl 5.018002 BerkeleyDB 0.54 db_version 6.0 INITIAL LOAD LLLL 1902 records LLLL-WWWWWWWWWWWWWWWWW-WWWWWWWWWWWWWWWWW-WWWWWWWWWWWWWWWWW 1 LLLL-YYYYYYYYYYYYYYYYYYYYYYYYYYYY 93 LLLL-WWWWWWWWWWWWWWWWW-WWWWWWWWWWWWWWWWW 494 LLLL 37 LLLL-YYYYYYYYYYYYYYYYYYYYYYYYYYYY-YYYYYYYYYYYYYYYYYYYYYYYYYYYY 37 LLLL-ZZZZZZ 95 LLLL-WWWWWWWWWWWWWWWWW 1099 LLLL-ZZZZZZ-ZZZZZZ 46