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