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]);
}
}
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)],
);