2012-10-23 35 views
2

'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"; 
} 

寄託都工作正常!

但是,如果我用一個綁哈希,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,Larry Wall的 ...

我瘦國王,如果它是一個錯誤?

也許更多的事情在幕後...

我問我的解決方案是否正確?

回答

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 
+0

@Dinak,更新了我的答案。 – ikegami

+0

對不起!沒有第二次調用,代碼將無限期地運行。我認爲,當它更新值時,每個索引都會回退1.然後,下一次對每個索引再次獲取相同的條目。我所看到的是重複的一對鑰匙,價值正在印刷上新的價值。 – Dinak

+0

期望的是一個與新值匹配的URL列表。 (我使用第二個電話來完成)。 – Dinak

相關問題