原型:返回数组或标量

时间:2014-04-01 12:37:09

标签: arrays perl reference return-value perl-data-structures

我无法理解如何使用子程序原型返回数组。 这是一个例子

sub f (&@) {
        my ($func) = @_;        
        eval &$func;
}

my $a = f {return 1};
my @b = f {return (2,1,1,4)};

print "a = ".$a."\n";
print "b = ".scalar(@b)."\n";

这会输出a = 1b = 1,但我希望@b的长度为4。

我还尝试在函数\ eval &$func中返回引用f。然后我可以取消引用标量($$a是1),但是在取消引用数组(@$b)perl时告诉我它不是数组引用。

2 个答案:

答案 0 :(得分:5)

原型对子例程是返回标量还是列表没有影响。如果您想知道调用子程序的上下文,请使用wantarray

eval &$func;

上面的行首先在标量上下文中调用$func引用的子例程,然后将其返回值转换为字符串并将该字符串作为Perl程序执行。

sub f (&) {
    my ($func) = @_;
    eval { &$func }
}

这将执行您显然想要的操作(在$func块内调用feval本身被调用的相同上下文(标量或列表)中调用的子例程捕捉运行时错误。)

sub f (&) {
    my ($func) = @_;
    eval { $func->(@_) }
}

这是更现代的风格,使用->运算符。

答案 1 :(得分:1)

无需评估,您可以

use warnings;
sub f (&) {
    my ($func) = @_;
    $func->(); # better than &$func
}
另一方面,

eval仅返回$f给出的列表中的最后一个元素,因为它与编写eval scalar $func->();相同,因此@b最终只有一个element => 4

来自perldoc -f eval

  

EXPR的返回值被解析并执行,好像它是一个小的Perl程序。首先解析表达式的值(它本身在标量上下文中确定),如果没有错误,则在当前Perl程序的词汇上下文中作为块执行。