【问题标题】:Perl function that takes a BLOCK as the second parameter?将 BLOCK 作为第二个参数的 Perl 函数?
【发布时间】:2023-02-06 20:13:48
【问题描述】:
我想写一个第一个参数是描述,第二个参数是代码块的函数。我希望完成的代码读起来像:
verify "description" { boolean-assertion-block };
我特别希望避免使用 sub 关键字。
我可以将描述放在代码块之后,没问题:
sub verify (&$) { ... }
但是当我反转原型符号顺序时:
sub verify ($&) { ... }
然后我收到一条错误消息:
Type of arg 2 to main::verify must be sub {} (not anonymous hash ({})) at ...
显然,Perl 对作为代码块的第一个参数有特殊处理。
那么,也许我可以把它变成一个咖喱函数?
sub verify ($) {
my $message = shift;
return sub (&) { . . . }
}
但是后来我在描述和代码块之间发现了一个语法错误:
syntax error at ... near ""..." { "
我尝试更改调用语法以尝试帮助编译器:
test "...", { BLOCK };
test("..."){ BLOCK };
test("...")({ BLOCK });
( test "..." )({ BLOCK });
没有快乐。 Perl 甚至可以做我想做的事吗?
【问题讨论】:
标签:
perl
higher-order-functions
currying
【解决方案1】:
(&) 原型只有在用于子程序中的第一个参数时才有这样的好处。来自perldoc perlsub:
"&" 的有趣之处在于你可以用它生成新的语法,只要它在初始位置
提供类似级别的友好的一种方法是:
sub verify ($%) {
my ( $message, %opts ) = @_;
my $coderef = $opts{using};
...;
}
sub using (&) {
my ( $coderef ) = @_;
return ( using => $coderef );
}
# The `verify` sub accepts a name followed by a hash of options:
#
verify(
"your message here",
"using" => sub { ... },
);
# The `using` sub returns a two-element list that will satisfy
# that hash of options:
#
verify "your message here", using {
...;
};
如果您迫切希望允许完全相同的语法:
verify "description" { boolean-assertion-block };
......那么它仍然是可能的,但需要黑魔法。 Keyword::Simple 可能是您最好的选择,但 Devel::Declare 和 Filter::Simple 是选项。