Perl - передать блок кода в качестве параметра в скобках - PullRequest
3 голосов
/ 07 марта 2011

Можно ли передать блок кода в подпрограмму с использованием синтаксиса "круглых скобок"?

Т.е. когда я пишу

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

, это работает.Но когда я пытаюсь добавить скобки

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

, это интерпретируется как анонимный хеш, выдающий сообщение об ошибке.Не помогает ни экранирование, ни использование eval.

Идея, лежащая в основе всей этой суеты, заключается в том, что вызов является частью выражения, т.е.вызов, выдающий нежелательный результат.

Ответы [ 3 ]

15 голосов
/ 07 марта 2011

Анонимная подпрограмма объявляется с синтаксисом

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

Система-прототип Perl допускает специальное исключение, когда блок кода является первым параметром, в этом случае вы можете опустить ведущий sub и простопередать блок, похожий на встроенный Perl.Но это работает только при вызове в стиле без скобок.Использование паренов заставляет парсер думать, что вы хотите передать хеш-реф.

Таким образом, вы можете сказать

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

Если вы настаиваете на использовании паренов.

5 голосов
/ 08 марта 2011

Нет, только для встроенных.

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

Добавление круглых скобок вокруг всего вызова обычно является подходящим решением.

( any { defined } (undef, undef, 1) )
3 голосов
/ 07 марта 2011

Просто вставьте sub:

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