【问题标题】: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::DeclareFilter::Simple 是选项。

    【讨论】:

      【解决方案2】:

      如果 & 是原型中的第一件事,则只能使用块语法。来自perlsub

      & 需要匿名子例程,如果作为第一个参数传递,则不需要 sub 关键字或后续逗号

      Dancer2Mojolicious 中的其他自定义 DSL 通常使用 sub 关键字。

      get '/foo' => sub {
        ...
      };
      

      Plack::BuilderWeb::Scraper 使用块返回对象,然后可以嵌套。

      【讨论】:

        猜你喜欢
        • 2019-05-15
        • 1970-01-01
        • 2011-03-08
        • 1970-01-01
        • 2013-11-17
        • 2021-12-20
        • 2019-11-25
        • 2020-08-28
        • 2016-10-04
        相关资源
        最近更新 更多