不鼓励的perl习语的起源:&x(…)和sub x($$){…}

前端之家收集整理的这篇文章主要介绍了不鼓励的perl习语的起源:&x(…)和sub x($$){…}前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
在我的perl代码中,我之前使用过以下两种写作风格,我后来发现它们在现代perl中被劝阻:

# Style #1: Using & before calling a user-defined subroutine
&name_of_subroutine($something,$something_else);

# Style #2: Using ($$) to show the number of arguments in a user-defined sub
sub name_of_subroutine($$) {
  # the body of a subroutine taking two arguments.
}

由于不了解这些风格,我只是停止使用它们.

但是,出于好奇,我想知道以下内容

>这两种写作风格的起源是什么? (我敢肯定我自己没有想过这些款式.)
>为什么这两种写作风格在现代perl中不鼓励?
>在某个时间点,这些款式被认为是最佳做法吗?

解决方法

&由于两个原因,sigil不常用于现代Perl中的函数调用.首先,它很大程度上是多余的,因为Perl会将任何看起来像函数(后跟parens)的东西视为一个函数.其次,执行方式& 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

所以最终,使用&对于每个函数调用最终隐藏少数&函数;可能导致很难找到错误的电话.另外,使用& sigil阻止了对函数原型的尊重,这在某些情况下很有用(如果你知道你在做什么),但也可能导致难以追踪错误.最终,&是功能行为的强大修饰符,只应在需要该行为时使用.

原型是相似的,它们的使用应该在现代Perl中受到限制.必须明确说明的是Perl中的原型不是函数签名.它们是编译器的提示,告诉它以与内置函数类似的方式解析对这些函数调用.也就是说,原型中的每个符号都告诉编译器在参数上强加那种类型的上下文.在定义行为类似于map或push或keys的函数时,此功能非常有用,这些函数的处理方式与标准列表运算符不同.

sub my_map (&@) {...}  # first arg is either a block or explicit code reference

my @ret = my_map {some_function($_)} 1 .. 10;

不鼓励sub($$){…}和原型的类似用法的原因是因为9次中有10次作者意味着“我想要两个args”而不是“我想要两个args,每个args都有一个强加于调用的标量上下文现场”.前一个断言写得更好:

use Carp;
sub needs2 {
   @_ == 2 or croak 'needs2 takes 2 arguments';
   ...
}

这将允许以下调用样式按预期工作:

my @array = (2,4);

needs2 @array;

总结一下,这两个& sigil和函数原型是有用且功能强大的工具,但只有在需要该功能时才能使用它们.它们的多余使用(或作为参数验证的误用)导致意外行为并且难以追踪错误.

猜你在找的Perl相关文章