您可以在傳入構造函數時使用屬性初始值設定程序捕獲並更改存儲的值。 (但是,只有在屬性在構造函數中設置時纔會運行,而不是在任何其他時間運行。)有關初始化程序的文檔可以在Class::MOP::Attribute中找到。
由於這隻會捕獲通過構造函數設置屬性的情況,您仍需要捕獲設置屬性的其他情況。這可以用一個方法修改完成像你說的,但你可以在這兩個合併成一個方法,圍繞自動生成的存取包裹:
has my_attr => (
is => 'rw',
isa => 'DBIx::Class::Row',
initializer => 'my_attr',
);
# my_attr is the autogenerated accessor - we method-modify it to mutate the
# value being set, and catch cases where it is called as an initializer.
# called for reads, writes, and on initialization at construction time
around 'my_attr' => sub {
my $orig = shift;
my $self = shift;
# value is not defined if being called as a reader
# setter and attr are only defined if being called as an initializer
my ($value, $setter, $attr) = @_;
# the reader behaves normally
return $self->$orig if not @_;
# convert the string to the row object
my $row = $self->convert_str_to_row_obj($value);
# if called as an initializer, set the value and we're done
return $setter->($row) if $setter;
# otherwise, call the real writer with the new value
$self->$orig($row);
};
嗯 - 我認爲這將做到這一點,但是當我嘗試了,我得到'屬性(my_attr)不會傳遞類型約束,因爲:對於值爲'Foo'的'DBIx :: Class :: Row',驗證失敗。看起來類型約束在*初始化方法運行之前被檢查* – cubabit 2011-02-28 11:23:02
我可能必須將isa更改爲'Str |目的' – cubabit 2011-02-28 14:56:01