当使用属性初始化器传递给构造函数时,您可以捕获和改变存储的值。(但是,它仅在构造函数中设置属性时运行,而不是在任何其他时间运行。)初始化器的文档可以在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);
};