Pergunta

I'm writing a client for a REST server using Moose and trying to map the calls into objects. Since many of the calls are simple and will use a boilerplate function to pre-fetch it, I'm trying to use export a function that creates the actual before functions within each class.

package R::A;

use Moose;

use R::Util qw(make_befores);

has 'var' => (is => 'rw', isa => 'Str');

make_befores('/servercall/' => ['var']);

1;

package R::Util;

use Moose; use Moose::Exporter;

sub make_befores {
    while (my ($c, $vs) = each(@_)){
        before $vs => sub {
            # make call and set object values
        };
    }
}

Moose::Exporter->setup_import_methods(
    as_is     => [ 'make_befores', ],
);

1;

That's probably incomplete and definitely untested but I think it relays the point. When calling make_befores, it calls it in context of R::Util and breaks since it doesn't call it as R::A with all its variables and such. If make_befores is simply copy-and-pasted into R::A, it works. This will be used in multiple classes, though, so I want it to be an import-able function.

Or am I going about this all wrong?

UPDATED:

Fuji Goro's solution worked great, but was hard to figure out for a Moose newbie like myself, so here's what it ended up looking like:

sub make_befores {
    my $meta = shift;
    while (my ($c, $vs) = each(@_)){
        my $sub = sub { ... };
        Moose::Util::add_method_modifier($meta, before => [$vs => $sub]);
    }
}
Foi útil?

Solução

before is just a syntactic sugar to the MOP. See Moose.pm. Use MOP directly, or you can use Moose::Util::add_method_modifier() and with_meta for this case.

use Moose::Util;
use Moose::Exporter;

sub make_before {
    my($meta, @methods) = @_;
    Moose::Util::add_method_modifier($meta, before => \@methods);
}

Moose::Exporter->setup_import_methods(
    with_meta => [qw(make_before)],
);
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top