我有一个类,其属性设置如下:
has _data => (
is => 'ro',
lazy => 1,
builder => '_load',
);
sub _load {
my $self = shift;
return retrieve $self->_file;
}
但是我现在想要在返回数据之前调用已经在类上定义的方法。
在老派Perl OO,我会做这样的事情:
sub _load {
# Assuming laziness is implemented somewhere else.
my $self = shift;
$self->{_data} = retrieve $self->_file;
$self->refresh; # which does something with $self->{_data}
return $self->{_data};
}
但是我无法想象在穆斯这样做的“干净”方式。
我考虑过以下情况,但认为它们非常难看,并且必须有更好的方法来做到这一点。
_data
读写,我可能会将数据写入访问者,调用该方法然后从Moose的访问者返回值以写回访问者。_raw_data
,将数据存储在那里,修改refresh()
以使用该属性,其他一切都使用_data()
。 $self->{_data}
。我尝试了after '_load' => \&refresh;
,但这只是创造了一个无限循环。
答案 0 :(得分:1)
这可以很好地利用触发器:
has _data => (
is => 'ro',
lazy => 1,
builder => '_load',
trigger => sub { shift->refresh },
);
除了触发器对默认值/构建值不起作用 - 仅对显式传递给构造函数的值或传递给writer / accessor方法。悲伤的脸。 : - (
一种解决方案是重写您的refresh
方法,这样它就可以接受一个参数(如果没有给出参数,可能会回退到$self->_data
上运行,而不是在$self->_data
上运行
sub _load {
my $self = shift;
my $tmp = retrieve $self->_file;
$self->refresh($tmp);
return $tmp;
}
sub refresh {
my $self = shift;
my $data = scalar(@_) ? $_[0] : $self->_data;
# do something with $data
}