2016-07-05 40 views
2

注:我有點想通了這一點,看到所有的方式在年底的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); 
} 

我希望這個代碼10添加數字1到我的哈希值,而是哈希被消滅了,一旦測試程序完成遞歸不包含任何東西。我錯過了什麼?下面是輸出:

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; 

使一切工作正常。爲什麼第一條語句會修改新的本地%散列,當我期望這個本地%散列指向我最初傳入例程的相同的去引用散列引用?

+0

Re「*爲什麼第一條語句會修改新的本地%hash *」,如果有兩個具有相同名稱的變量,則只有內部變量可見。因此改變'%hash'將會改變本地的,而不是全局的。 – ikegami

回答

6

一切按預期工作。在測試子你先聲明使得通過哈希的副本:

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

變異通過哈希,你應該hashref工作,如:

my $hashref= $_[0]; 

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

這種方法會改變原來的哈希值,而不是它的複製。

+0

這對我來說有點直觀,即將%散列分配給解除引用的散列引用會生成副本! –

+0

對不起,我的意思是非直覺。 –