属性初期化子を使用してコンストラクターに渡されたときに格納されている値をキャッチして変更できます。(ただし、属性がコンストラクターで設定されている場合にのみ実行され、それ以外のときは実行されません。)初期化子のドキュメントは、Class :: MOP::Attributeにあります。
これは、コンストラクターを介して属性が設定されている場合のみをキャッチするため、属性が設定されている他のケースをキャッチする必要があります。これは、あなたが言ったようにメソッド修飾子を使って行うことができますが、自動生成されたアクセサーをラップして、2つを1つのメソッドに組み合わせることができます。
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);
};