gpt4 book ai didi

perl - 从 ArrayRef[HashRef] 强制 ArrayRef[MyClass]

转载 作者:行者123 更新时间:2023-12-03 00:29:36 27 4
gpt4 key购买 nike

试图回答How to instantiate Moose classes from a big hash ,我想我又遇到了一个我不完全理解 Moose 类型强制的地方。由于某种原因,以下代码发出警告:

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($_) };

但它死得很惨。

最佳答案

嗯,它并没有完全成功,当您尝试使用 coerce => 1 更新这些字段时,您应该能感觉到。那是why :

You cannot pass coerce => 1 unless the attribute's type constraint has a coercion

Previously, this was accepted, and it sort of worked, except that if you attempted to set the attribute after the object was created, you would get a runtime error. Now you will get an error when you attempt to define the attribute.

不过,我想我找到了解决这个问题的方法,首先引入子类型,然后更改包的顺序:

package Company::Person;
use Moose;
use Moose::Util::TypeConstraints;

subtype 'ArrayRefCompanyPersons',
as 'ArrayRef[Company::Person]';

coerce 'ArrayRefCompanyPersons',
from 'ArrayRef[HashRef]',
via { [ map { Company::Person->new($_) } @$_ ] };

has 'id' => (is => 'ro', isa => 'Num');
has 'name' => (is => 'ro', isa => 'Str');
has 'age' => (is => 'ro', isa => 'Num');

package Company::Department;
use Moose;

has 'id' => (is => 'ro', isa => 'Num');
has 'name' => (is => 'ro', isa => 'Str');
has 'employees' => (is => 'ro', isa => 'ArrayRefCompanyPersons', coerce => 1);

package Company;
use Moose;
use Moose::Util::TypeConstraints;

subtype 'ArrayRefCompanyDepartments',
as 'ArrayRef[Company::Department]';

coerce 'ArrayRefCompanyDepartments',
from 'ArrayRef[HashRef]',
via { [ map { Company::Department->new($_) } @$_ ] };

has 'id' => (is => 'ro', isa => 'Num');
has 'name' => (is => 'ro', isa => 'Str');
has 'departments' => (is => 'ro', isa => 'ArrayRefCompanyDepartments', coerce => 1);

其余代码与您的版本中的相同。这可以在没有任何警告的情况下工作,并且more-o-less的行为就像(我再次认为)应该的那样。

关于perl - 从 ArrayRef[HashRef] 强制 ArrayRef[MyClass],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12485673/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com