2011-03-07 62 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))