如何扩展Moose的自动pragma导出?

时间:2009-11-05 04:01:45

标签: perl moose mop

您知道Moose在导入过程中如何自动启用strictwarnings吗?我希望通过启用我的Moose课程中的autodieuse feature ':5.10'来扩展该行为。

我跟踪了Moose在Moose::Exporter中执行此操作的位置,它为Moose组装了一个自定义import子组件,为调用类调用strict->importwarnings->import

但是,我无法找到一种以Moose-ish方式扩展此导入方法的方法。

我该如何处理?

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

4 个答案:

答案 0 :(得分:5)

我的方法可以向后解决问题。

为什么不使用ToolSet创建一组包含use的{​​{1}}语句以及其他编译指示?

代码应该类似于:

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 ,但还没有机会尝试一下。 FWIW,评论是积极的。

答案 1 :(得分:2)

由于模块可以通过多种方式将其函数导出到use - 命名空间中,因此您可能需要进行一些代码挖掘以实现每个所需的库。您所要求的并不是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使事情变得有点复杂,因为它依赖于从caller()中找到use-er的包并使用goto,但是你可以通过更多的测试找到更好的方法。您实施的越多,这个库可能就越复杂,但它可能具有足够高的价值,您可以在您或您公司的代码中使用一次性解决方案。

答案 2 :(得分:2)

Moose::Exporter将允许您为正在使用的糖类定义自定义import方法。 MooseX::POE多年来一直使用这个版本,但我认为这是一种“hackish”时尚。查看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's 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

答案 3 :(得分:1)

你必须在你的包中定义一个名为import的子,并导入那里的所有其他东西。

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的import方法。你可以通过子类化来做到这一点,也许你甚至可以自己使用Moose; - )