2011-12-12 79 views
9

我知道這應該很容易在谷歌搜索,更不用說perl的一個微不足道的用途,但我已經嘗試了很多我找到的解決方案,到目前爲止沒有人給出了預期的行爲。本質上,我試圖調用子例程,從該子例程返回對散列的引用,將對該散列的引用傳遞給另一個子例程,然後通過類似於以下代碼打印該散列的內容:如何在perl中通過引用傳遞散列

#!/usr/bin/perl                                                 

my $foo = make_foo(); 

foreach $key (sort keys %$foo) { 
    print "2 $key $$foo{$key}\n"; 
} 

print_foo(\%foo); 

sub print_foo 
{ 
    my %loc = ???; 
    foreach $key (sort keys %loc}) { 
     print "3 $key $loc{$key}\n"; 
    } 
} 

sub make_foo 
{ 
    my %ret; 
    $ret{"a"} = "apple"; 
    foreach $key (sort keys %ret) { 
     print "1 $key $ret{$key}\n"; 
    } 
    return \%ret; 
} 

有人可以告訴我這樣做的最佳方式(通過子程序),而不創建一個額外的哈希副本?我試過的解決方案沒有打印出以「3」開頭的任何行。

+8

另外,我強烈建議你開始在所有代碼的頂部使用'use strict'。你需要改變你的'foreach'行來使用'my'聲明你的變量,但是它會爲你節省很多麻煩,來調試簡單的拼寫錯誤。 – zostay

回答

10

你必須拉爲參考參數,然後取消對它的引用:

sub print_foo 
{ 
    my ($loc) = @_; 
    foreach my $key (sort keys %$loc) { 
     print "3 $key $loc->{$key}\n"; 
    } 
} 

每當你做一個參考,你必須明確地取消對它的引用。另外,請注意,對引用的任何更改都會更改原始內容。如果你想避免改變原有的,你可以通過哈希作爲一個列表:

print_foo(%foo); # flattens the hash to a list and passes it in through @_ 

sub print_foo 
{ 
    my (%loc) = @_; # load the hash from the list 
    foreach my $key (sort keys %loc) { 
     print "3 $key $loc{$key}\n"; 
    } 
} 

或者散列引用複製到一個新的哈希:

sub print_foo 
{ 
    my ($ref_loc) = @_; # changes to %$ref_loc will change %foo 
    my %loc = %$ref_loc; # COPY, changes to %loc do not change %foo 
    foreach my $key (sort keys %loc}) { 
     print "3 $key $loc{$key}\n"; 
    } 
} 
-1

要轉換,從一個參考哈希像這樣:

my %loc = %{@_[0]}; 

my %loc = %{shift}; 

你也可以把它作爲一個參考:

my $locref = shift; 
foreach $key (sort keys %$locref}) { 
    print "3 $key $locref->{$key}\n"; 
} 

這信息可以通過在命令行輸入perldoc perlref找到。

+4

單元素片段可以更好地寫爲'%{$ _ [0]}','%{shift}'是指名爲'shift'的哈希變量,您可能意指'%{+ shift}'或'%{shift @_}'。命名循環變量應該是詞法'foreach my $ key ...' –

+0

正確的所有計數。 – Dan

3

其他一切都是好的,所以我「M只是要集中精力print_foo ...

sub print_foo 
{ 
    my %loc = %{shift @_}; 
    foreach $key (sort keys %loc) { 
     print "3 $key $loc{$key}\n"; 
    } 
} 

僅供參考,你需要認識到現在%LOC是哈希的COPY(我問了一個問題,它在這裏解釋這一點:Confusion about proper usage of dereference in Perl)。爲了避免複製...

sub print_foo 
{ 
    my $loc = shift @_; 
    foreach $key (sort keys %$loc) { 
     my $val = $loc->{$key} 
     print "3 $key $val\n"; 
    } 
}