我正在处理一些非Moose遗留代码,我想用Moose类对其进行扩展。这是遗留代码的简化:Moose - 修改对象散列中的默认属性位置
package My::Legacy;
sub create {
my ($class, $args) = @_;
my $fields = { _fields => {}};
foreach my $key (keys %$args) {
$fields->{_fields}->{$key} = $args->{$key}
}
bless $fields, $class;
}
1;
的我::遗产类处理所有的CRUD操作,缓存和其他的东西。所有操作都是根据内部_field散列中包含的值执行的,因此,例如,如果要更新值,它必须位于_field散列中。 My :: Legacy类为此提供setter/getter。
的我::遗产是需要由其提供的“糖”几类子类:我::遗产::对象A,我::遗产::对象B等
我需要再添加一个,我想用Moose扩展它。问题是,每次我都会设置一个属性的时候,我将不得不继续其价值同步在内部_fields散,因此,例如,如果我有...
package My::Legacy::MyMooseObj;
use Moose;
use MooseX::NonMoose;
use namespace::autoclean;
has _fields => (
isa => HashRef,
is => 'rw',
default => sub { {} },
);
has attr_a => (
isa => 'Int',
is => 'ro',
);
has attr_b => (
isa => 'Str',
is => 'ro',
);
__PACKAGE__->meta->make_immutable;
...我这样做:
my $MyMooseObj = My::Legacy::MyMooseObj->new();
$MyMooseObj->attr_a(15);
...我想attr_a的在_fields被设置为好,所以如果我dump出来的话就会像:
bless({
'_fields' => {
'attr_a' => 15,
},
'attr_a' => 15,
}, 'My::Legacy::MyMooseObj');
的方式我拿出实现这一目标是为了增加一个触发器,每个属性写它的价值在_fields哈希每次设置:
has attr_b => (
isa => 'Str',
is => 'ro',
trigger => sub { # Write in the _fields attribute attr_b value! },
);
这是一个有点恼人,因为每一次我添加了一个新的属性,我必须确保它有触发器设置:/
你能想到更好的方法吗?有没有办法告诉Moose在默认情况下读取/写入不在对象哈希的“根目录”中的属性(所以在我的情况下,从_fields)读取/写入属性?
的问题是,我不得不“特征”,“custom_get”,“custom_set”,“custom_has”添加到所有属性我想要“同步”,所以也许我最初的做法可以节省我一些打字的时间,并且我仍然可以保留__PACKAGE __-> meta-> make_immutable? – barbasa
你没有想到* meta *够了!我们再添加一个例子... – tobyink
哇!超级整洁!非常感谢...我明确地开始思考更多_meta_ :) – barbasa