我正在處理一些非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