2016-11-12 7 views
1

Я хочу создать полную иерархию объектов из hashref БЕЗ использования BUILDARGS. Есть ли возможный и простой способ сделать это?Автоматически создавать объект атрибута в perl Moose без использования BUILDARGS

#!/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 для каждого класса.

ответ

3

Вы можете использовать принуждение типа.

  1. Определить тип и принуждение где-то (лоси Best Practices рекомендуется поместить все определения типа в одном модуле):

    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, 
    ); 
    

И это должно быть.