有什么办法可以在Moose对象中使用Moose :: Exporter吗?

Eth*_*her 3 perl export moose

我正在寻找一种方法来从父Moose类中设置一些辅助方法,而不是一个独立的实用程序类.如果可能的话,将Moose糖添加到模块是一种更透明的方式,因为它不需要明确要求任何辅助模块(因为一切都是通过extends声明来的).

根据文档中提供示例,这大致与我的目的相同:

package Parent;

use Moose;

Moose::Exporter->setup_import_methods(
    with_meta => [ 'has_rw' ],
    as_is     => [ 'thing' ],
    also      => 'Moose',
);

sub has_rw {
    my ( $meta, $name, %options ) = @_;
    $meta->add_attribute(
        $name,
        is => 'rw',
        %options,
    );
}

# then later ...
package Child;

use Moose;
extends 'Parent';

has 'name';
has_rw 'size';
thing;
Run Code Online (Sandbox Code Playgroud)

但是这不起作用:

perl -I. -MChild -wle'$obj = Child->new(size => 1); print $obj->size'
Run Code Online (Sandbox Code Playgroud)
String found where operator expected at Child.pm line 10, near "has_rw 'size'"
        (Do you need to predeclare has_rw?)
syntax error at Child.pm line 10, near "has_rw 'size'"
Bareword "thing" not allowed while "strict subs" in use at Child.pm line 12.
Compilation failed in require.
BEGIN failed--compilation aborted.

PS.我也尝试将导出魔法转移到一个角色(with Role;而不是extends Parent;),但会出现相同的错误.

per*_*rin 7

这是不受支持的,并且有充分的理由.类或角色与糖方法不同,在某种程度上,不同的东西应该是不同的.如果您的问题是必须"使用"Moose + A Custom Sugar软件包,那么您可以通过简单地让您的自定义糖包导出Moose来解决这个问题,从您的示例中窃取:

package MySugar;
use strict;
use Moose::Exporter;

Moose::Exporter->setup_import_methods(
    with_meta => [ 'has_rw' ],
    as_is     => [ 'thing' ],
    also      => 'Moose',
);

sub has_rw {
    my ( $meta, $name, %options ) = @_;
    $meta->add_attribute(
        $name,
        is => 'rw',
        %options,
    );
}
Run Code Online (Sandbox Code Playgroud)

然后你简单地说:

package MyApp;
use MySugar; # imports everything from Moose + has_rw and thing    
extends(Parent);

has_rw 'name';
has 'size';
thing;
Run Code Online (Sandbox Code Playgroud)

这是如何MooseX::POE工作,以及其他几个包.我会反对extends像你在这里建议的那样引入糖,因为一个类不是一堆糖函数,两者真的不应该混淆.

更新:要同时引入两个最干净的方法是将Parent重写为应用于Moose :: Object的角色.

package Parent::Methods;
use 5.10.0;
use Moose::Role;

sub something_special { say 'sparkles' }
Run Code Online (Sandbox Code Playgroud)

然后我们简单地将调用更改为MySugar中的Moose :: Exporter

Moose::Exporter->setup_import_methods(
    apply_base_class_roles => 'Parent::Methods',
    with_meta              => ['has_rw'],
    as_is                  => ['thing'],
    also                   => 'Moose',
);
Run Code Online (Sandbox Code Playgroud)

现在你可以简单地说

package MyApp;
use MySugar; 

has_rw 'name';
has 'size';
thing;

package main;
MyApp->new->something_special; # prints sparkles
Run Code Online (Sandbox Code Playgroud)

我相信你最不想要的细节.