如果我们在每个循环中更改/更新哈希值会发生什么?

时间:2012-10-23 17:14:34

标签: perl function hash each tie

'perldoc -f each'说我不安全删除或在迭代时添加值,除非该项是每个()最近返回的项。

当我运行此代码snnipet时:

my ($key,$value);

my %fruits = qw/ banana 1 apple 2 grape 3 /;

while ( $key = each %fruits ) {
    $fruits{$key} *= 7;
    print "$key = $fruits{$key}\n";
}

print "\nRead only\n\n";

while ( ($key,$value) = each %fruits ) {
    print "$key = $value\n";
}

everthing工作正常!

但是如果我使用绑定哈希,humnn:

#-------------------------------------------------------------------------------
# select entries on database to print or to update.
sub select_urls {
    my ($dbPath,$match,$newValue) = @_;

    tie(my %tiedHash,'DB_File',$dbPath,O_RDWR|O_EXLOCK,0600,$DB_BTREE) || die("$program_name: $dbPath: $!\n");

    while ( my($key,$value) = each %tiedHash ) {
        if ( $key =~ $match ){
            if ( defined $newValue ) {
                $tiedHash{$key} = $newValue;
                ($key,$value) = each %tiedHash; # because 'each' come back 1 step when we update the entry
                print "Value changed --> $key = $value\n";
            } else {
                print "$key = $value\n";
            }
        }
    }

    untie(%tiedHash) ||  die("$program_name: $dbPath: $!\n");
}

是必要的第二次调用每个()。

我必须'perl -v':

  

$ perl -v

     

这是perl 5,版本12,颠覆2(v5.12.2(*))   amd64-openbsd(有8个注册补丁,详见perl -V)

     

版权所有1987-2010,拉里沃尔   ...

我在想它是不是一个错误?!!

也许幕后会有更多的事情......

我问我的解决方案是否正确???

1 个答案:

答案 0 :(得分:3)

这是问题的元素(键)的添加或删除。改变价值应该没有问题。并列哈希没有固有的区别。

my ($key,$value);

use Tie::Hash;

tie my %fruits, 'Tie::StdHash';
%fruits = qw/ banana 1 apple 2 grape 3 /;

while ( $key = each %fruits ) {
    $fruits{$key} *= 7;
    print "$key = $fruits{$key}\n";
}

print "\nRead only\n\n";

while ( ($key,$value) = each %fruits ) {
    print "$key = $value\n";
}

输出:

banana = 7
apple = 14
grape = 21

Read only

banana = 7
apple = 14
grape = 21

您的第二个代码段未显示错误。它没有展示任何东西。它不可运行,您没有指定输出内容,也没有指定您希望输出的内容。但是,让我们看看DB_File是否存在问题。

use DB_File qw( $DB_BTREE );
use Fcntl   qw( O_RDWR O_CREAT );  # I don't have O_EXLOCK

my ($key,$value);

tie(my %fruits, 'DB_File', '/tmp/fruits', O_RDWR|O_CREAT, 0600, $DB_BTREE)
   or die $!;
%fruits = qw/ banana 1 apple 2 grape 3 /;

while ( $key = each %fruits ) {
    $fruits{$key} *= 7;
    print "$key = $fruits{$key}\n";
}

print "\nRead only\n\n";

while ( ($key,$value) = each %fruits ) {
    print "$key = $value\n";
}

不。

apple = 14
banana = 7
grape = 21

Read only

apple = 14
banana = 7
grape = 21