File Coverage

blib/lib/App/Betting/Toolkit/GameState.pm
Criterion Covered Total %
statement 18 80 22.5
branch 0 32 0.0
condition 0 3 0.0
subroutine 6 19 31.5
pod 10 11 90.9
total 34 145 23.4


line stmt bran cond sub pod time code
1             package App::Betting::Toolkit::GameState;
2              
3 1     1   74021 use 5.006;
  1         5  
  1         39  
4              
5 1     1   6 use strict;
  1         3  
  1         39  
6 1     1   5 use warnings;
  1         7  
  1         31  
7              
8 1     1   6474 use Data::Dumper;
  1         14299  
  1         75  
9 1     1   1195 use Try::Tiny;
  1         2275  
  1         65  
10 1     1   1345 use Storable qw(dclone);
  1         5274  
  1         1149  
11              
12             =head1 NAME
13              
14             =over 1
15              
16             App::Betting::Toolkit::GameState - A GameState object for use with App::Betting::Toolkit
17              
18             =back
19              
20             =head1 VERSION
21              
22             =over 1
23              
24             Version 0.062
25              
26             =back
27              
28             =cut
29              
30             our $VERSION = '0.062';
31              
32              
33             =head1 SYNOPSIS
34              
35             =over 1
36              
37             use App::Betting::Toolkit::GameState;
38              
39             my $match = App::Betting::Toolkit::GameState->new();
40              
41             $match->name("Arsenal V Aston Villa");
42              
43             =back
44              
45             =head1 SUBROUTINES/METHODS
46              
47             =head2 new
48              
49             =over 1
50              
51             Create a new App::Betting::Toolkit::GameState object.
52              
53             Default object:
54              
55             =back
56              
57             my $match = App::Betting::Toolkit::GameState->new();
58              
59             =over 1
60              
61             Object with required fields:
62              
63             =back
64              
65             my $match = App::Betting::Toolkit::GameState->new( {
66             required => qw(name)
67             } );
68              
69             =over 1
70              
71             Object with auto validation (note validation would always return true here as there are no required fields):
72              
73             =back
74              
75             my $match = App::Betting::Toolkit::GameState->new( {
76             options => { autovalidate => 1 }
77             } );
78              
79             =over 1
80              
81             Object with restricted flags, auto validation and required fields:
82              
83             =back
84              
85             my $match = App::Betting::Toolkit::GameState->new( {
86             options => { autovalidate => 1 },
87             required => [ qw(name time state) ],
88             restrict => {
89             state => [ qw(suspended active finished) ],
90             }
91             });
92              
93             =over 1
94              
95             New match objects ALWAYS start invalid.
96              
97             =back
98              
99             =cut
100              
101             sub new {
102 0     0 1   my $class = shift;
103              
104 0           my $args = shift;
105              
106 0           my $required = [];
107 0           my $options = {};
108 0           my $restrict = {};
109              
110 0 0         $options = $args->{options} if ( $args->{options} );
111 0 0         $restrict = $args->{restrict} if ( $args->{restrict} );
112 0 0         $required = $args->{required} if ( $args->{required} );
113              
114 0           my $self = {
115             special => {
116             version => $VERSION,
117             localtime => time,
118             valid => 0,
119             },
120             options => $options,
121             required => $required,
122             restrict => $restrict,
123             var => {},
124             };
125              
126 0           bless $self, $class;
127 0           return $self;
128             }
129              
130             =head2 load
131              
132             =over 1
133              
134             Load a App::Betting::Toolkit::GameState object from a scalar.
135              
136             =back
137              
138             my $unblessedObject = someSouce();
139              
140             my $match = App::Betting::Toolkit::GameState->load($unblessedObject);
141              
142             =cut
143              
144             sub load {
145 0     0 1   my $class = shift;
146 0           my $self = shift;
147              
148 0           $self = dclone($self);
149              
150 0           bless $self, $class;
151              
152 0           return $self;
153             }
154              
155             =head2 loadable
156              
157             =over 1
158              
159             Check if a passed object will load without error.
160              
161             On error: return 0
162              
163             On success: return 1
164              
165             if (App::Betting::Toolkit::GameState->loadable($unblessedObject)) {
166             $match = App::Betting::Toolkit::GameState->load($unblessedObject);
167             }
168              
169             =back
170              
171             =cut
172              
173             sub loadable {
174 0     0 1   my $class = shift;
175 0           my $self = shift;
176              
177 0     0     try { bless $self, $class }
178 0     0     catch { return 0 }
179              
180 0           return 1;
181             }
182              
183             =head2 pureCopy
184              
185             =over 1
186              
187             Loop through the match object and return an unblessed scalar version that can be sent elsewhere and loaded with the load function.
188              
189             On error: Returns undef
190              
191             On success: Returns a unblessed GameState object.
192              
193             =back
194              
195             =cut
196              
197             sub pureCopy {
198 0     0 1   my $self = shift;
199 0           my $copy;
200              
201 0           foreach my $key (keys %{ $self }) { $copy->{$key} = $self->{$key}; }
  0            
  0            
202              
203 0           return $copy;
204             }
205              
206             =head2 dump
207              
208             =over 1
209              
210             Return the match as a plain scalar that has been outputted through Data::Dumper
211              
212             On error: Something is very wrong 8)
213              
214             On success: Returns a Data Dumped scalar of the GameState object.
215              
216             =back
217              
218             =cut
219              
220             sub dump {
221 0     0 1   return Dumper(shift);
222             }
223              
224             =head2 validate
225              
226             =over 2
227              
228             Validate the required fields against the current fields in the object, this
229             is done automatically if autovalidate => 1 is set.
230              
231             NOTE: This function cannot fail, it will simply just return 0 (invalid)
232              
233             On success: Returns 0 or 1 (Invalid or Valid)
234              
235             =back
236              
237             =cut
238              
239             sub validate {
240 0     0 1   my $self = shift;
241              
242 0           foreach my $key ( @{ $self->{required} } ) {
  0            
243 0 0         return 0 if (!$self->view($key));
244              
245             # Ok is there any restraints on this field
246 0           my $value = $self->view($key);
247              
248 0 0         if ($self->{restrict}->{$key}) {
249 0 0         return 0 if (!isin($value,$self->{restrict}->{$key}));
250             }
251              
252             # Ok so this one is valid..
253             }
254              
255 0           $self->{special}->{valid} = 1;
256              
257 0           return 1;
258             }
259              
260             =head2 isValid
261              
262             =over 1
263              
264             Return the current validation state.
265              
266             On error: Returns undef;
267              
268             On success: Returns 0 or 1 (Invalid or Valid)
269              
270             =back
271              
272             =cut
273              
274             sub isValid {
275 0     0 1   my $self = shift;
276              
277 0 0         return undef if (!defined $self->{special}->{valid});
278 0 0         return undef if ($self->{special}->{valid} !~ m#^0|1$#);
279              
280 0           return $self->{special}->{valid};
281             }
282              
283             =head2 set
284              
285             =over 1
286              
287             Set a variable in the match object. If called without a second parameter
288             the current value of the flag will be returned.
289              
290             On error: Returns undef;
291              
292             On success: Returns new value
293              
294             $match->set('team1name','Sheffield Wednesday');
295              
296             print $match->set('team1name'),"\n";
297              
298             =back
299              
300             =cut
301              
302             sub set {
303 0     0 1   my $self = shift;
304 0           my $varName = shift;
305 0           my $varValue = shift;
306              
307 0 0         return if (!$varName);
308              
309 0 0         $self->{var}->{$varName} = $varValue if (defined $varValue);
310              
311 0 0         $self->validate() if ($self->{options}->{autovalidate});
312              
313 0 0         return $self->{var}->{$varName} if (defined $self->{var}->{$varName});
314             }
315              
316             =head2 updateTime
317              
318             =over 1
319              
320             Update the gamestate objects creation time flag, this is handy for if you are storing a copy of a gamestate object somewhere and you need the time to be accurate.
321              
322             =back
323              
324             $match->updateTime;
325              
326             =cut
327              
328             sub updateTime {
329 0     0 1   my $self = shift;
330              
331 0           $self->{special}->{localtime} = time;
332 0           return $self->{special}->{localtime};
333             }
334              
335             =head2 view
336              
337             =over 1
338              
339             View a variable stored in the match object (does the same as set without its second parameter but does not trigger a validate call even with autovalidate set)
340              
341             On error: Returns undef;
342              
343             On success: Returns value
344              
345             print $match->view('name');
346              
347             =back
348              
349             =cut
350              
351             sub view {
352 0     0 1   my $self = shift;
353 0           my $varName = shift;
354              
355 0 0         return undef if (!$varName);
356              
357 0 0         return $self->{var}->{$varName} if (defined $self->{var}->{$varName});
358              
359             }
360              
361              
362             =head1 AUTHOR
363              
364             =over 1
365              
366             Paul G Webster, C<< >>
367              
368             =back
369              
370             =head1 BUGS
371              
372             =over 1
373              
374             Please report any bugs or feature requests to C, or through
375             the web interface at L. I will be notified, and then you'll
376             automatically be notified of progress on your bug as I make changes.
377              
378             =back
379              
380              
381             =head1 SUPPORT
382              
383             You can find documentation for this module with the perldoc command.
384              
385             perldoc App::Betting::Toolkit::GameState
386              
387              
388             You can also look for information at:
389              
390             =over 4
391              
392             =item * RT: CPAN's request tracker (report bugs here)
393              
394             L
395              
396             =item * AnnoCPAN: Annotated CPAN documentation
397              
398             L
399              
400             =item * CPAN Ratings
401              
402             L
403              
404             =item * Search CPAN
405              
406             L
407              
408             =back
409              
410              
411             =head1 ACKNOWLEDGEMENTS
412              
413              
414             =head1 LICENSE AND COPYRIGHT
415              
416             Copyright 2013 Paul G Webster.
417              
418             This program is distributed under the (Revised) BSD License:
419             L
420              
421             Redistribution and use in source and binary forms, with or without
422             modification, are permitted provided that the following conditions
423             are met:
424              
425             * Redistributions of source code must retain the above copyright
426             notice, this list of conditions and the following disclaimer.
427              
428             * Redistributions in binary form must reproduce the above copyright
429             notice, this list of conditions and the following disclaimer in the
430             documentation and/or other materials provided with the distribution.
431              
432             * Neither the name of Paul G Webster's Organization
433             nor the names of its contributors may be used to endorse or promote
434             products derived from this software without specific prior written
435             permission.
436              
437             THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
438             "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
439             LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
440             A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
441             OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
442             SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
443             LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
444             DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
445             THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
446             (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
447             OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
448              
449              
450             =cut
451              
452             sub isin {
453 0     0 0   my $test = shift;
454 0           my $array = shift;
455              
456 0           foreach my $key ( @{ $array } ) {
  0            
457 0 0 0       next if ( (!$key) || (!$test) );
458 0 0         return 1 if ($key eq $test);
459             }
460              
461 0           return 0;
462             }
463              
464             1; # End of App::Betting::Toolkit::GameState