"Connecting" 一个带有哈希的 Moo 对象
"Connecting" a Moo object with a hash
在我的真实代码中,我想 "synchronize" 一个带有散列(实际上是绑定散列)的 Moo(如果 Moo 不起作用,则为 Moose)对象,以便读取 属性 Moo 对象的 属性 将从散列中读取相应的值并写入 Moo 对象的 属性 将存储到散列中。
以下为简化代码:
#!/usr/bin/perl
use feature qw(say);
package X;
use Moo;
use Data::Dumper;
my $BusinessClass = 'X';
has 'base' => (is => 'rw', builder => 'base_builder');
sub base_builder {
return {};
}
foreach my $Key (qw(a b c)) {
{
no strict 'refs';
*{"${BusinessClass}::$Key"} = sub {
if (@_ == 2) {
return $_[0]->base->{$Key} = $_[1];
} else {
return $_[0]->base->{$Key};
}
};
has $Key => ( is => 'rw',
lazy => 0,
required => 0,
reader => "${BusinessClass}::_access1_$Key",
writer => "${BusinessClass}::_access2_$Key",
);
}
}
my $obj = X->new(a=>123, b=>456);
print Dumper $obj->base;
$obj->c(789);
print Dumper $obj->base;
问题是传递给 new
函数的属性没有存储在 has $obj->base
中(但它们应该是)。在上面的代码示例中,属性 c
被正确存储,但 a
和 b
没有存储到散列中。这是一个错误。
处理这种情况的好方法是什么?
这可以通过添加来解决:
sub BUILD {
my ($self, $args) = @_;
foreach my $Key (keys %$args) {
$self->base->{$Key} = $args->{$Key};
my $clearer = "_clear_local_$Key";
$self->$clearer();
}
}
完整代码:
#!/usr/bin/perl
use feature qw(say);
package X;
use Moo;
use Data::Dumper;
my $BusinessClass = 'X';
has 'base' => (is => 'rw', builder => 'base_builder');
sub base_builder {
return {};
}
sub BUILD {
my ($self, $args) = @_;
foreach my $Key (keys %$args) {
$self->base->{$Key} = $args->{$Key};
my $clearer = "_clear_local_$Key";
$self->$clearer();
}
}
foreach my $Key (qw(a b c)) {
{
no strict 'refs';
*{"${BusinessClass}::$Key"} = sub {
if (@_ == 2) {
return $_[0]->base->{$Key} = $_[1];
} else {
return $_[0]->base->{$Key};
}
};
has $Key => ( is => 'rw',
lazy => 0,
required => 0,
reader => "${BusinessClass}::_access1_$Key",
writer => "${BusinessClass}::_access2_$Key",
clearer => "_clear_local_$Key",
);
}
}
my $obj = X->new(a=>123, b=>456);
print Dumper $obj->base;
$obj->c(789);
print Dumper $obj->base;
print Dumper {%$obj};
在我的真实代码中,我想 "synchronize" 一个带有散列(实际上是绑定散列)的 Moo(如果 Moo 不起作用,则为 Moose)对象,以便读取 属性 Moo 对象的 属性 将从散列中读取相应的值并写入 Moo 对象的 属性 将存储到散列中。
以下为简化代码:
#!/usr/bin/perl
use feature qw(say);
package X;
use Moo;
use Data::Dumper;
my $BusinessClass = 'X';
has 'base' => (is => 'rw', builder => 'base_builder');
sub base_builder {
return {};
}
foreach my $Key (qw(a b c)) {
{
no strict 'refs';
*{"${BusinessClass}::$Key"} = sub {
if (@_ == 2) {
return $_[0]->base->{$Key} = $_[1];
} else {
return $_[0]->base->{$Key};
}
};
has $Key => ( is => 'rw',
lazy => 0,
required => 0,
reader => "${BusinessClass}::_access1_$Key",
writer => "${BusinessClass}::_access2_$Key",
);
}
}
my $obj = X->new(a=>123, b=>456);
print Dumper $obj->base;
$obj->c(789);
print Dumper $obj->base;
问题是传递给 new
函数的属性没有存储在 has $obj->base
中(但它们应该是)。在上面的代码示例中,属性 c
被正确存储,但 a
和 b
没有存储到散列中。这是一个错误。
处理这种情况的好方法是什么?
这可以通过添加来解决:
sub BUILD {
my ($self, $args) = @_;
foreach my $Key (keys %$args) {
$self->base->{$Key} = $args->{$Key};
my $clearer = "_clear_local_$Key";
$self->$clearer();
}
}
完整代码:
#!/usr/bin/perl
use feature qw(say);
package X;
use Moo;
use Data::Dumper;
my $BusinessClass = 'X';
has 'base' => (is => 'rw', builder => 'base_builder');
sub base_builder {
return {};
}
sub BUILD {
my ($self, $args) = @_;
foreach my $Key (keys %$args) {
$self->base->{$Key} = $args->{$Key};
my $clearer = "_clear_local_$Key";
$self->$clearer();
}
}
foreach my $Key (qw(a b c)) {
{
no strict 'refs';
*{"${BusinessClass}::$Key"} = sub {
if (@_ == 2) {
return $_[0]->base->{$Key} = $_[1];
} else {
return $_[0]->base->{$Key};
}
};
has $Key => ( is => 'rw',
lazy => 0,
required => 0,
reader => "${BusinessClass}::_access1_$Key",
writer => "${BusinessClass}::_access2_$Key",
clearer => "_clear_local_$Key",
);
}
}
my $obj = X->new(a=>123, b=>456);
print Dumper $obj->base;
$obj->c(789);
print Dumper $obj->base;
print Dumper {%$obj};