&
由於兩個原因,sigil不常用於現代Perl中的函數調用。首先,它很大程度上是多餘的,因爲Perl會考慮任何看起來像函數(隨後是parens)的函數。其次,執行&function()
和&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
因此最終,對每個函數調用使用&
最終隱藏了幾個&function;
調用,這會導致難以發現的錯誤。另外,使用&
sigil可以防止遵守函數原型,這在某些情況下很有用(如果您知道你在做什麼),但也可能導致困難追蹤錯誤。最終,&
是功能行爲的強大修飾符,只應在需要該行爲時使用。
原型是相似的,它們的使用應該限制在現代Perl中。必須明確說明的是,Perl中的原型不是函數簽名。它們提示編譯器告訴它以與內置函數類似的方式解析對這些函數的調用。也就是說,原型中的每個符號都會告訴編譯器在參數上強加這種類型的上下文。此功能在定義類似於map
或push
或的函數時非常有用,它們的第一個參數與標準列表運算符的區別不同。
sub my_map (&@) {...} # first arg is either a block or explicit code reference
my @ret = my_map {some_function($_)} 1 .. 10;
原因原型sub ($$) {...}
和類似用途都望而卻步,因爲9次了10年筆者的意思是「我想有兩個參數」,而不是「我希望每個有兩個參數與施加在調用點標量上下文」 。前者主張更好地寫着:
use Carp;
sub needs2 {
@_ == 2 or croak 'needs2 takes 2 arguments';
...
}
這將然後允許如預期的那樣在呼叫風格的工作:
my @array = (2, 4);
needs2 @array;
綜上所述,無論是&
印記和函數原型是有用和強大的工具,但只有在需要該功能時才能使用它們。他們多餘的使用(或誤用作參數驗證)會導致意外的行爲,並且很難追蹤錯誤。
所有已經討論過的SO:http://stackoverflow.com/questions/2056904 http:// stackoverflow。com/questions/297034 http://stackoverflow.com/questions/2485078 – daxim 2010-05-16 15:45:54
[爲什麼Perl函數原型不好?](http://stackoverflow.com/questions/297034/why-are-perl-function- prototypes-bad) – Ether 2010-05-16 16:42:19
由於'&foo(@args)'的使用覆蓋了原型,所以你會問這兩種常見的Perl特性濫用問題,這很具有諷刺意味。 – daotoad 2010-05-16 18:24:45