2011-03-07 61 views
3

是否可以使用「圓括號」語法將代碼塊傳遞給子?Perl - 通過代碼塊作爲圓括號內的參數

I.e.當我寫

List::MoreUtils::any { defined ($_) } (undef, undef, 1); 

它的工作原理。但是當我嘗試添加括號時

List::MoreUtils::any ({ defined ($_) } , (undef, undef, 1)); 

這被解釋爲一個匿名散列,給出一個錯誤消息。無論是逃避還是使用eval都無濟於事。

後面所有忙亂的想法是,如果該呼叫是一個表達式的一部分,即

if (first_index { defined (${$_})} $jms_positions > $jms_positionals_seen) 

一些運算符之後的參數可能會在呼叫之前執行,從而產生不期望的結果。

回答

15

一個匿名子程序聲明的語法

sub { say "The sub with no name!" }; 

Perl的原型系統允許一個特殊的例外,代碼塊是第一個參數,在這種情況下你可以離開領先的sub,只是通過該塊,類似於Perl內置。但是,只有在無括號的風格中調用它時纔有效。使用parens會導致解析器認爲你想傳遞一個hash-ref。

因此可以這樣說

List::MoreUtils::any(sub { defined }, undef, undef, 1); 

如果你堅持要用括號。

+0

不知何故,這個工程。我認爲一個'sub'需要在一個塊內的return語句來向主叫方提供任何東西。令人驚訝的是,它不是! Perl的語法確實是我見過的最奇怪的語法。 – 2011-03-07 19:53:27

+0

'sub {42}; '返回42. – Dallaylaen 2011-03-07 20:47:47

+1

=> parens不會關閉原型。爲此,你還需要'&'sigil。在這種情況下,parens只是混淆perl的解析器。 – 2011-03-07 22:21:00

3

只需插入sub

List::MoreUtils::any (sub { defined ($_) } , (undef, undef, 1)); 
5

不,只適用於builtins。

$ perl -ce'map({ "..." } @a)' 
-e syntax OK 

$ perl -ce'grep({ "..." } @a)' 
-e syntax OK 

$ perl -ce'sub f(&@); f { "..." } @a' 
-e syntax OK 

$ perl -ce'sub f(&@); f({ "..." } @a)' 
Array found where operator expected at -e line 1, near "} " 
     (Missing operator before ?) 
syntax error at -e line 1, near "} @a" 
-e had compilation errors. 

在整個調用中添加parens通常是一個合適的解決方法。

(any { defined } (undef, undef, 1))