如何在perl中通过引用传递哈希

时间:2011-12-12 21:52:48

标签: perl

我知道这应该可以在google上轻松搜索,更不用说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”开头的任何行。

3 个答案:

答案 0 :(得分: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 :(得分:3)

其他一切都很好,所以我只专注于print_foo ......

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

仅供参考,你需要意识到%loc现在是哈希的副本(我在这里问了一个解释这个问题的问题: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";
    }
}

答案 2 :(得分:-1)

您希望将其从引用转换为哈希,如下所示:

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

my %loc = %{shift};

您也可以将其作为参考:

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

可以通过在命令行键入perldoc perlref来找到此信息。