我不是一個沒有客觀化的深層物體的狂熱者,幸運的是,穆斯有內在的強制,這樣你就可以將一個深度物體變得像魔術一樣客觀化。
我有點過分了,但我決定繼續前進,只是記錄下自己的練習,儘管我認爲我可以「羅列」一些項目並獲得更好的結果,或者強制Alpha進行強制轉換無論如何,鍵入從必需字段構建結果類。
我不完全喜歡我編碼的方式,但我不想花很多時間在上面,但它適用於上面的對象。你必須做大量的工作,使之去一個更復雜的對象,你會想分手的代碼放到單獨的類:
Alpha.pm:
package Alpha;
use Moose;
use Moose::Util::TypeConstraints;
subtype 'AlphaCodes',
as 'Alpha::Codes';
subtype 'AlphaData',
as 'Alpha::Data';
coerce 'AlphaCodes',
from 'ArrayRef[HashRef]',
via { Alpha::Codes->new(data => $_) };
coerce 'AlphaData',
from 'HashRef',
via { Alpha::Data->new($_) };
has 'code' => (
is => 'ro',
isa => 'AlphaCodes',
required => 1,
coerce => 1);
has 'data' => (
is => 'ro',
isa => 'AlphaData',
required => 1,
coerce => 1);
package Alpha::Codes;
use Moose;
use Moose::Util::TypeConstraints;
extends 'Alpha::KeyedList';
subtype 'ArrayRefOfCodes',
as 'ArrayRef[Alpha::Code]';
coerce 'ArrayRefOfCodes',
from 'ArrayRef[HashRef]',
via { [ map { Alpha::Code->new($_) } @$_ ] };
has 'data' => (
is => 'ro',
isa => 'ArrayRefOfCodes',
required => 1,
coerce => 1);
package Alpha::KeyedList;
use Moose;
use Moose::Util::TypeConstraints;
sub unique_list {
my $self = shift;
my %seen =();
my @retval =();
foreach my $item (@{$self->data}) {
unless ($seen{$item->key}) {
push(@retval,$item);
$seen{$item->key} = 1;
}
}
return @retval;
}
package Alpha::Data;
use Moose;
use Moose::Util::TypeConstraints;
subtype 'AlphaDataDomestics',
as 'Alpha::Data::Domestics';
coerce 'AlphaDataDomestics',
from 'ArrayRef[HashRef]',
via { Alpha::Data::Domestics->new(data => $_) };
has 'domestic' => (
is => 'ro',
isa => 'AlphaDataDomestics',
required => 1,
coerce => 1);
package Alpha::Data::Domestics;
use Moose;
use Moose::Util::TypeConstraints;
extends 'Alpha::KeyedList';
subtype 'ArrayRefOfDomestics',
as 'ArrayRef[Alpha::Data::Domestic]';
coerce 'ArrayRefOfDomestics',
from 'ArrayRef[HashRef]',
via { [ map { Alpha::Data::Domestic->new($_) } @$_ ] };
has 'data' => (
is => 'ro',
isa => 'ArrayRefOfDomestics',
required => 1,
coerce => 1);
package Alpha::Data::Domestic;
use Moose;
extends 'Alpha::Keyed';
has 'a' => (is => 'ro' , isa => 'Str' , required => 1);
has 'b' => (is => 'ro' , isa => 'Str' , required => 1);
sub build_key {
my $self= shift;
return $self->a . '__' . $self->b;
}
package Alpha::Code;
use Moose;
extends 'Alpha::Keyed';
has 'x' => (is => 'ro' , isa => 'Str' , required => 1);
has 'y' => (is => 'ro' , isa => 'Str' , required => 1);
sub build_key {
my $self= shift;
return $self->x . '__' . $self->y;
}
package Alpha::Keyed;
use Moose;
has 'key' => (is => 'ro'
, isa => 'Str'
, builder => 'build_key'
, lazy => 1);
package main;
my $VAR1 = {
'alpha' => {
'code' => [
{
'x' => 1,
'y' => 2
},
{
'x' => 1,
'y' => 2
}
],
'data' => {
'domestic' => [
{
'a' => 0,
'b' => 5
},
{
'a' => 0,
'b' => 5
},
{
'a' => 1,
'b' => 2
},
]
}
}
};
my $alpha = Alpha->new($VAR1->{alpha});
use Data::Dumper;
warn Dumper([ $alpha->code->unique_list ]);
warn Dumper([ $alpha->data->domestic->unique_list ]);
1;
現在對於運行:
$VAR1 = [
bless({
'y' => 2,
'x' => 1,
'key' => '1__2'
}, 'Alpha::Code')
];
$VAR1 = [
bless({
'a' => 0,
'b' => 5,
'key' => '0__5'
}, 'Alpha::Data::Domestic'),
bless({
'a' => 1,
'b' => 2,
'key' => '1__2'
}, 'Alpha::Data::Domestic')
];
對於alpha.code的條目,你知道這些條目總是有 'X' 和 'Y' 的元素,或者說下alpha.data。國內,他們會一直有'一'和'B'? – Horus
@Horus - 結構對於特定數組的每個元素都是相同的... –
基於此,我生成了一個OO響應,您可能想要查看它。你也可以在其上進行Data :: Compare比較。我更喜歡OO版本,因爲我認爲複雜深度的對象不應該表示爲非模式化的hashrefs&arrayrefs。 – Horus