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

时间:2011-06-29 06:49:04

标签: perl

SaveImages @img_sources;

以上将报告:

Array found where operator expected 

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

5 个答案:

答案 0 :(得分:13)

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

示例:

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

不起作用,而

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

的工作原理。

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

答案 1 :(得分:6)

Perl可以先解析(或定义)那些没有parens的子程序。例如:

sub SaveImages;

SaveImages @img_sources;

答案 2 :(得分: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.

通常在实践中不预先声明潜艇。这通常不是问题,因为人们通常习惯于使用程序员创建的潜艇。

Perl::Critic(支持Damien Conway Perltopia模型的模块,如Perl最佳实践中所述)建议对以下方法进行以下处理:

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

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

答案 3 :(得分:4)

这里有很多好处,还有一点:另见subs pragma。在函数调用之前使用use subs qw/SaveImage/;(可能在其他use调用的顶部附近),它应该以一种不那么突兀的方式很好地预先声明你的子。

答案 4 :(得分:-2)

您可以省略具有内置函数的()(请参阅perlfunc),因为内置函数是该语言的关键字,不需要将括号识别为函数。

一些导入的函数(来自max的{​​{1}}),通常来自核心模块,也可以不带括号调用。

如果在调用之前声明了子例程,则也可以省略括号,尽管Perl Best Practices(第2章,第4节)建议避免它以区分对子例程和内置函数的调用。