为什么 Moose make_immutable 杀死这个脚本?
package testDB;
use Moose;
use Carp;
use SQL::Library;
has 'lib' => (#FOLDBEG
is => 'rw',
isa => 'Str',
default => 'default',
trigger => \&_sql_lib_builder,
);#FOLDEND
has 'lib_dir' => (#FOLDBEG
is => 'ro',
isa => 'Str',
default => '/SQL',
);#FOLDEND
has '_sql_lib' => (#FOLDBEG
builder => '_sql_lib_builder',
is => 'rw',
isa => 'Str',
);
has '_sql_lib' => (#FOLDBEG
builder => '_sql_lib_builder',
is => 'rw',
handles => {
get_sql => 'retr',
get_elements => 'elements',
},
);
sub _sql_lib_builder {
my ($self, $lib) = shift();
$self->lib() or die("I am unable to get a lib.");
$lib = $self->lib unless $lib;
my $lib_dir = $self->lib_dir;
print $lib_dir."\n";
my $lib_file = $lib_dir . '/' . $lib . '.sql';
unless (-e $lib_file ) {
confess "SQL library $lib does not exist";
}
my $library = new SQL::Library { lib => $lib_file };
$self->_sql_lib($library);
}#FOLDEND
__PACKAGE__->meta->make_immutable;
my $tdb=testDB->new();
使用 perl 5.8.8 和 Moose 2.0205
$ perl testDB.pl
I am unable to get a lib. at testDB.pl line 35.
package testDB;
use Moose;
use Carp;
use SQL::Library;
has 'lib' => (#FOLDBEG
is => 'rw',
isa => 'Str',
default => 'default',
trigger => \&_sql_lib_builder,
);#FOLDEND
has 'lib_dir' => (#FOLDBEG
is => 'ro',
isa => 'Str',
default => '/SQL',
);#FOLDEND
has '_sql_lib' => (#FOLDBEG
builder => '_sql_lib_builder',
is => 'rw',
isa => 'Str',
);
has '_sql_lib' => (#FOLDBEG
builder => '_sql_lib_builder',
is => 'rw',
handles => {
get_sql => 'retr',
get_elements => 'elements',
},
);
sub _sql_lib_builder {
my ($self, $lib) = shift();
$self->lib() or die("I am unable to get a lib.");
$lib = $self->lib unless $lib;
my $lib_dir = $self->lib_dir;
print $lib_dir."\n";
my $lib_file = $lib_dir . '/' . $lib . '.sql';
unless (-e $lib_file ) {
confess "SQL library $lib does not exist";
}
my $library = new SQL::Library { lib => $lib_file };
$self->_sql_lib($library);
}#FOLDEND
__PACKAGE__->meta->make_immutable;
my $tdb=testDB->new();
Using perl 5.8.8 and Moose 2.0205
$ perl testDB.pl
I am unable to get a lib. at testDB.pl line 35.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您已定义
_sql_lib
属性两次,一次表示isa Str
,一次表示它处理方法(而Str
则不处理),但是这不是你说的问题。主要问题是您没有使用
lazy => 定义
.其构建器(或默认值)依赖于对象的其他属性的任何属性都必须是惰性属性,因为 Moose 不保证在对象构造期间为属性赋值的顺序。_sql_lib
。 1.make_immutable 引发错误的原因是调用它会为您的类生成不同的构造函数,而该构造函数恰好以不同的顺序初始化属性。
You've defined the
_sql_lib
attribute twice, once sayingisa Str
and once saying it handles methods (which aStr
doesn't), but that's not the problem you're talking about.The main problem is that you didn't define
_sql_lib
withlazy => 1
. Any attribute whose builder (ordefault
) depends on other attributes of the object must belazy
, because Moose doesn't guarantee the order in which attributes are assigned values during object construction.The reason that
make_immutable
brings out the bug is that calling it generates a different constructor for your class, which happens to initialize the attributes in a different order.