在试图回答How to instantiate Moose classes from a big hash时,我想我已经到了另一个我不完全理解穆斯式强制的地方 . 出于某种原因,以下代码发出警告:
You cannot coerce an attribute (departments) unless its type (ArrayRef[Company::Department]) has a coercion at ./test.pl line 12.
You cannot coerce an attribute (employees) unless its type (ArrayRef[Company::Person]) has a coercion at ./test.pl line 23.
但后来成功了 .
#!/usr/bin/env perl
use warnings;
use strict;
package Company;
use Moose;
use Moose::Util::TypeConstraints;
has 'id' => (is => 'ro', isa => 'Num');
has 'name' => (is => 'ro', isa => 'Str');
has 'departments' => (is => 'ro', isa => 'ArrayRef[Company::Department]', coerce => 1);
coerce 'ArrayRef[Company::Department]',
from 'ArrayRef[HashRef]',
via { [ map { Company::Department->new($_) } @$_ ] };
package Company::Department;
use Moose;
has 'id' => (is => 'ro', isa => 'Num');
has 'name' => (is => 'ro', isa => 'Str');
has 'employees' => (is => 'ro', isa => 'ArrayRef[Company::Person]', coerce => 1);
package Company::Person;
use Moose;
use Moose::Util::TypeConstraints;
has 'id' => (is => 'ro', isa => 'Num');
has 'name' => (is => 'ro', isa => 'Str');
has 'age' => (is => 'ro', isa => 'Num');
coerce 'ArrayRef[Company::Person]',
from 'ArrayRef[HashRef]',
via { [ map { Company::Person->new($_) } @$_ ] };
package main;
my %hash = (
company => {
id => 1,
name => 'CorpInc',
departments => [
{
id => 1,
name => 'Sales',
employees => [
{
id => 1,
name => 'John Smith',
age => '30',
},
],
},
{
id => 2,
name => 'IT',
employees => [
{
id => 2,
name => 'Lucy Jones',
age => '28',
},
{
id => 3,
name => 'Miguel Cerveza',
age => '25',
},
],
},
],
}
);
my $company = Company->new($hash{company});
use Data::Dumper;
print Dumper $company;
应该怎么做?附:我试着干脆做
coerce 'Company::Department',
from 'HashRef',
via { Company::Department->new($_) };
但它死得很可怕 .
2 回答
好吧,它没有't succeed completely, and you should feel it when you'尝试用
coerce => 1
更新这些字段 . 那是why:尽管如此,我认为我找到了修复它的方法,首先引入子类型,然后更改包的顺序,第二:
其余代码与您的版本相同 . 这可以在没有任何警告的情况下工作,并且更多的行为(再次,我认为)它应该是 .
来自Moose::Manual::Type docs:
所以要添加到
raina77ow
子类型和包顺序答案(1)我建议创建一个Company::Types
模块:然后将
use Company::Types
放在所有Company::
课程中 .