File Coverage

blib/lib/Hints.pm
Criterion Covered Total %
statement 57 76 75.0
branch 7 22 31.8
condition 2 2 100.0
subroutine 13 16 81.2
pod 12 12 100.0
total 91 128 71.0


line stmt bran cond sub pod time code
1             package Hints;
2              
3 2     2   1382 use strict;
  2         3  
  2         71  
4 2     2   9 use vars qw/$VERSION/;
  2         3  
  2         89  
5 2     2   2140 use IO::Handle;
  2         17336  
  2         138  
6 2     2   1994 use IO::File;
  2         4642  
  2         1707  
7              
8             $VERSION = '0.02';
9              
10             =head1 NAME
11              
12             Hints - Perl extension for hints databases
13              
14             =head1 SYNOPSIS
15              
16             use Hints;
17              
18             my $hints = new Hints;
19              
20             $hints->load_from_file('my.hints');
21              
22             print $hints->random();
23              
24             =head1 DESCRIPTION
25              
26             In many programs you need hints database and methods for accessing this
27             database. Extension Hints is object oriented abstract module, you can
28             use file-base of hints or make descendant with own base.
29              
30             =head1 THE HINTS CLASS
31              
32             =head2 new
33              
34             Constructor create instance of Hints class. Than call C constructor
35             for build implicit database (descendant ussually re-implement these method).
36              
37             my $hints = new Hints;
38              
39             =cut
40              
41             sub new {
42 4     4 1 1615 my $class = shift;
43 4         44 my $obj = bless { base => [], last => 0 }, $class;
44 4         35 $obj->clear();
45 4         53 srand (time() ^ ($$ + ($$ << 15)));
46 4         28 return $obj->init(@_);
47             }
48              
49             =head2 init
50              
51             This method was called from C constructor for building implicit
52             database. Base class define only abstract version. Return value of C
53             method must be instance (typically same as calling instance). You can use
54             this to change class or stop making instance by returning of undefined value.
55              
56             =cut
57              
58             sub init {
59 1     1 1 4 return shift;
60             }
61              
62             =head2 load_from_file (FILE, SEPARATOR)
63              
64             Loading all hints from file specified as first argument. Hints separator is
65             determined by second argument. If separator is undefined than default separator
66             is used (^---$). Separator argument is regular expression.
67              
68             You can also use file handle or reference to array instead of filename.
69              
70             $hints->load_from_file('my.hints','^**SEPARATOR**$');
71             $hints->load_from_file(\*FILE,'^**SEPARATOR**$');
72             $hints->load_from_file(\@lines,'^**SEPARATOR**$');
73              
74             =cut
75              
76             sub load_from_file {
77 4     4 1 164 my $obj = shift;
78 4         8 my $file = shift;
79 4   100     23 my $separator = shift || '^---$';
80 4         7 my $ioref;
81              
82 4 50       17 return unless defined $file;
83 4         8 my @lines = ();
84 4 50       48 if (ref $file eq 'ARRAY') {
    0          
85 4         20 @lines = @$file;
86             } elsif (ref $file) {
87 0         0 eval {
88 0         0 $ioref = *{$file}{IO};
  0         0  
89             };
90 0 0       0 return if $@;
91 0         0 @lines = <$ioref>;
92             } else {
93 0 0       0 return unless $ioref = new IO::File $file;
94 0         0 @lines = <$ioref>;
95             }
96              
97 4         8 my @current = ();
98 4         18 for (@lines) {
99 52         63 chomp;
100 52 100       171 if (/$separator/) {
101 16         27 push @{$obj->{base}},[ @current ];
  16         53  
102 16         34 @current = ();
103             } else {
104 36         59 push @current,$_;
105             }
106             }
107 4 50       18 $ioref->close() unless ref $file;
108 4 100       16 push @{$obj->{base}},\@current if @current;
  3         17  
109             }
110              
111             =head2 clear
112              
113             This method clear hints database.
114              
115             $hints->clear;
116              
117             =cut
118              
119             sub clear {
120 5     5 1 176 my $obj = shift;
121              
122 5         29 $obj->{base} = [];
123             }
124              
125             =head2 format
126              
127             Method is used for formatting hint before returning. Ussually redefined by
128             descendant. In abstract class making one long line from multilines.
129              
130             =cut
131              
132             sub format {
133 3     3 1 4 my $obj = shift;
134 3         8 my $output = join ' ',@_;
135 3         8 $output =~ s/\s+$//;
136 3         31 return $output;
137             }
138              
139             =head2 first
140              
141             Return first hint from database.
142              
143             my $hint = $hints->first;
144              
145             =cut
146              
147             sub first {
148 1     1 1 4 my $obj = shift;
149 1         3 $obj->{iterator} = 0;
150 1         5 return $obj->next;
151             }
152              
153             =head2 next
154              
155             Return next hint from database (used after first).
156             If no hint rest undefined value is returned.
157              
158             my $hint = $hints->first;
159             do {
160             print $hint."\n";
161             } if (defined $hint = $hints->next);
162              
163             =cut
164              
165             sub next {
166 2     2 1 7 my $obj = shift;
167 2         4 $obj->{last} = $obj->{iterator};
168 2         10 return $obj->item($obj->{iterator}++);
169             }
170              
171             =head2 random
172              
173             Return random hint from database.
174              
175             my $hint = $hints->random;
176              
177             =cut
178              
179             sub random {
180 0     0 1 0 my $obj = shift;
181 0         0 my $l;
182 0         0 do {
183 0         0 $l = rand($obj->count());
184 0 0       0 last if $obj->count() == 1;
185             } while ($l == $obj->{last});
186 0         0 return $obj->item($obj->{last} = $l);
187             }
188              
189             =head2 count
190              
191             Return number of hints in database.
192              
193             my $number = $hints->count;
194              
195             =cut
196              
197             sub count {
198 5     5 1 33 my $obj = shift;
199 5         9 return scalar @{$obj->{base}};
  5         19  
200             }
201              
202             =head2 item NUMBER
203              
204             Return NUMBER. item from database.
205              
206             # return last hint
207             my $hint = $hints->item($hints->count - 1);
208              
209             =cut
210              
211             sub item {
212 3     3 1 6 my $obj = shift;
213 3         5 my $number = shift;
214 3         4 $obj->{last} = $number;
215 3         4 return $obj->format(@{$obj->{base}->[$number]});
  3         12  
216             }
217              
218             =head2 forward
219              
220             Return next hint after last wanted hint from database.
221              
222             my $random_hint = $hints->random;
223             my $next_hint = $hints->forward;
224              
225             =cut
226              
227             sub forward {
228 0     0 1   my $obj = shift;
229 0 0         $obj->{last} = 0 if ++$obj->{last} >= $obj->count;
230 0           return $obj->item($obj->{last});
231             }
232              
233             =head2 backward
234              
235             Return previous hint before last wanted hint from database.
236              
237             my $random_hint = $hints->random;
238             my $prev_hint = $hints->backward;
239              
240             =cut
241              
242             sub backward {
243 0     0 1   my $obj = shift;
244 0 0         $obj->{last} = $obj->count() - 1 if --$obj->{last} < 0;
245 0           return $obj->item($obj->{last});
246             }
247              
248             1;
249              
250             __END__