你知道 Moose 是如何在导入过程中自动开启strict
的吗?warnings
我想通过打开autodie
并use feature ':5.10'
在我的 Moose 类中扩展这种行为。
我已经追踪到 Moose 在哪里执行此操作,在 中,它为调用和调用类的 MooseMoose::Exporter
组装了一个自定义子。import
strict->import
warnings->import
但是,我想不出一种以 Moose 方式扩展此导入方法的方法。
我该如何处理?
你知道 Moose 是如何在导入过程中自动开启strict
的吗?warnings
我想通过打开autodie
并use feature ':5.10'
在我的 Moose 类中扩展这种行为。
我已经追踪到 Moose 在哪里执行此操作,在 中,它为调用和调用类的 MooseMoose::Exporter
组装了一个自定义子。import
strict->import
warnings->import
但是,我想不出一种以 Moose 方式扩展此导入方法的方法。
我该如何处理?
我的方法倒着解决了这个问题。
为什么不使用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,评论是积极的。
由于模块可以通过多种方式将其函数导出到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,但您可以通过更多测试找到更好的方法。您实施的越多,这个库可能就越复杂,但它可能具有足够高的价值,让您拥有可以在您或您公司的所有代码中使用的一次性解决方案。
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
你必须在你的包中定义一个名为 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 ;-)