为什么我不能在这里省略()?

new*_*erl 6 perl

SaveImages @img_sources;
Run Code Online (Sandbox Code Playgroud)

以上将报告:

Array found where operator expected 
Run Code Online (Sandbox Code Playgroud)

为什么我不能省略()这里?

Nyl*_*ile 13

因为您的SaveImages子例程是在调用后声明的.如果在调用之前声明子例程,则不需要括号.

例:

use strict;
use warnings;
use Data::Dumper;
my @ar = (1, 2);
fn @ar;
sub fn
{
    print Dumper \@_;
}
Run Code Online (Sandbox Code Playgroud)

不起作用,而

use strict;
use warnings;
use Data::Dumper;
my @ar = (1, 2);
sub fn
{
    print Dumper \@_;
}
fn @ar;
Run Code Online (Sandbox Code Playgroud)

作品.

这是一种预期的行为,并在骆驼书中指出.


sal*_*lva 6

Perl可以在没有parens的情况下解析对子程序的调用,而这些子程序之前已经被声明(或定义)了.例如:

sub SaveImages;

SaveImages @img_sources;
Run Code Online (Sandbox Code Playgroud)


Dav*_*idO 6

来自perlsub:

要调用子例程:

NAME(LIST); # & is optional with parentheses.
NAME LIST; # Parentheses optional if predeclared/imported.
&NAME(LIST); # Circumvent prototypes.
&NAME; # Makes current @_ visible to called subroutine.
Run Code Online (Sandbox Code Playgroud)

通常潜艇在实践中不会预先申报.这通常不是问题,因为人们通常习惯于使用程序员创建的子程序.

Perl :: Critic(Perl最佳实践中提出的支持Damien Conway的Perltopia模型的模块)建议对sub进行以下处理:

  • 禁止使用&符号.
  • 禁止子程序原型.
  • 禁止内置插件的parens.

不使用带有内置函数的parens的原因之一是使它们在视觉上与程序定义的函数区别开来,这些函数传统上使用parens.因为preclare subs是不寻常的,并且不鼓励使用&符号(因为它改变了@_的处理方式)或原型(因为,这是一个长篇故事),留下了使用parens和脚本的非常强大的背景 - 定义的潜艇.