将块传递给Moose方法

mhd*_*mhd 5 perl moose

是否有可能将块传递给Moose方法?在标准的Perl中,我可以使用这样的原型定义一个函数

sub fn (&) {
    my $code =\&{shift @_};
    $code->();
}
Run Code Online (Sandbox Code Playgroud)

然后将一个块传递给函数而没有显式sub引用,即fn { say "Hi there, world" }.

我认为这只有在子程序是第一个参数的情况下才有可能,并且因为这总是$self使用Moose方法,所以它似乎不可能存在,迫使我以稍微更明确的方式做到这一点:

sub wrapper {
    my ($self, $code) = @_;
    $code->()
}

Wrapper->wrapper(sub { say "Hi there, world" });
Run Code Online (Sandbox Code Playgroud)

现在,这将是一个非常方便的方式来包装一些块,即提供一些额外的文本或有条件地执行代码或围绕一些代码,其中错误处理保持不变(例如,eval一些代码和日志错误,记录用户等. ).

如果我没有遗漏某些东西,是否有一些半便捷的解决方法或替代方法来实现这样的事情而没有太多的线路噪音?

dra*_*tun 4

看一下PerlX::MethodCallWithBlockCPAN 模块,它扭曲了 Perl 语法(通过模块)以允许您在方法调用后 Devel::Declare放置一个块。

例如:

use 5.016;
use warnings;
use PerlX::MethodCallWithBlock;

{
    package Foo;
    use Moose;

    sub bar {
        my ($self, $code) = @_;
        $code->();
    }
}

Foo->bar { say "Hi there world" };
Run Code Online (Sandbox Code Playgroud)

该模块作为概念验证而发布。到目前为止我还没有遇到任何问题,但 YMMV 。

  • 对于其他阅读者,MkV 正在挖掘 Switch.pm 对源过滤器的使用,这些过滤器尝试将整个源文件作为字符串进行解析和修改。解析 Perl 时不可避免的错误可能会导致整个代码出现奇怪的副作用。Devel::Declare 完全是另一回事。DD 挂钩 Perl 解析器以查找它想要修改的点。事实上,最近 Perl 中添加了额外的钩子供 DD 使用。虽然不完美,但它非常稳定,并且没有源过滤器所带来的任何错误。苹果和橙子。 (3认同)