ivan_pozdeev ivan_pozdeev - 3 months ago 20
Perl Question

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 anonymous 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.

Answer

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.