2011-06-29 44 views
6
SaveImages @img_sources; 

以上将报告:为什么我不能忽略()在这里?

Array found where operator expected 

为什么我不能忽略这里的()

+1

我不知道。你从哪里得到'SaveImages'? –

+1

总是显示一个完整的测试脚本。这通常会显示导致问题的事情,比如缺少名为“SaveImages”的声明子例程。 –

回答

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; 

作品。

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

-2

由于内置函数是语言的关键字,因此不需要使用括号来识别功能,因此可以省略带内置函数的()(请参阅perlfunc)。

通常来自核心模块的一些导入函数(如max from List::Util)也可以在没有括号的情况下调用。

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

+2

请注意,Perl函数原型** _不是与其他语言中的函数原型相同的东西(它们只是名字不好)。你可能不想使用它们,很好,几乎没有。另外,-1:不正确。您可以使用用户定义的子元素忽略父元素,前提是子元素在调用之前定义。 –

+1

如果您宣布了正确的原型,则不需要parens。你想'sub fn(@){print @_; }'我假设你想打印的内容不是参考值正确的:) –

+0

@Joel你说得对。我只是在测试,并认为它并不重要。谢谢。答案已更新。 –

6

当以前声明(或已定义)的Perl时,Perl可以解析调用子程序而不需要parens。例如:

sub SaveImages; 

SaveImages @img_sources; 
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. 

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

Perl::Critic(A支持Perltopia达明康威的模型在Perl最佳实践阐述模块)提出以下处理的潜艇:

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

不使用parens内置插件的原因之一是使它们在视觉上不同于程序定义的函数,传统上它使用parens。由于预先声明subs是不常见的,因此使用&符号(因为它改变了如何处理@)或原型(因为它是一个很长的故事)是不鼓励的,这为使用parens和script-定义的潜艇。

4

这里有很多优点,只是一个:另请参阅subs pragma。在你的函数调用之前(可能与其他use调用接近顶部)使用类似use subs qw/SaveImage/;,它应该很好地以不太突出的方式预先声明你的sub。

相关问题