package Attribute::Cached; our $VERSION = 0.01; =head1 NAME Attribute::Cached - easily cache subroutines results using a :Cached attribute =head1 SYNOPSIS sub getCache { return $global_cache } sub foo :Cached(60) { ... } sub bar :Cached(time=>30, key=>\&keygen) { ... } # or supply a specific cache sub baz :Cached(time=>20, cache=>$cache) { ... } =head1 DESCRIPTION In many applications, including web apps, caching data is used to help scale the sites, trading a slight lack of immediacy in results with a lower load on DB and other resources. Usually we'll do something like this sub my_query { my ($self, %pars) = @_; # get a cache my $cache = $self->get_cache; # generate a key: for example with %pars (foo=>1), we might use # the key "my_query:foo=1"; my $key = $self->get_key( %pars ); my $result; # check if we've already cached this call, and return if so if ($result = $cache->get($key)) { warn "Cache hit for $key"; return $result; } # The next lines are what this subroutine is /actually/ doing $result = $self->expensive_operation; # ... additional processing as required # set the result in the cache for future accesses $cache->set($key, $result, 20); # hard code a cache time here return $result; } The caching logic is repeated boilerplate and, worse, really has nothing to do with what we're trying to achieve here. With L we'd write this as: sub getCache { my $self = shift; return $self->get_cache(@_) } sub my_query :Cached(time=>20, key=>\&get_key) { my $result = $self->expensive_operation; # ... additional processing as required return $result; } =head1 ATTRIBUTE VALUES The C<:Cached> attribute takes the following parameters =over 4 =item C