我正在寻找一种从父Moose类中设置一些辅助方法的方法,而不是一个独立的实用程序类。如果可能的话,将Moose糖添加到模块是一种更透明的方式,因为它不需要明确要求任何辅助模块(因为所有内容都来自extends
声明)。
基于example provided in the documentation,这大致是我想要的:
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;
然而,这不起作用:
perl -I. -MChild -wle'$obj = Child->new(size => 1); print $obj->size'
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;
),但会出现相同的错误。
答案 0 :(得分: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,
);
}
然后你只需说:
package MyApp;
use MySugar; # imports everything from Moose + has_rw and thing
extends(Parent);
has_rw 'name';
has 'size';
thing;
这是MooseX::POE
的工作原理,以及其他几个包。我会反对让extends
像你在这里建议的那样引入糖,因为一个类不是一堆糖函数,而且两者真的不应该混淆。
更新:要同时引入两个最干净的方法是将Parent重写为应用于Moose :: Object的角色。
package Parent::Methods;
use 5.10.0;
use Moose::Role;
sub something_special { say 'sparkles' }
然后我们只是将对MySugar中的Moose :: Exporter的调用更改为
Moose::Exporter->setup_import_methods(
apply_base_class_roles => 'Parent::Methods',
with_meta => ['has_rw'],
as_is => ['thing'],
also => 'Moose',
);
现在你可以简单地说
package MyApp;
use MySugar;
has_rw 'name';
has 'size';
thing;
package main;
MyApp->new->something_special; # prints sparkles
我相信你想要的最终细节。