如何扩展 Moose 的自动编译指示导出?

发布于 2024-08-10 17:21:42 字数 506 浏览 11 评论 0原文

您知道 Moose 如何在导入过程中自动打开 strictwarnings 吗?我想通过在我的 Moose 类中打开 autodieuse feature ':5.10' 来扩展该行为。

我已经在 Moose::Exporter 中找到了 Moose 执行此操作的位置,它为 Moose 组装了一个自定义 import 子函数,调用 strict->import code> 和调用类的 warnings->import

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

我应该如何处理这个问题?

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

You know how Moose automatically turns on strict and warnings during import? I want to extend that behavior by turning on autodie and use feature ':5.10' in my Moose classes.

I've tracked down where Moose does this, in Moose::Exporter, which assembles a custom import sub for Moose that calls strict->import and warnings->import for the calling class.

However, I can't figure out a way to extend this import method in a Moose-ish way.

How should I handle this?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

很快妥协 2024-08-17 17:21:42

我的方法是向后解决问题。

为什么不使用 ToolSet 创建一组包含 use 语句code>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,评论是积极的。

My approach solves the problem backwards.

Why not use ToolSet to create a group of use statements that includes Moose, along with your additional pragmas?

The code should look something like:

 # 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

I haven't tested this. Frankly, I just found ToolSet a few days ago, and haven't had a chance to try it out yet. FWIW, the reviews are positive.

小兔几 2024-08-17 17:21:42

由于模块可以通过多种方式将其函数导出到 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,但您也许可以通过更多测试找到更好的方法。您实现的越多,这个库可能就越复杂,但它可能具有足够高的价值,让您拥有可以在您或您公司的所有代码中使用的一次性解决方案。

Since there are many ways a module might export its functions into the use-ing namespace, you may need to do some code digging in order to implement each desired library. What you're asking for isn't anything specific to Moose, so you can write your or your company's own best practices module which will set up a group of standards for you to work with, e.g.

use OurCompany::BestPractices::V1;

with

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 makes things a little more complicated since it relies on finding the use-er's package from caller() and uses the goto, but you may be able to find a better way with more testing. The more you implement, the more complicated this library might be, but it might be of high enough value for you to have the one-off solution that you can use within all you or your company's code.

以歌曲疗慰 2024-08-17 17:21:42

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

Moose::Exporter will allow you to define a custom import method for a sugar class you're using. MooseX::POE used a version of this for years, but does so in what I consider a "hackish" fashion. Looking at the documentation for Moose::Exporter the following should be roughly what you're asking for

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

This can then be used like so

package MyApp;
use Modern::Moose;

has greeting => (is => 'ro', default => 'Hello');
sub run { say $_[0]->greeting } # 5.10 is enabled
初与友歌 2024-08-17 17:21:42

您必须在包中定义一个名为 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 的导入方法。你可以通过子类化来做到这一点,也许你甚至可以自己使用 Moose ;-)

You have to define a sub called import in your package, and import all the other stuff there.

An example from Modern::Perl (another policy module you might look at):

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: Sorry, didn't read the question carefully enough.

A good way to extend an existing import method is to write your own in a new package, and call Moose's import method from there. You can do that by subclassing, maybe you can even use Moose yourself for that ;-)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文