2011-12-16 64 views
9

这是我有:我应该如何修改原型以允许在coderef之后构造散列?

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之后的参数转换为散列?

回答

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在哈希REF。

+2

它更准确的说,'first_attrib =>“1”,second_attrib =>“2”`是* list *,并且一个列表可以被分配给一个散列。 – friedo 2011-12-16 15:54:05

+0

@friedo:的确如此。感谢您指出了这一点。 – flesk 2011-12-16 16:08:25

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"; 
相关问题