Вы можете перехватить и изменить значение, сохраняемое при передаче в конструктор с инициализатором атрибута .(Однако он запускается только тогда, когда атрибут установлен в конструкторе, а не в любое другое время.) Документацию для инициализаторов можно найти в 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);
};