Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing a block to a Moose method

Tags:

perl

moose

Is it somehow possible to pass blocks to Moose methods? In standard Perl, I can define a function with prototypes like this

sub fn (&) {
    my $code =\&{shift @_};
    $code->();
}

and then pass a block to the function without explicit sub references, i.e. fn { say "Hi there, world" }.

I think this is only possible if the subroutine is the first parameter, and as this is always $self with a Moose method, it doesn't seem possible there, forcing me to do it the slightly more explicit way:

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

Wrapper->wrapper(sub { say "Hi there, world" });

Now this would be a pretty convenient way to wrap some blocks, i.e. to provide some additional text or conditionally execute code or wrap an eval around some code where the error handling stays the same (e.g. eval some code and log errors, record user etc.).

If I'm not missing something, is there some semi-convenient workaround or alternative method to achieve something like this without too much line noise?

like image 496
mhd Avatar asked Oct 06 '22 09:10

mhd


1 Answers

Have a look at the PerlX::MethodCallWithBlock CPAN module which contorts the Perl syntax (via the Devel::Declare module) to allow you to put a block after a method call.

For e.g.:

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

{
    package Foo;
    use Moose;

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

Foo->bar { say "Hi there world" };

This module was released as a proof of concept. So far I've had no issues with it but YMMV.

like image 118
draegtun Avatar answered Oct 10 '22 02:10

draegtun