我无法理解如何使用子程序原型返回数组。 这是一个例子
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 = 1
和b = 1
,但我希望@b
的长度为4。
我还尝试在函数\ eval &$func
中返回引用f
。然后我可以取消引用标量($$a
是1),但是在取消引用数组(@$b
)perl时告诉我它不是数组引用。
答案 0 :(得分:5)
原型对子例程是返回标量还是列表没有影响。如果您想知道调用子程序的上下文,请使用wantarray
。
eval &$func;
上面的行首先在标量上下文中调用$func
引用的子例程,然后将其返回值转换为字符串并将该字符串作为Perl程序执行。
sub f (&) {
my ($func) = @_;
eval { &$func }
}
这将执行您显然想要的操作(在$func
块内调用f
在eval
本身被调用的相同上下文(标量或列表)中调用的子例程捕捉运行时错误。)
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
EXPR的返回值被解析并执行,好像它是一个小的Perl程序。首先解析表达式的值(它本身在标量上下文中确定),如果没有错误,则在当前Perl程序的词汇上下文中作为块执行。