在perl Moose中自动创建属性对象,而不使用BUILDARGS

时间:2016-11-12 13:05:06

标签: perl moose

我想使用BUILDARGS从hashref中创建完整的对象层次结构。有没有可行的简单方法呢?

#!/usr/bin/perl
use v5.14;
use strict;
use warnings;
{
    package Obj1;

    use v5.14;
    use strict;
    use warnings;
    use Moose;

    has 'backend' => (
        is          => 'ro',
        isa         => 'Obj2',
        required    => 1,
    );

    no Moose;
    __PACKAGE__->meta->make_immutable;

    1;
}
{
    package Obj2;

    use v5.14;
    use strict;
    use warnings;
    use Moose;

    has 'flag' => (
        is          => 'ro',
        isa         => 'Bool',
        required    => 1,
    );

    no Moose;
    __PACKAGE__->meta->make_immutable;

    1;
}

my $data = {
    backend => {
        flag => 1
    }
};

my $s = Obj1->new($data);
say $s->backend->flag;

到目前为止,我一直在使用BUILDARGS,但我想这可能会有些自动化,对吧?这是一个简单的例子,在我的代码中有更深层次的层次结构,如果我可以停止为每个类编写BUILDARGS,那将是非常好的。

1 个答案:

答案 0 :(得分:3)

您可以使用类型强制。

  1. 在某处定义类型和强制(Moose最佳实践建议将所有类型定义放在一个模块中):

    package My::Types;
    use Moose::Util::TypeConstraints;
    class_type 'Obj2Class', { class => 'Obj2' };
    coerce 'Obj2Class', from 'HashRef', via { Obj2->new($_) };
    
  2. 使用新的类型定义修改backend并使其具有强制性:

    use My::Types;
    has backend => (
        is       => 'ro',
        isa      => 'Obj2Class',
        coerce   => 1,
        required => 1,
    );
    
  3. 那应该是它。