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

发布于 2024-12-10 18:42:56 字数 1550 浏览 0 评论 0原文

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

甜是你 2024-12-17 18:42:56

您已定义 _sql_lib 属性两次,一次表示 isa Str,一次表示它处理方法(而 Str 则不处理),但是这不是你说的问题。

主要问题是您没有使用 lazy => 定义 _sql_lib 。 1..其构建器(或默认值)依赖于对象的其他属性的任何属性都必须是惰性属性,因为 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 引发错误的原因是调用它会为您的类生成不同的构造函数,而该构造函数恰好以不同的顺序初始化属性。

You've defined the _sql_lib attribute twice, once saying isa Str and once saying it handles methods (which a Str doesn't), but that's not the problem you're talking about.

The main problem is that you didn't define _sql_lib with lazy => 1. Any attribute whose builder (or default) depends on other attributes of the object must be lazy, because Moose doesn't guarantee the order in which attributes are assigned values during object construction.

# 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',
    },
);

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文