如何从 Moose 包中导出子例程?

发布于 2025-01-15 20:49:56 字数 114 浏览 3 评论 0原文

如何从 Moose 包中导出正常的非 OO 子例程?在常规包中,我会使用 Exporter@ISA@EXPORT 来完成此操作。

How can I export a normal, non-OO subroutine from a Moose package? In a regular package, I'd do it with Exporter, @ISA and @EXPORT.

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

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

发布评论

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

评论(1

伴随着你 2025-01-22 20:49:56

Moose 用于构建类和角色。虽然从技术上讲您也可以导出函数,但这不一定是最好的主意。

下面是一个示例 Moose 类,它还导出一个函数。

MyApp/Widget.pm

use v5.26;
use warnings;

package MyApp::Widget;

use Exporter qw( import );
our @EXPORT_OK = qw( is_widget );

use Moose;
use namespace::autoclean -except => 'import';

has name => ( is => 'ro', isa => 'Str', required => 1 );

sub is_widget {
    my $object = shift;
    blessed( $object ) and $object->isa( __PACKAGE__ );
}

__PACKAGE__->meta->make_immutable;

以下是您可以如何使用它:

use v5.26;
use warnings;
use MyApp::Widget qw( is_widget );

my $w = 'MyApp::Widget'->new( name => 'Foo' );
say is_widget( $w );
say $w->is_widget;

请注意,尽管 is_widget 是一个可导出函数,但它也可以作为方法来调用!在这种情况下,这是一个功能而不是一个错误,但通常这会带来不便。

更好的想法可能是创建两个单独的包:一个用于您的类,另一个用于您的可导出函数。

MyApp/Widget.pm

use v5.26;
use warnings;

package MyApp::Widget;

use Moose;
use namespace::autoclean;

has name => ( is => 'ro', isa => 'Str', required => 1 );

__PACKAGE__->meta->make_immutable;

MyApp/Util.pm

use v5.26;
use warnings;

package MyApp::Util;

use Exporter qw( import );
our @EXPORT_OK = qw( is_widget );

use Scalar::Util qw( blessed );

sub is_widget {
    my $object = shift;
    blessed( $object ) and $object->isa( 'MyApp::Widget' );
}

1;

您可以像这样调用您的包:

use v5.26;
use warnings;
use MyApp::Widget;
use MyApp::Util qw( is_widget );

my $w = 'MyApp::Widget'->new( name => 'Foo' );
say is_widget( $w );

因为 Moose 类和 Exporter 现在完全分离,所以您不能不再调用 $w->is_widget — 它完全是一个函数,不再是一个方法。

Moose is for building classes and roles. While you technically can also export functions, it's not necessarily the best idea.

Here's an example Moose class which also exports a function.

MyApp/Widget.pm

use v5.26;
use warnings;

package MyApp::Widget;

use Exporter qw( import );
our @EXPORT_OK = qw( is_widget );

use Moose;
use namespace::autoclean -except => 'import';

has name => ( is => 'ro', isa => 'Str', required => 1 );

sub is_widget {
    my $object = shift;
    blessed( $object ) and $object->isa( __PACKAGE__ );
}

__PACKAGE__->meta->make_immutable;

Here's how you might use it:

use v5.26;
use warnings;
use MyApp::Widget qw( is_widget );

my $w = 'MyApp::Widget'->new( name => 'Foo' );
say is_widget( $w );
say $w->is_widget;

Note that even though is_widget was intended an exportable function, it can also be called as a method! In this case, that's a feature rather than a bug, but often that will be an inconvenience.

A better idea might be to create two separate packages: one for your class and one for your exportable functions.

MyApp/Widget.pm

use v5.26;
use warnings;

package MyApp::Widget;

use Moose;
use namespace::autoclean;

has name => ( is => 'ro', isa => 'Str', required => 1 );

__PACKAGE__->meta->make_immutable;

MyApp/Util.pm

use v5.26;
use warnings;

package MyApp::Util;

use Exporter qw( import );
our @EXPORT_OK = qw( is_widget );

use Scalar::Util qw( blessed );

sub is_widget {
    my $object = shift;
    blessed( $object ) and $object->isa( 'MyApp::Widget' );
}

1;

And you'd call use your packages like this:

use v5.26;
use warnings;
use MyApp::Widget;
use MyApp::Util qw( is_widget );

my $w = 'MyApp::Widget'->new( name => 'Foo' );
say is_widget( $w );

Because the Moose class and the Exporter are now cleanly separated, you can no longer call $w->is_widget — it's entirely a function and no longer a method.

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