File Coverage

blib/lib/Tie/Scalar/Timeout.pm
Criterion Covered Total %
statement 38 46 82.6
branch 10 14 71.4
condition 5 5 100.0
subroutine 10 10 100.0
pod n/a
total 63 75 84.0


line stmt bran cond sub pod time code
1 1     1   29339 use 5.008;
  1         3  
  1         31  
2 1     1   4 use strict;
  1         2  
  1         27  
3 1     1   4 use warnings;
  1         1  
  1         49  
4              
5             package Tie::Scalar::Timeout;
6             BEGIN {
7 1     1   15 $Tie::Scalar::Timeout::VERSION = '2.101420';
8             }
9             # ABSTRACT: Scalar variables that time out
10 1     1   700 use parent 'Tie::Scalar';
  1         254  
  1         4  
11 1     1   4383 use Time::Local;
  1         1689  
  1         579  
12              
13             sub TIESCALAR {
14 4     4   496 my $class = shift;
15 4         28 my $self = {
16             VALUE => undef,
17             EXPIRES => '+1d',
18             POLICY => undef,
19             NUM_USES => -1,
20             @_,
21             };
22 4         15 $self->{EXPIRY_TIME} = _expire_calc($self->{EXPIRES});
23 4         12 $self->{NUM_USES_ORIG} = $self->{NUM_USES};
24 4         17 return bless $self, $class;
25             }
26              
27             sub FETCH {
28 16     16   3003202 my $self = shift;
29              
30             # if num_uses isn't set or set to a negative value, it won't
31             # influence the expiration process
32 16 100 100     84 if ( ($self->{NUM_USES} == 0)
33             || (time >= $self->{EXPIRY_TIME})) {
34              
35             # policy can be a coderef or a plain value
36 7 100       25 return &{ $self->{POLICY} } if ref($self->{POLICY}) eq 'CODE';
  1         5  
37 6         32 return $self->{POLICY};
38             }
39 9 100       26 $self->{NUM_USES}-- if $self->{NUM_USES} > 0;
40 9         28 return $self->{VALUE};
41             }
42              
43             sub STORE {
44 2     2   11 my $self = shift;
45 2         10 $self->{VALUE} = shift;
46              
47             # reset expiration time and number of uses
48 2         6 $self->{EXPIRY_TIME} = _expire_calc($self->{EXPIRES});
49 2         8 $self->{NUM_USES} = $self->{NUM_USES_ORIG};
50             }
51              
52             # This routine was nicked and adapted from CGI.pm. It should probably go
53             # into a separate module. This internal routine creates an expires time
54             # exactly some number of hours from the current time. It incorporates
55             # modifications from Mark Fisher.
56             sub _expire_calc {
57 6     6   8 my $time = shift;
58 6         36 my %mult = (
59             's' => 1,
60             'm' => 60,
61             'h' => 60 * 60,
62             'd' => 60 * 60 * 24,
63             'M' => 60 * 60 * 24 * 30,
64             'y' => 60 * 60 * 24 * 365
65             );
66              
67             # format for time can be in any of the forms...
68             # "now" -- expire immediately
69             # "+180s" -- in 180 seconds
70             # "+2m" -- in 2 minutes
71             # "+12h" -- in 12 hours
72             # "+1d" -- in 1 day
73             # "+3M" -- in 3 months
74             # "+2y" -- in 2 years
75             # "-3m" -- 3 minutes ago(!)
76             # If you don't supply one of these forms, we assume you are
77             # specifying the date yourself
78 6         9 my $offset;
79              
80             # if (!$time || (lc($time) eq 'now')) {
81 6 50       53 if (lc($time) eq 'now') {
    50          
    50          
    50          
82 0         0 $offset = 0;
83             } elsif ($time =~ /^(\d\d?)-(\w{3})-(\d{4}) (\d\d?):(\d\d?):(\d\d?)/) {
84 0         0 require Time::Local; # don't use unless necessary
85 0         0 my ($mday, $monthname, $year, $hours, $min, $sec) =
86             ($1, $2, $3, $4, $5, $6);
87 0         0 my $month = {
88             jan => 0,
89             feb => 1,
90             mar => 2,
91             apr => 3,
92             may => 4,
93             jun => 5,
94             jul => 6,
95             aug => 7,
96             sep => 8,
97             oct => 9,
98             nov => 10,
99             dec => 11,
100             }->{ lc $monthname };
101 0         0 $year -= 1900;
102 0         0 return Time::Local::timelocal_nocheck($sec, $min, $hours, $mday, $month,
103             $year);
104             } elsif ($time =~ /^\d+/) {
105 0         0 return $time;
106             } elsif ($time =~ /^([+-]?(?:\d+|\d*\.\d*))([mhdMy]?)/) {
107 6   100     35 $offset = ($mult{$2} || 1) * $1;
108             } else {
109 0         0 return $time;
110             }
111 6         31 return time + $offset;
112             }
113             1;
114              
115              
116             __END__