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

How can I export a subroutine from a Moose package?

如何从 Moose 包中导出正常的非 OO 子例程?在常规包装中,我会使用 Exporter@ISA@EXPORT

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

这是一个示例 Moose class,它也导出一个函数。

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 旨在作为可导出函数,但它也可以作为方法调用!在这种情况下,这是一个功能而不是错误,但通常会带来不便。

一个更好的主意可能是创建两个单独的包:一个用于您的 class,一个用于您的可导出函数。

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 class 和 Exporter 现在完全分开,您不能再调用 $w->is_widget — 它完全是一个函数,不再是一个方法。