In our classes we have a pattern where we create an attribute to
represent a calculated value (calculated by a builder method).
For various reasons we want to cache the calculated value in an
attribute and then clear the attribute when an underlying attribute
changes.

I asked this question a while ago on Stackoverflow and I'm now trying
to implement one of the suggestions, a role to do all of the dirty
work for me.

http://stackoverflow.com/questions/1775572/moose-expiring-cached-results-of-calculations-when-attribute-values-change/1780681#1780681

So in a nut shell I want this behaviour:

package main;

use strict;
use warnings;
my $f = XX::Foobar->new( bar => '10' );

print $f->calc(), "\n"; # calc attribute now populated with value of do_calc

$f->clear_bar(); # bar and calc should be cleared
$f->calc(), "\n"; # calc attribute now populated with value of do_calc

$f->bar(2);        # calc attribute
$f->calc(), "\n"; # Calc slot now populated with value of do_calc

package XX::Foobar;
use lib './lib';
use Moose;

use MooseX::DependsOnA; # My temp name for my Role/MooseXtension

has bar => ( isa     => 'Num', clearer => 'clear_bar' );

has calc => (
    depends_on => ['bar'], # provided by Role if bar is ever changed
call clear_value on this attribute
    is         => 'rw',
    isa        => 'Num',
    lazy       => 1,
    builder    => 'do_calc'
);

sub do_calc {
   my ($self) = @_;
   return  3.14 * $self->bar;
}


I have a MooseX:: package that almost does this but has the following issues:
* doesn't clear dependent attributes on 'clear_$attr' only on 'set'
* heavily cribbed from other MooseX:: modules
* I have to apply a trait to every attribute in the class to get it to
participate

Here is the code for MooseX::DependsOnA: http://gist.github.com/396125

All of this code is cribbed together from various sources and I'm sure
that it's all crap.
What am I missing?

Thanks,
Clayton

Reply via email to