问题
You know how Moose automatically turns on strict
and warnings
during import? I want to extend that behavior by turning on autodie
and use feature ':5.10'
in my Moose classes.
I've tracked down where Moose does this, in Moose::Exporter
, which assembles a custom import
sub for Moose that calls strict->import
and warnings->import
for the calling class.
However, I can't figure out a way to extend this import method in a Moose-ish way.
How should I handle this?
http://www.friedo.com/bullwinkle.gif
回答1:
Since there are many ways a module might export its functions into the use
-ing namespace, you may need to do some code digging in order to implement each desired library. What you're asking for isn't anything specific to Moose, so you can write your or your company's own best practices module which will set up a group of standards for you to work with, e.g.
use OurCompany::BestPractices::V1;
with
package OurCompany::BestPractices::V1;
use strict;
use warnings;
use feature (':5.10');
require Fatal;
require Moose;
# Required for straight implementation of autodie code
our @ISA;
push @ISA, qw(
Fatal
);
sub import {
my $caller = caller;
strict->import;
warnings->import;
feature->import( ':5.10' );
Moose->import ({into => $caller});
#autodie implementation copied from autodie source
splice(@_,1,0,Fatal::LEXICAL_TAG);
goto &Fatal::import;
}
1;
Autodie makes things a little more complicated since it relies on finding the use-er's package from caller() and uses the goto, but you may be able to find a better way with more testing. The more you implement, the more complicated this library might be, but it might be of high enough value for you to have the one-off solution that you can use within all you or your company's code.
回答2:
My approach solves the problem backwards.
Why not use ToolSet to create a group of use
statements that includes Moose
, along with your additional pragmas?
The code should look something like:
# MagicMoose.pm
package MagicMoose;
use base 'ToolSet';
ToolSet->use_pragma( qw/feature :5.10/ ); # perl 5.10
ToolSet->use_pragma( qw/autodie/ );
# define exports from other modules
ToolSet->export(
'Moose' => undef, # get the defaults
);
1; # modules must return true
I haven't tested this. Frankly, I just found ToolSet
a few days ago, and haven't had a chance to try it out yet. FWIW, the reviews are positive.
回答3:
Moose::Exporter
will allow you to define a custom import
method for a sugar class you're using. MooseX::POE
used a version of this for years, but does so in what I consider a "hackish" fashion. Looking at the documentation for Moose::Exporter
the following should be roughly what you're asking for
package Modern::Moose;
use Moose ();
use Moose::Exporter;
my ($import) = Moose::Exporter->build_import_methods(
also => 'Moose',
install => [qw(unimport init_meta)],
);
sub import { # borrowing from mortiz's answer for feature/mro
feature->import( ':5.10' );
mro::set_mro( scalar caller(), 'c3' );
goto &$import;
}
This can then be used like so
package MyApp;
use Modern::Moose;
has greeting => (is => 'ro', default => 'Hello');
sub run { say $_[0]->greeting } # 5.10 is enabled
回答4:
You have to define a sub called import in your package, and import all the other stuff there.
An example from Modern::Perl (another policy module you might look at):
use 5.010_000;
use strict;
use warnings;
use mro ();
use feature ();
sub import {
warnings->import();
strict->import();
feature->import( ':5.10' );
mro::set_mro( scalar caller(), 'c3' );
}
Update: Sorry, didn't read the question carefully enough.
A good way to extend an existing import method is to write your own in a new package, and call Moose's import method from there. You can do that by subclassing, maybe you can even use Moose yourself for that ;-)
来源:https://stackoverflow.com/questions/1678263/how-can-i-extend-mooses-automatic-pragma-exports