2012-04-13 70 views
7

我無法理解哈希引用並在原地更改哈希,而不是返回它。我想寫一個子例程,它將從散列中返回一個值並修改散列。編碼時我遇到了一些問題。所以,我寫了下面的基本代碼來理解修改哈希的地方。在子程序中修改哈希引用的Perl

#!/usr/local/bin/perl 
#Check hash and array references 
#Author: Sidartha Karna 
use warnings; 
use strict; 
use Data::Dumper; 

sub checkHashRef{ 
    my ($hashRef, $arrVal) = @_; 
    my %hashDeref = %{$hashRef}; 

    $hashDeref{'check'} = 2;   
    push(@{$arrVal}, 3); 

    print "There:" ; 
    print Dumper $hashRef;  
    print Dumper %hashDeref;   
    print Dumper $arrVal 

} 


my %hashVal = ('check', 1); 
my @arrVal = (1, 2); 

checkHashRef(\%hashVal, \@arrVal); 

print "here\n"; 
print Dumper %hashVal; 
print Dumper @arrVal; 

觀察到的輸出是:



    There:$VAR1 = { 
      'check' => 1 
     }; 
    $VAR1 = 'check'; 
    $VAR2 = 2; 
    $VAR1 = [ 
      1, 
      2, 
      3 
     ]; 
    here 
    $VAR1 = 'check'; 
    $VAR2 = 1; 
    $VAR1 = 1; 
    $VAR2 = 2; 
    $VAR3 = 3; 

從輸出中,我推斷,改變hashDeref不修改所述參考的數據。我的理解是否正確?有沒有辦法修改散列變量而不是返回它。

回答

18

這使得%hashVal一(淺)副本:

my %hashDeref = %{$hashRef}; 

哈希裁判$hashRef仍指向%hashVal%hashDeref不,它只是一個副本。如果要修改就地傳遞哈希裁判,然後用通過哈希裁判工作:

sub checkHashRef{ 
    my ($hashRef, $arrVal) = @_; 
    $hashRef->{'check'} = 2; 
    #... 

,這將會使你的變化%hashVal。在陣的情況下,你永遠做一個副本,你只是取消對它的引用就地:

push(@{$arrVal}, 3); 

和變化$arrVal@arrVal顯示出來。

+0

謝謝「mu太短」 – Sid 2012-04-13 08:01:04