为什么Moose make_immutable会杀死这个脚本?

时间:2011-10-18 20:50:26

标签: perl immutability moose

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.

1 个答案:

答案 0 :(得分:3)

您已经定义了_sql_lib属性两次,一次说isa Str并且一旦说它处理方法(Str没有),但这不是你的问题谈论。

主要问题是您没有使用_sql_lib定义lazy => 1。其构建器(或default)依赖于对象的其他属性的任何属性必须为lazy,因为Moose不保证在对象构造期间为属性分配值的顺序。

# REMOVE THIS:
#has '_sql_lib' => (#FOLDBEG                                 
#   builder => '_sql_lib_builder',
#    is => 'rw',
#    isa => 'Str',
#);

has '_sql_lib' => (#FOLDBEG                                 
    builder => '_sql_lib_builder',
    is => 'rw',
    lazy => 1,                       # ADD THIS LINE
    handles => {
        get_sql => 'retr',
        get_elements => 'elements',
    },
);

make_immutable揭示错误的原因是调用它会为您的类生成不同的构造函数,这恰好以不同的顺序初始化属性。