File Coverage

blib/lib/Mojolicious/Plugin/Memorize.pm
Criterion Covered Total %
statement 35 35 100.0
branch 18 20 90.0
condition 3 5 60.0
subroutine 7 7 100.0
pod 3 3 100.0
total 66 70 94.2


line stmt bran cond sub pod time code
1             package Mojolicious::Plugin::Memorize;
2              
3 2     2   1394 use Mojo::Base 'Mojolicious::Plugin';
  2         3  
  2         13  
4              
5             our $VERSION = '0.02';
6             $VERSION = eval $VERSION;
7              
8 2     2   443 use Mojo::Util;
  2         4  
  2         1017  
9              
10             has cache => sub { +{} };
11              
12             sub register {
13 2     2 1 61 my ($plugin, $app) = @_;
14              
15             $app->helper(
16             memorize => sub {
17 18     18   4314321 shift;
18 18 100       129 return $plugin unless @_;
19 15         37 unshift @_, $plugin;
20 15         210 goto $plugin->can('memorize'); # for the sake of the auto-naming
21             }
22 2         16 );
23              
24             }
25              
26             sub expire {
27 2     2 1 4 my ($self, $name) = @_;
28 2         36 delete $self->cache->{$name};
29             }
30              
31             sub memorize {
32 15     15 1 34 my $self = shift;
33              
34 15         311 my $mem = $self->cache;
35              
36 15 50       155 return '' unless ref(my $cb = pop) eq 'CODE';
37 15 100 50     98 my ($name, $args)
38             = ref $_[0] eq 'HASH' ? (undef, shift) : (shift, shift || {});
39              
40             # Default name
41 15 50 66     155 $name ||= join '', map { $_ || '' } (caller(1))[0 .. 3];
  32         106  
42              
43             # Return memorized result or invalidate cached
44 15 100       66 return $mem->{$name}{content} if $self->_check_cached($name);
45              
46             # Determine new expiration time
47 8         14 my $expires = 0;
48 8 100       35 if ( my $delta = $args->{duration} ) {
    100          
49 2         9 $expires = $delta + Mojo::Util::steady_time;
50             } elsif ( my $time = $args->{expires} ) {
51 2         3 my $delta = $time - time;
52 2         8 $expires = $delta + Mojo::Util::steady_time;
53             }
54              
55             # Memorize new result
56 8         51 $mem->{$name}{expires} = $expires;
57 8         18 return $mem->{$name}{content} = $cb->();
58             }
59              
60             sub _check_cached {
61 15     15   23 my ($self, $name) = @_;
62 15         250 my $mem = $self->cache;
63              
64 15 100       116 return unless exists $mem->{$name}; # avoid autoviv
65              
66 9 100       51 return 1 unless my $expires = $mem->{$name}{expires};
67              
68 6 100       15 return 1 unless Mojo::Util::steady_time >= $expires;
69              
70 2         34 delete $mem->{$name};
71              
72 2         7 return 0;
73             }
74              
75             1;
76              
77             =head1 NAME
78              
79             Mojolicious::Plugin::Memorize - Memorize part of your Mojolicious template
80              
81             =head1 SYNOPSIS
82              
83             use Mojolicious::Lite;
84             plugin 'Memorize';
85              
86             any '/' => 'index';
87              
88             any '/reset' => sub {
89             my $self = shift;
90             $self->memorize->expire('access');
91             $self->redirect_to('/');
92             };
93              
94             app->start;
95              
96             __DATA__
97              
98             @@ index.html.ep
99              
100             %= memorize access => { expires => 0 } => begin
101             This page was memorized on
102             %= scalar localtime
103             % end
104              
105             =head1 DESCRIPTION
106              
107             This plugin provides the functionality to easily memorize a portion of a
108             template, to prevent re-evaluation. This may be useful when a portion of your
109             response is expensive to generate but changes rarely (a menu for example).
110              
111             The C helper derives from the helper that was removed from
112             C at version 4.0, with two major changes. The underlying plugin
113             object is returned when no arguments are passed and the system is resiliant
114             against time jumps.
115              
116             =head1 HELPERS
117              
118             =over
119              
120             =item C
121              
122             When called with arguments, this helper wraps the functionality of the
123             C method below. See its documentation for usage.
124              
125             When called without arguments, the plugin object is returned, allowing the use
126             of other plugin methods or access to the plugin's cache.
127              
128             =back
129              
130             =head1 ATTRIBUTES
131              
132             =over
133              
134             =item C
135              
136             A hash reference containing the memorized template content and other data.
137              
138             =back
139              
140             =head1 METHODS
141              
142             =over
143              
144             =item C
145              
146             This method allows for manually expiring a memorized template block. This may
147             useful if the template is set to never expire or when the underlying content is
148             known to have changed.
149              
150             This is an example of the utility of having access to the underlying hash. In
151             the original implementation of the core helper, this access was not available.
152              
153             =item C
154              
155             This method behaves as the old helper did. It takes as many as three arguments,
156             the final of which must be a template block (see L) to
157             be memorized. The first argument may be a string which is the name (key) of the
158             memorized template (used for later access); if this is not provided one will be
159             generated. A hashref may also be passed in which is used for additional
160             arguments.
161              
162             As of this writing, the only available argument are C and C.
163             The C key specifies the number of seconds that the template should be
164             memorized, while the C key specifies a time (epoch seconds) after which
165             the template should be re-evaluated. C is the recommened usage,
166             C is provided for historical reasons, and is implemented using
167             C. If both are provided, C is used.
168              
169             Note that either key may be set to zero to prevent timed expiration.
170              
171             =item C
172              
173             This method is called upon loading the plugin and probably is not useful for
174             other purposes.
175              
176             =back
177              
178             =head1 SEE ALSO
179              
180             =over
181              
182             =item *
183              
184             L
185              
186             =item *
187              
188             L
189              
190             =item *
191              
192             L
193              
194             =back
195              
196             =head1 SOURCE REPOSITORY
197              
198             L
199              
200              
201             =head1 AUTHORS
202              
203             =over
204              
205             =item Joel Berger, Ejoel.a.berger@gmail.comE
206              
207             =item Sebastian Riedel
208              
209             =back
210              
211             =head1 COPYRIGHT AND LICENSE
212              
213             Copyright (C) 2013 by Joel Berger and Sebastian Riedel
214              
215             This library is free software; you can redistribute it and/or modify
216             it under the same terms as Perl itself.
217