Perl - pass code block as parameter inside parentheses
Is it possible to pass a block of code to a sub using "parentheses" syntax?
I.e. when i write
List::MoreUtils::any { defined ($_) } (undef, undef, 1);
it works. But when i try to add parentheses
List::MoreUtils::any ( { defined ($_) } , (undef, undef, 1) );
this is interpreted as an an开发者_JAVA技巧onymous hash, giving an error message. Neither escaping nor using eval helps.
The idea behind all the fuss is if the call is a part of an expression, i.e.
if (first_index { defined (${$_})} $jms_positions > $jms_positionals_seen )
some operator following the arguments might be executed before the call, producing an undesired result.
An anonymous subroutine is declared with the syntax
sub { say "The sub with no name!" };
Perl's prototype system allows a special exception where a code block is the first parameter, in which case you can leave off the leading sub
and just pass the block, similar to a Perl builtin. But this only works when calling it in the parentheses-less style. Using parens causes the parser to think you want to pass a hash-ref.
So you can say
List::MoreUtils::any( sub { defined }, undef, undef, 1 );
If you insist on using parens.
No, only for the 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.
Adding parens around the whole call is usually a suitable workaround.
( any { defined } (undef, undef, 1) )
Just insert sub
:
List::MoreUtils::any ( sub { defined ($_) } , (undef, undef, 1) );
精彩评论