File Coverage

blib/lib/MooseX/AutoDestruct/V2/Trait/Attribute.pm
Criterion Covered Total %
statement 22 39 56.4
branch 3 6 50.0
condition 0 2 0.0
subroutine 5 11 45.4
pod 0 5 0.0
total 30 63 47.6


line stmt bran cond sub pod time code
1             #
2             # This file is part of MooseX-AutoDestruct
3             #
4             # This software is Copyright (c) 2011 by Chris Weyl.
5             #
6             # This is free software, licensed under:
7             #
8             # The GNU Lesser General Public License, Version 2.1, February 1999
9             #
10             package MooseX::AutoDestruct::V2::Trait::Attribute;
11             {
12             $MooseX::AutoDestruct::V2::Trait::Attribute::VERSION = '0.009';
13             }
14              
15             # ABSTRACT: Clear your attributes after a certain time
16              
17 2     2   4140 use Moose::Role;
  2         9665  
  2         14  
18 2     2   12152 use namespace::autoclean;
  2         4  
  2         23  
19              
20             # debugging
21             #use Smart::Comments '###', '####';
22              
23             has ttl => (is => 'ro', isa => 'Int', required => 1, predicate => 'has_ttl');
24              
25             has value_slot => (is => 'ro', isa => 'Str', lazy_build => 1, init_arg => undef);
26             has destruct_at_slot => (is => 'ro', isa => 'Str', lazy_build => 1, init_arg => undef);
27              
28 0     0   0 sub _build_value_slot { shift->name }
29 2     2   97 sub _build_destruct_at_slot { shift->name . '__DESTRUCT_AT__' }
30              
31             around slots => sub {
32             my ($orig, $self) = (shift, shift);
33              
34             return ($self->$orig(), $self->destruct_at_slot);
35             };
36              
37             sub set_doomsday {
38 0     0 0 0 my ($self, $instance) = @_;
39              
40             # ...
41              
42             # set our destruct_at slot
43 0         0 my $doomsday = $self->ttl + time;
44              
45             ### doomsday set to: $doomsday
46             ### time() is: time()
47 0         0 $self
48             ->associated_class
49             ->get_meta_instance
50             ->set_slot_value($instance, $self->destruct_at_slot, $doomsday)
51             ;
52              
53 0         0 return;
54             }
55              
56             sub has_doomsday {
57 0     0 0 0 my ($self, $instance) = @_;
58              
59 0         0 return $self
60             ->associated_class
61             ->get_meta_instance
62             ->is_slot_initialized($instance, $self->destruct_at_slot)
63             ;
64             }
65              
66             # return true if this value has expired
67             sub doomsday {
68 0     0 0 0 my ($self, $instance) = @_;
69              
70 0         0 my $doomsday = $self
71             ->associated_class
72             ->get_meta_instance
73             ->get_slot_value($instance, $self->destruct_at_slot)
74             ;
75 0   0     0 $doomsday ||= 0;
76              
77             ### $doomsday
78             ### time > $doomsday: time > $doomsday
79 0         0 return time > $doomsday;
80             }
81              
82             sub avert_doomsday {
83 0     0 0 0 my ($self, $instance) = @_;
84              
85             ### in avert_doomsday()...
86 0         0 $self
87             ->associated_class
88             ->get_meta_instance
89             ->deinitialize_slot($instance, $self->destruct_at_slot)
90             ;
91              
92 0         0 return;
93             }
94              
95             after set_initial_value => sub { shift->set_doomsday(shift) };
96             after set_value => sub { shift->set_doomsday(shift) };
97             after clear_value => sub { shift->avert_doomsday(shift) };
98              
99             before get_value => sub { shift->enforce_doomsday(@_) };
100             before has_value => sub { shift->enforce_doomsday(@_) };
101              
102             sub enforce_doomsday {
103 0     0 0 0 my ($self, $instance, $for_trigger) = @_;
104              
105             # if we're not set yet...
106 0 0       0 $self->clear_value($instance) if $self->doomsday($instance);
107 0         0 return;
108             }
109              
110             # FIXME do we need this?
111             after get_value => sub {
112             my ($self, $instance, $for_trigger) = @_;
113              
114             $self->set_doomsday unless $self->has_doomsday($instance);
115             };
116              
117             around _inline_clear_value => sub {
118             my ($orig, $self) = (shift, shift);
119             my ($instance) = @_;
120              
121             my $mi = $self->associated_class->get_meta_instance;
122              
123             return $self->$orig(@_)
124             . $mi->inline_deinitialize_slot($instance, $self->destruct_at_slot)
125             . ';'
126             ;
127             };
128              
129             sub _inline_destruct {
130 4     4   6 my $self = shift;
131 4         7 my ($instance) = @_;
132              
133 4         33 my $slot_exists = $self->_inline_instance_has(@_);
134 4         94 my $destruct_at_slot_value = $self
135             ->associated_class
136             ->get_meta_instance
137             ->inline_get_slot_value($instance, $self->destruct_at_slot)
138             ;
139              
140 4         32 my $clear_attribute;
141 4 100       29 if ($self->has_clearer) {
142              
143             # if we have a clearer method, we should call that -- it may have
144             # been wrapped in the class
145              
146 2         23 my $clearer = $self->clearer;
147 2 50       7 ($clearer) = keys %$clearer if ref $clearer;
148              
149 2         4 $clear_attribute = "${instance}->" . $clearer . '()';
150             }
151             else {
152             # otherwise, just deinit all the slots we use
153 2         29 $clear_attribute = $self->_inline_clear_value(@_);
154             }
155              
156 4         40 return " if ($slot_exists && time() > $destruct_at_slot_value) { $clear_attribute } ";
157             }
158              
159             my $destruct_wrapper = sub {
160             my $self = shift;
161             return ($self->_inline_destruct(@_), super);
162             };
163              
164             override _inline_has_value => $destruct_wrapper;
165             override _inline_get_value => $destruct_wrapper;
166              
167             sub _inline_set_doomsday {
168 5     5   13 my ($self, $instance) = @_;
169 5         27 my $mi = $self->associated_class->get_meta_instance;
170              
171 5         451 my $code = $mi->inline_set_slot_value(
172             $instance,
173             $self->destruct_at_slot,
174             'time() + ' . $self->ttl,
175             );
176              
177 5         93 return "$code;\n";
178             }
179              
180             override _inline_instance_set => sub {
181             my $self = shift;
182             return 'do { ' . $self->_inline_set_doomsday(@_) . ';' . super . ' }';
183             };
184              
185             !!42;
186              
187              
188              
189             =pod
190              
191             =head1 NAME
192              
193             MooseX::AutoDestruct::V2::Trait::Attribute - Clear your attributes after a certain time
194              
195             =head1 VERSION
196              
197             version 0.009
198              
199             =head1 DESCRIPTION
200              
201             Attribute trait of L<MooseX::AutoDestruct> for L<Moose> version
202             2.xx.
203              
204             =begin Pod::Coverage
205              
206              
207              
208              
209             =end Pod::Coverage
210              
211             =head1 SEE ALSO
212              
213             L<MooseX:AutoDestruct>.
214              
215             =head1 AUTHOR
216              
217             Chris Weyl <cweyl@alumni.drew.edu>
218              
219             =head1 COPYRIGHT AND LICENSE
220              
221             This software is Copyright (c) 2011 by Chris Weyl.
222              
223             This is free software, licensed under:
224              
225             The GNU Lesser General Public License, Version 2.1, February 1999
226              
227             =cut
228              
229              
230             __END__
231