根据
Moose::Manual::Attribute
:
如果有许多属性仅因名称不同,则可以
立即声明所有内容:
package Point;
use Moose;
has [ 'x', 'y' ] => ( is => 'ro', isa => 'Int' );
还有,因为
has
只是一个函数调用,您可以在循环中调用它:
for my $name ( qw( x y ) ) {
my $builder = '_build_' . $name;
has $name => ( is => 'ro', isa => 'Int', builder => $builder );
}
还有一个
lazy_build
属性,请参见
Moose::Meta::Attribute
,但文件上说:
“请注意,强烈建议不要使用此功能”
最后一个选项是使用扩展包。
我想这已经存在于CPAN上的某个地方了,但我找不到它,所以下面是我尝试实现
Moose
扩展名:
package MyMooseAttributeExtensions;
use strict;
use warnings;
our %orig_has; # save original 'has' sub routines here
sub import {
my $callpkg = caller 0;
{
no strict 'refs';
no warnings 'redefine';
$orig_has{$callpkg} = *{$callpkg."::has"}{CODE};
*{$callpkg."::has"} = \&private_has;
}
return;
}
sub private_has {
my ($attr, %args) = @_;
my $callpkg = caller 0;
if (exists $args{private} ) {
delete $args{private};
%args = (
%args,
lazy => 1,
init_arg => undef, # prevent from being set by constructor
builder => "_set_$attr"
);
}
$orig_has{$callpkg}->($attr, %args);
}
1;