如何在Moose对象中设置一堆属性构建器?
问题描述:
我有以下五个驼鹿属性:如何在Moose对象中设置一堆属性构建器?
has ['summary_file', 'html_file', 'url1', 'url2', 'txt_file'] => (
is => 'rw',
isa => 'Str',
required => 0,
lazy => 1,
default => sub { confess "Attribute not set"; },
);
我想:
- 让他们每个人用自己的制造商(如设置
'summary_file'
使用_build_summary_file
等) - 制作默认
confess
子状态(未初始化)属性被调用(例如"Attribute 'summary_file' not set"
)。
我可以通过写五个单独的has
来完成上述操作,但也许有更紧凑的方法?
答
你可以做一些类似以下(新工作后,如你的“不工作”的评论):
package My::Class;
use Moose;
use namespace::autoclean;
for my $attr (qw(x y)) {
has $attr => (
is => 'rw',
isa => 'Str',
required => 0,
lazy => 1,
builder => "_build_$attr",
);
}
sub _build_x { rand }
sub _build_y { rand }
__PACKAGE__->meta->make_immutable;
package main;
use strict; use warnings;
my $o = My::Class->new;
print $o->$_, "\n" for qw(x y);
注意,你不能同时指定一个default
和builder
。
@Oesor指出在评论什么我忘了:
has ['summary_file', 'html_file', 'url1', 'url2', 'txt_file'] => (
is => 'rw',
isa => 'Str',
required => 0,
lazy_build => 1,
);
答
如果你正在寻找一个属性抛出异常的访问时,它不具有设定的值,看看MooseX::LazyRequire。
如果您正在寻找一个构建器在调用时发出警告,请在构建器方法中包含该语句...或者包装访问器/读取器方法来执行此操作。 (例如,“before 'attribute_name' => sub { ...complain... };
”)
如果您正在寻找指定生成器方法使用相同的命名约定lazy_build的属性的方式呢,看MooseX::AttributeShortcuts(支持‘builder => 1
’为“builder => "_build_${attribute_name}"
”)。
或者只声明他们lazy_build,默认为_build_ $ accessor。 – Oesor 2010-11-18 20:36:34
@Oesor:在这种情况下,你也会得到一个公开的谓词和清晰的,这往往是不可取的。根据文档'lazy_build'的 – Ether 2010-11-18 21:42:10
也将'required'设置为true。这是什么意思? – 2010-11-19 08:31:24