2011-06-29 31 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。