Как я могу продлить автоматический экспорт прагмы Moose?

Вы знаете, как Moose автоматически включает strict и warnings во время импорта? Я хочу расширить это поведение, включив autodie и use feature ':5.10' в моих классах Moose.

Я отслеживал, где Лось делает это, в Moose::Exporter, который собирает пользовательский import sub для Moose, который вызывает strict->import и warnings->import для вызывающего класса.

Однако я не могу найти способ расширить этот метод импорта в Moose-ish.

Как мне это сделать?

http://www.friedo.com/bullwinkle.gif

Ответ 1

Поскольку существует много способов, которыми модуль может экспортировать свои функции в пространство имен use -ing, вам может потребоваться выполнить кодовое кодовое слово, чтобы реализовать каждую нужную библиотеку. То, о чем вы просите, не является чем-то особенным для Moose, поэтому вы можете написать свой собственный модуль вашей собственной практики или вашей компании, который будет создавать группу стандартов для вас, например,

use OurCompany::BestPractices::V1;

с

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 делает вещи немного более сложными, поскольку он полагается на поиск пакета use-er от caller() и использует goto, но вы можете найти лучший способ с большим количеством тестов. Чем больше вы реализуете, тем сложнее будет эта библиотека, но для вас может быть достаточно высокое значение, чтобы иметь одноразовое решение, которое вы можете использовать во всех своих или ваших корпоративных кодах.

Ответ 2

Мое решение решает проблему назад.

Почему бы не использовать ToolSet, чтобы создать группу операторов use, которая включает Moose, вместе с вашими дополнительными прагмами?

Код должен выглядеть примерно так:

 # 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

Я не тестировал это. Честно говоря, я только что нашел ToolSet несколько дней назад, и у меня еще не было возможности попробовать это. FWIW, отзывы положительные.

Ответ 3

Moose::Exporter позволит вам определить пользовательский метод import для используемого вами класса сахара. MooseX::POE использовал версию этого в течение многих лет, но делает это в том, что я считаю "хакерским" способом. Если посмотреть на документацию для Moose::Exporter, следует примерно следующее:

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 answer for feature/mro
    feature->import( ':5.10' );
    mro::set_mro( scalar caller(), 'c3' );        
    goto &$import;
}

Затем это можно использовать так

package MyApp;
use Modern::Moose;

has greeting => (is => 'ro', default => 'Hello');
sub run { say $_[0]->greeting } # 5.10 is enabled

Ответ 4

Вы должны определить дополнительный импорт в своем пакете и импортировать все остальные вещи там.

Пример из Modern:: Perl (другой политический модуль, на который вы можете посмотреть):

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' );
}

Обновление: Извините, недостаточно внимательно прочитал вопрос.

Хороший способ расширить существующий метод импорта - написать свой собственный в новом пакете и вызвать метод импорта Moose. Вы можете сделать это путем подклассификации, возможно, вы даже можете использовать Moose для этого: -)