我应该如何修改原型以允许在coderef之后构造哈希?

时间:2011-12-16 13:11:47

标签: perl subroutine-prototypes

这就是我所拥有的:

use 5.14.0;
use strict;
use warnings;

sub my_func(&$) {
    my $coderef = shift;
    my %attribs = @_;
}

这是我想要实现的目标:

my_func {
    print 1;
} first_attrib => "1",second_attrib => "2";

但是,我收到错误Too many arguments for main::my_func at x.pl line 12, near ""2";"。我应该如何修改原型,以便将coderef之后的参数转换为哈希?

2 个答案:

答案 0 :(得分:8)

如果您将sub my_func(&$)更改为sub my_func(&%),您的代码就可以使用。

问题是first_attrib => "1",second_attrib => "2"不是散列引用,而是列表。正如friedo指出的那样,可以将列表分配给散列,尽管具有奇数个元素的列表可能会产生不需要的结果,并会产生use warnings的警告。

或者,您可以将代码更改为

sub my_func(&$) {
    my $coderef = shift;
    my ($attribs) = @_;
}

my_func {
    print 1;
} {first_attrib => "1",second_attrib => "2"};

实现您的目标。

你必须将$attribs包装在parens中的原因是将数组赋给标量只返回数组中元素的数量。此时@_就是这个数组:

({first_attrib => "1",second_attrib => "2"})

将散列引用作为单个元素。

($attribs) = @_;

告诉perl创建一个标量$attribs作为其第一个元素的匿名数组,并逐个元素地将@_中的元素分配给匿名数组,从而使$attribs指向@_中的哈希引用。

答案 1 :(得分:3)

你需要实现Perl子的参数形成一个列表。您使用参数列表的第一个元素作为coderef,其余元素形成一个哈希:

#!/usr/bin/env perl

use 5.14.0;
use strict;
use warnings;

sub my_func(&@) {
    my $coderef = shift;
    my %attribs = @_;
    $coderef->() for keys %attribs;
}

my_func {
    print 1;
} first_attrib => "1",second_attrib => "2";