&
由于两个原因,sigil不常用于现代Perl中的函数调用。首先,它很大程度上是多余的,因为Perl会考虑任何看起来像函数(随后是parens)的函数。其次,执行&function()
和&function
的方式有很大的不同,这可能会让经验较少的Perl程序员感到困惑。在第一种情况下,函数被调用时没有参数。在第二种情况下,调用函数与当前@_
(它甚至可以更改参数列表将被后来的语句在范围中可以看出:
sub print_and_remove_first_arg {print 'first arg: ', shift, "\n"}
sub test {
&print_and_remove_first_arg;
print "remaining args: @_\n";
}
test 1, 2, 3;
打印
first arg: 1
remaining args: 2 3
因此最终,对每个函数调用使用&
最终隐藏了几个&function;
调用,这会导致难以发现的错误。另外,使用&
sigil可以防止遵守函数原型,这在某些情况下很有用(如果您知道你在做什么),但也可能导致困难追踪错误。最终,&
是功能行为的强大修饰符,只应在需要该行为时使用。
原型是相似的,它们的使用应该限制在现代Perl中。必须明确说明的是,Perl中的原型不是函数签名。它们提示编译器告诉它以与内置函数类似的方式解析对这些函数的调用。也就是说,原型中的每个符号都会告诉编译器在参数上强加这种类型的上下文。此功能在定义类似于map
或push
或的函数时非常有用,它们的第一个参数与标准列表运算符的区别不同。
sub my_map (&@) {...} # first arg is either a block or explicit code reference
my @ret = my_map {some_function($_)} 1 .. 10;
原因原型sub ($$) {...}
和类似用途都望而却步,因为9次了10年笔者的意思是“我想有两个参数”,而不是“我希望每个有两个参数与施加在调用点标量上下文” 。前者主张更好地写着:
use Carp;
sub needs2 {
@_ == 2 or croak 'needs2 takes 2 arguments';
...
}
这将然后允许如预期的那样在呼叫风格的工作:
my @array = (2, 4);
needs2 @array;
综上所述,无论是&
印记和函数原型是有用和强大的工具,但只有在需要该功能时才能使用它们。他们多余的使用(或误用作参数验证)会导致意外的行为,并且很难追踪错误。
所有已经讨论过的SO:http://stackoverflow.com/questions/2056904 http:// stackoverflow。com/questions/297034 http://stackoverflow.com/questions/2485078 – daxim 2010-05-16 15:45:54
[为什么Perl函数原型不好?](http://stackoverflow.com/questions/297034/why-are-perl-function- prototypes-bad) – Ether 2010-05-16 16:42:19
由于'&foo(@args)'的使用覆盖了原型,所以你会问这两种常见的Perl特性滥用问题,这很具有讽刺意味。 – daotoad 2010-05-16 18:24:45