10

你知道 Moose 是如何在导入过程中自动开启strict的吗?warnings我想通过打开autodieuse feature ':5.10'在我的 Moose 类中扩展这种行为。

我已经追踪到 Moose 在哪里执行此操作,在 中,它为调用和调用类的 MooseMoose::Exporter组装了一个自定义子。importstrict->importwarnings->import

但是,我想不出一种以 Moose 方式扩展此导入方法的方法。

我该如何处理?

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

4

4 回答 4

5

我的方法倒着解决了这个问题。

为什么不使用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,评论是积极的。

于 2009-11-05T15:53:13.773 回答
2

由于模块可以通过多种方式将其函数导出到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 使事情变得更复杂一些,因为它依赖于从 caller() 中找到用户的包并使用 goto,但您可以通过更多测试找到更好的方法。您实施的越多,这个库可能就越复杂,但它可能具有足够高的价值,让您拥有可以在您或您公司的所有代码中使用的一次性解决方案。

于 2009-11-05T16:36:04.603 回答
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
于 2009-11-09T20:54:15.120 回答
1

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

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

于 2009-11-05T14:00:20.673 回答