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
_dataread-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