Como posso estender as exportações Pragma automáticas de Moose?
Pergunta
Você sabe como Moose liga automaticamente strict
e warnings
durante a importação? Eu quero estender esse comportamento ligando autodie
e use feature ':5.10'
em minhas aulas de alces.
Eu rastreou onde Moose faz isso, em Moose::Exporter
, que monta uma sub import
personalizado para Moose que as chamadas strict->import
e warnings->import
para a classe chamando.
No entanto, não posso descobrir uma maneira de estender este método de importação de forma Moose-ish.
Como devo lidar com isso?
Solução
Uma vez que existem muitas maneiras um módulo pode exportar suas funções no namespace-ing use
, você pode precisar fazer algumas escavações código, a fim de implementar cada biblioteca desejada. O que você está pedindo não é nada específico para Moose, assim você pode escrever o seu próprio módulo ou da sua empresa as melhores práticas que irá criar um grupo de padrões para você trabalhar com, por exemplo.
use OurCompany::BestPractices::V1;
com
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 torna as coisas um pouco mais complicado, uma vez que se baseia em encontrar pacote de uso-er de quem chama () e usa o Goto, mas você pode ser capaz de encontrar uma maneira melhor, com mais testes. Quanto mais você implementar, o mais complicado esta biblioteca pode ser, mas pode ser de valor alto o suficiente para você ter o one-off solução que você pode usar dentro de tudo o que você ou o código da sua empresa.
Outras dicas
A minha abordagem resolve o problema para trás.
Por que não usar ToolSet para criar um grupo de instruções use
que inclui Moose
, juntamente com o seu pragmas adicionais?
O código deve ser algo como:
# 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
Eu não testei isso. Francamente, eu só encontrei ToolSet
há poucos dias, e não tive a chance de experimentá-lo ainda. FWIW, os comentários são positivos.
Moose::Exporter
lhe permitirá definir um método import
personalizado para uma classe de açúcar que você está usando. MooseX::POE
usado uma versão deste há anos, mas faz isso de que eu considero uma moda "hackish". Olhando para a documentação para Moose::Exporter
o seguinte deve ser mais ou menos o que você está pedindo
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;
}
Este pode então ser usada como assim
package MyApp;
use Modern::Moose;
has greeting => (is => 'ro', default => 'Hello');
sub run { say $_[0]->greeting } # 5.10 is enabled
Você tem que definir uma sub chamado de importação em seu pacote e importar todas as outras coisas lá.
Um exemplo de Modern :: Perl (outro módulo de política que você pode olhar):
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:. Desculpe, não leu a pergunta com cuidado suficiente
Uma boa maneira de estender um método de importação existente é escrever seu próprio em um novo pacote, e chamar o método de importação do Moose de lá. Você pode fazer isso por subclasses, talvez você ainda pode usar Moose-se para que; -)