perl - How to call method within builder -
i have class attribute set follows:
has _data => ( => 'ro', lazy => 1, builder => '_load', ); sub _load { $self = shift; return retrieve $self->_file; }
however want call method defined on class before returning data.
in old-school perl oo, i'd doing this:
sub _load { # assuming laziness implemented somewhere else. $self = shift; $self->{_data} = retrieve $self->_file; $self->refresh; # $self->{_data} return $self->{_data}; }
but can't figure out 'clean' way in moose.
i've considered following, think quite ugly, , there must better way of doing this.
- if make
_data
read-write, potentially write data accessor, call method return value accessor moose write accessor. - if turn plain old method i'd have define attribute,
_raw_data
, store data in there, modifyrefresh()
use attribute, , else uses_data()
. - violate encapsulation , access underlying
$self->{_data}
directly.
i tried after '_load' => \&refresh;
, created endless loop.
this nice use of triggers:
has _data => ( => 'ro', lazy => 1, builder => '_load', trigger => sub { shift->refresh }, );
except triggers don't work on default/built values - on values passed constructor explicitly, or passed writer/accessor method. sad face. :-(
one solution rewrite refresh
method instead of operating on $self->_data
, can accept parameter (perhaps falling operating on $self->_data
if no parameter given.
sub _load { $self = shift; $tmp = retrieve $self->_file; $self->refresh($tmp); return $tmp; } sub refresh { $self = shift; $data = scalar(@_) ? $_[0] : $self->_data; # $data }
Comments
Post a Comment