2016-07-05 7 views
2

を動作しないハッシュリファレンスを(私は一種の終わりにすべての方法を参照して、これを考え出しNOTE)を渡します長すぎる。私は最終的に、ハッシュをテストし、参照渡しするための短いテストプログラムを書いて、期待通りに動作しません。私は何か非常にシンプルな私は行方不明だと確信している...誰もそれを見つけることができますか?perlは予想通り

#!/usr/bin/perl 
use Data::Dumper; 

my %hash =(); 
print "BEFORE ADDING KEYS\n"; 
print Dumper (\%hash); 
test (\%hash, 10); 
print "AFTER ADDING KEYS\n"; 
print Dumper (\%hash); 

sub test { 

my %hash = %{$_[0]}; 
my $number = $_[1]; 
if ($number == 0) { return; } 

print "BEFORE ADDING KEY HASH_REF=$_[0] NUMBER=$number\n"; 
print Dumper (\%hash); 
$hash{$number} = $number; 
print "AFTER ADDING KEY\n"; 
print Dumper (\%hash);  
test ($_[0], $number - 1); 
} 

私は、このコードは私のハッシュに1に番号10を追加することを期待し、代わりにハッシュを一掃取得し、テストルーチンを再帰的に終了したら、何が含まれていません。私は何が欠けていますか?

BEFORE ADDING KEYS 
$VAR1 = {}; 
BEFORE ADDING KEY HASH_REF=HASH(0xdb82fd0) NUMBER=10 
$VAR1 = {}; 
AFTER ADDING KEY 
$VAR1 = { 
      '10' => 10 
     }; 
BEFORE ADDING KEY HASH_REF=HASH(0xdb82fd0) NUMBER=9 
$VAR1 = {}; 
AFTER ADDING KEY 
$VAR1 = { 
      '9' => 9 
     }; 

... 

BEFORE ADDING KEY HASH_REF=HASH(0xdb82fd0) NUMBER=1 
$VAR1 = {}; 
AFTER ADDING KEY 
$VAR1 = { 
      '1' => 1 
     }; 
AFTER ADDING KEYS 
$VAR1 = {}; 

この行を変更する:

$hash{$number} = $number; 

へ:予想通り

$_[0]->{$number} = $number; 

はすべての作品を作ったここで出力されます。このローカル%ハッシュが最初にルーチンに渡されたのと同じde-referencedハッシュリファレンスを参照すると、最初のステートメントは新しいローカル%ハッシュを変更するのはなぜですか?

+0

Re *なぜ最初のステートメントが新しいローカル%hash *を変更するのですか?同じ名前の2つの変数がある場合、内側の変数のみが表示されます。 '%hash 'を変更すると、グローバルなものではなくローカルのものが変更されます。 – ikegami

答えて

6

すべてが意図したとおりに動作します。あなた通過したハッシュのコピーになり、テストサブの最初の文:

my %hash = %{$_[0]}; 

渡されたハッシュを変異させると、あなたは同じように、ハッシュ・リファレンスで動作します:

my $hashref= $_[0]; 

$hashref->{key} = 'val'; 

このアプローチは、それはだ、オリジナルのハッシュをしませ変わりますコピー。

+0

逆参照されたハッシュリファレンスに%ハッシュを代入するとコピーが作成されるのはちょっとわかりませんでした。 –

+0

申し訳ありませんが、私はUN直感的な意味でした。 –

関連する問題