如何从已传递给perl中的子例程的哈希中检索数组

时间:2012-02-17 03:41:06

标签: arrays perl hash

我正在尝试编写一个子程序,它接受数组的哈希作为参数。但是,当我尝试检索其中一个数组时,我似乎得到了数组的大小而不是数组本身。

my(%hash) = (  );
$hash{"aaa"} = ["blue", 1];

_subfoo("test", %hash);

sub _subfoo {

    my($test ,%aa) = @_;

    foreach my $name (keys %aa) {
        my @array = @{$aa{$name}};
        print $name. " is ". @array ."\n";
    }
}

这会像我预期的那样返回2而不是(蓝色,1)。在子例程中是否还有其他方法可以处理哈希中的数组?

道歉,如果这对于堆栈溢出,第一次海报和编程新手来说太简单了。

2 个答案:

答案 0 :(得分:10)

您将@array数组置于标量上下文中:

print $name. " is ". @array ."\n";

标量上下文中的数组为您提供数组中元素的数量,@array恰好有2个元素。请尝试其中之一:

print $name . " is " . join(', ', @array) . "\n";
print $name, " is ", @array, "\n";
print "$name is @array\n";

您将看到@array的元素。使用join可以随意粘贴元素;第二个评估列表上下文中的@array并将值混合在一起而不将它们分开;第三个插入@array通过将其元素与$"(默认为单个空格)连接起来。

答案 1 :(得分:4)

由于mu太短了,你在标量上下文中使用了数组,因此它返回了它的长度而不是它的元素。我还有一些关于你的代码的其他指示。

当其中一些参数是数组或散列时,通过引用传递参数有时是个好主意。这样做的原因是数组和散列在传递给子程序之前会扩展到列表中,这使得这样的事情变得不可能:

foo(@bar, @baz);
sub foo {                        # This will not work
    my (@array1, @array2) = @_;  # All the arguments will end up in @array1
    ...
}

然而,这将有效:

foo(\@bar, \@baz);
sub foo {                  
    my ($aref1, $aref2) = @_;
    ...
}

您可能会发现,在您的情况下,each对于您的目的来说是一个很好的功能,因为它会使阵列的解除引用更加整洁。

foo("test", \%hash);  # note the backslash to pass by reference

sub foo {
    my ($test, $aa) = @_; # note use of scalar $aa to store the reference

    while (my ($key, $value) = each %$aa)) {  # note dereferencing of $aa
        print "$key is @$value\n";            # ...and $value
    }
}