如何使用散列作为Perl中子例程的参数?

时间:2009-07-21 18:54:17

标签: perl hash parameters subroutine

我被要求修改一些现有代码以添加一些额外的功能。我在Google上搜索过,似乎无法找到答案。我有一些这样的效果......

%first_hash = gen_first_hash();
%second_hash = gen_second_hash();
do_stuff_with_hashes(%first_hash, %second_hash);

sub do_stuff_with_hashes
{
    my %first_hash = shift;
    my %second_hash = shift;

    # do stuff with the hashes
}

我收到以下错误:

Odd number of elements in hash assignment at ./gen.pl line 85.
Odd number of elements in hash assignment at ./gen.pl line 86.
Use of uninitialized value in concatenation (.) or string at ./gen.pl line 124.
Use of uninitialized value in concatenation (.) or string at ./gen.pl line 143.

第85行和第86行是子例程中的前两行,124和143是我访问哈希的地方。当我查找这些错误时,似乎暗示我的哈希值未初始化。但是,我可以验证哈希值是否有值。为什么我会收到这些错误?

5 个答案:

答案 0 :(得分:25)

将哈希值传递给函数时,哈希值将折叠为平面列表。因此,当您从函数的参数中移出一个值时,您只获得一个值。你想要做的是通过引用传递哈希值。

do_stuff_with_hashes(\%first_hash, \%second_hash);

但是你必须使用哈希作为参考。

my $first_hash  = shift;
my $second_hash = shift;

答案 1 :(得分:16)

有点晚了,但是,

如前所述,您必须传递引用,而不是哈希。

do_stuff_with_hashes(\%first_hash, \%second_hash);

但是如果你需要/想要使用你的哈希,你可以直接取消引用它们。

sub do_stuff_with_hashes {
    my %first_hash = %{shift()};
    my %second_hash = %{shift()};
};

答案 2 :(得分:9)

正如其他人所指出的那样,散列引用是要走的路。

提供另一种方法来执行此操作只是为了踢...因为谁需要临时变量?

do_stuff_with_hashes( { gen_first_hash() }, { gen_second_hash() } );

在这里,您只需动态创建哈希引用(通过函数调用周围的花括号)即可在do_stuff_with_hashes函数中使用。这没什么特别的,其他方法同样有效,可能更清晰。如果您在旅途中将此活动视为Perl的新手,这可能会有所帮助。

答案 3 :(得分:7)

首先,

 do_stuff_with_hashes(%first_hash, %second_hash);

将哈希“流”到列表中,相当于:

 ( 'key1_1', 'value1', ... , 'key1_n', 'value1_n', 'key2_1', 'value2_1', ... )

然后您选择其中一个项目。所以,

 my %first_hash = shift;

就像是说:

 my %first_hash = 'key1_1'; 
 # leaving ( 'value1', ... , 'key1_n', 'value1_n', 'key2_1', 'value2_1', ... )

您不能拥有{ 'key1' }之类的哈希值,因为'key1'无法映射到任何内容。

答案 4 :(得分:0)

没有shift()的解决方案速度更快,因为它不会复制内存中的数据,您可以在子例程中修改哈希。看看我的例子:

sub do_stuff_with_hashes($$$) {
    my ($str,$refHash1,$refHash2)=@_;
    foreach (keys %{$refHash1}) { print $_.' ' }
    $$refHash1{'new'}++;
}

my (%first_hash, %second_hash);
$first_hash{'first'}++;
do_stuff_with_hashes('any_parameter', \%first_hash, \%second_hash);
print "\n---\n", $first_hash{'new'};