Mojolicious-Plugin-Memorize
view release on metacpan or search on metacpan
lib/Mojolicious/Plugin/Memorize.pm view on Meta::CPAN
package Mojolicious::Plugin::Memorize;
use Mojo::Base 'Mojolicious::Plugin';
our $VERSION = '0.02';
$VERSION = eval $VERSION;
use Mojo::Util;
has cache => sub { +{} };
sub register {
my ($plugin, $app) = @_;
$app->helper(
memorize => sub {
shift;
return $plugin unless @_;
unshift @_, $plugin;
goto $plugin->can('memorize'); # for the sake of the auto-naming
}
);
}
sub expire {
my ($self, $name) = @_;
delete $self->cache->{$name};
}
sub memorize {
my $self = shift;
my $mem = $self->cache;
return '' unless ref(my $cb = pop) eq 'CODE';
my ($name, $args)
= ref $_[0] eq 'HASH' ? (undef, shift) : (shift, shift || {});
# Default name
$name ||= join '', map { $_ || '' } (caller(1))[0 .. 3];
# Return memorized result or invalidate cached
return $mem->{$name}{content} if $self->_check_cached($name);
# Determine new expiration time
my $expires = 0;
if ( my $delta = $args->{duration} ) {
$expires = $delta + Mojo::Util::steady_time;
} elsif ( my $time = $args->{expires} ) {
my $delta = $time - time;
$expires = $delta + Mojo::Util::steady_time;
}
# Memorize new result
$mem->{$name}{expires} = $expires;
return $mem->{$name}{content} = $cb->();
}
sub _check_cached {
my ($self, $name) = @_;
my $mem = $self->cache;
return unless exists $mem->{$name}; # avoid autoviv
return 1 unless my $expires = $mem->{$name}{expires};
return 1 unless Mojo::Util::steady_time >= $expires;
delete $mem->{$name};
return 0;
}
1;
=head1 NAME
Mojolicious::Plugin::Memorize - Memorize part of your Mojolicious template
=head1 SYNOPSIS
use Mojolicious::Lite;
plugin 'Memorize';
any '/' => 'index';
any '/reset' => sub {
my $self = shift;
$self->memorize->expire('access');
$self->redirect_to('/');
};
app->start;
__DATA__
@@ index.html.ep
%= memorize access => { expires => 0 } => begin
This page was memorized on
%= scalar localtime
% end
( run in 0.542 second using v1.01-cache-2.11-cpan-75ffa21a3d4 )