2011-12-12 43 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"; 
    } 
}