File Coverage

blib/lib/Bio/Polloc/Polloc/Root.pm
Criterion Covered Total %
statement 71 145 48.9
branch 24 58 41.3
condition 8 16 50.0
subroutine 14 24 58.3
pod 12 13 92.3
total 129 256 50.3


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             Bio::Polloc - Perl library for Polymorphic Loci Analyses
4              
5             =head1 AUTHOR - Luis M. Rodriguez-R
6              
7             Email lmrodriguezr at gmail dot com
8              
9             =cut
10              
11             package Bio::Polloc::Polloc::Root;
12              
13 12     12   30773 use strict;
  12         24  
  12         380  
14 12     12   6517 use Bio::Polloc::Polloc::Version;
  12         25  
  12         73  
15 12     12   7234 use Bio::Polloc::Polloc::IO;
  12         44  
  12         423  
16 12     12   7735 use Bio::Polloc::Polloc::Error;
  12         40  
  12         117  
17 12     12   703 use Error qw(:try);
  12         24  
  12         51  
18              
19             =head1 GLOBALS
20              
21             Global variables controling the behavior of the package
22              
23             =cut
24              
25             our($VERBOSITY, $DOER, $DEBUGLOG, $TIMESTAMP);
26              
27             =head2 VERSION
28              
29             The package's version
30              
31             =cut
32              
33             our $VERSION = 1.0503; # [a-version] from Bio::Polloc::Polloc::Version
34              
35              
36             =head2 VERBOSITY
37              
38             Verbosity level
39              
40             =cut
41              
42             $VERBOSITY = 0;
43 0     0 1 0 sub VERBOSITY { shift; $VERBOSITY = 0 + shift }
  0         0  
44              
45             =head2 TIMESTAMP
46              
47             Should I report the current Unix time on each debug line?
48              
49             =cut
50              
51             $TIMESTAMP = 0;
52 0     0 1 0 sub TIMESTAMP { shift; $TIMESTAMP = shift }
  0         0  
53              
54             =head2 DOER
55              
56             Should I save my work? Provided for testing purposes
57              
58             =cut
59              
60             $DOER = 1;
61 0     0 1 0 sub DOER { shift ; $DOER = shift }
  0         0  
62              
63             =head2 DEBUGLOG
64              
65             Sets the file at which debug information should be saved
66             if VERBOSITY is greater or equal to 2, and returns a
67             L<Bio::Polloc::Polloc::IO> object to write on it.
68              
69             =cut
70              
71             sub DEBUGLOG {
72 0     0 1 0 my $self = shift;
73 0 0       0 $DEBUGLOG = Bio::Polloc::Polloc::IO->new(@_) if $#_ >= 0;
74 0         0 return $DEBUGLOG;
75             }
76              
77             =head1 PUBLIC METHODS
78              
79             Methods provided by the package
80            
81             =head2 new
82              
83             Generic instantiation function
84              
85             =cut
86             sub new {
87 752     752 1 949 my $class = shift;
88 752         1185 my $self = {};
89 752   33     3398 bless $self, ref($class) || $class;
90 752 100       1603 if( @_ > 1 ){
91 505 50       958 shift if @_ % 2;
92 505         2384 my %param = @_;
93 505   33     2466 $self->verbosity($param{'-VERBOSE'} || $param{'-verbose'});
94             }
95 752         1998 return $self;
96             }
97              
98              
99             =head2 verbosity
100              
101             Gets/sets the verbosity level
102              
103             =head3 Arguments
104              
105             =over
106              
107             =item An integer
108              
109             -1 : No warnings
110             0 : Display warnings
111             1 : Display warnings with stacktrace
112             2 : + debug information
113             3 : + throw on warning
114              
115             =back
116              
117             =head3 Returns
118              
119             An integer (as the arguments)
120              
121             =cut
122              
123             sub verbosity {
124 1501     1501 1 1770 my($self,$value) = @_;
125 1501 100       2947 return $VERBOSITY unless ref $self;
126 1496 50       2554 $self->{'_verbosity'} = ($value+0) if defined $value;
127 1496 100       3570 $self->{'_verbosity'} = $VERBOSITY unless defined $self->{'_verbosity'};
128 1496         5327 return $self->{'_verbosity'};
129             }
130              
131              
132             =head2 throw
133              
134             Throws an Exception
135              
136             =head3 Arguments
137              
138             =over
139              
140             =item -text
141              
142             The message of the error
143              
144             =item -value
145              
146             The element causing the error
147              
148             =item -class
149              
150             The exception class (L<Bio::Polloc::Polloc::Error> by default)
151              
152             =back
153              
154             =head3 Returns
155              
156             Nothing
157              
158             =cut
159              
160             sub throw {
161 1     1 1 3 my ($self, @args) = @_;
162 1         6 my ($text, $value, $class) =
163             $self->_rearrange([qw(TEXT VALUE CLASS)], @args);
164 1   50     8 $class ||= "Bio::Polloc::Polloc::Error";
165 1         15 $class->throw( -text=>$text, -value=>$value, -object=>$self );
166             }
167              
168              
169             =head2 debug
170              
171             Appends debug information to the L<$Bio::Polloc::Polloc::DEBUGLOG> or STDERR
172             if verbosity is greater than 1
173              
174             =cut
175              
176             sub debug {
177 996     996 1 1674 my($self,@txt) = @_;
178 996 50       1642 if($self->verbosity >= 2){
179 0 0       0 my $msg = "" . ($TIMESTAMP ? "[".time()."] " : '') . ref($self) . " | " . join(' ', @txt) . "\n";
180 0 0       0 if(defined $self->DEBUGLOG){ $self->DEBUGLOG->_print($msg) }
  0         0  
181 0         0 else{ print STDERR $msg }
182             }
183             }
184              
185              
186             =head2 warn
187              
188             Launches a warning message. If verbosity is greater than two, the
189             message becomes a C<throw>.
190              
191             =cut
192              
193             sub warn {
194 0     0 1 0 my ($self, $txt, $value) = @_;
195 0         0 my $verb = $self->verbosity;
196 0 0       0 return if $verb==-1;
197 0 0       0 $self->throw($txt,$value,'Bio::Polloc::Polloc::LoudWarningException') if $verb >=3;
198 0         0 my $out = "\n" . ("-"x10) . " WARNING " . ("-"x10) . "\n" .
199             "MSG: " . $txt . "\n" ;
200 0 0       0 $out.= "VALUE: $value - ".ref($value)."\n" if defined $value;
201 0 0       0 if($verb>=1){
202 0         0 $out.= $self->stack_trace_dump;
203             }
204 0         0 $out.= ("-"x29) . "\n";
205 0         0 print STDERR $out;
206 0         0 return;
207             }
208              
209              
210             =head2 stack_trace_dump
211              
212             =cut
213              
214             sub stack_trace_dump {
215 0     0 1 0 my $self = shift;
216 0         0 my @stack = $self->stack_trace;
217              
218 0         0 shift @stack; # stack_trace
219 0         0 shift @stack; # stack_trace_dump
220 0         0 shift @stack; # error_msg
221              
222 0         0 my $out = "";
223 0         0 for my $stack ( @stack ){
224 0         0 my ($module, $file, $position, $function) = @{$stack};
  0         0  
225 0         0 $out.= "STACK $function $file:$position\n";
226             }
227 0         0 return $out;
228             }
229              
230             =head2 strack_trace
231              
232             =cut
233              
234             sub stack_trace {
235 0     0 0 0 my $self = shift;
236 0         0 my $i = 0;
237 0         0 my @out = ();
238 0         0 my $prev = [];
239 0         0 while( my @call = caller($i++)){
240 0         0 $prev->[3] = $call[3];
241 0         0 push @out, $prev;
242 0         0 $prev = \@call;
243             }
244 0         0 $prev->[3] = 'toplevel';
245 0         0 push @out, $prev;
246 0         0 return @out;
247             }
248              
249              
250             =head2 vardump
251              
252             Attempts to display all the content of a given object
253              
254             =head3 Arguments
255              
256             Some object (any type)
257              
258             =head3 Returns
259              
260             Nothing, the result is sent to STDOUT
261              
262             =cut
263              
264             sub vardump {
265 0     0 1 0 my ($self,$value) = @_;
266 0 0       0 if(!defined $value){
    0          
    0          
267 0         0 print "\nundef.\n";
268             }elsif(ref($value) =~ /hash/i){
269 0         0 print "{\n";
270 0         0 for my $k ( keys %$value ){
271 0         0 print "$k=>";
272 0         0 $self->vardump($value->{$k});
273 0         0 print "\n";
274             }
275 0         0 print "\n}\n";
276             }elsif(ref($value) =~ /array/i){
277 0         0 print "[\n";
278 0         0 for (@$value){
279 0         0 $self->vardump($_);
280 0         0 print "\n";
281             }
282 0         0 print "\n]\n";
283             }else{
284 0         0 print $value;
285             }
286             }
287              
288             =head2 rrmdir
289              
290             Recursively removes a directory.
291              
292             =cut
293              
294             sub rrmdir {
295 0     0 1 0 my ($self, $dir) = @_;
296 0 0       0 return unless -d $dir;
297 0         0 while(my $file = <$dir/*>){
298 0 0       0 next if $file =~ /^\.\.?$/;
299 0         0 $file = Bio::Polloc::Polloc::IO->catfile($dir, $file);
300 0 0       0 if(-d $file){ $self->rrmdir($file) }
  0         0  
301 0         0 else { unlink $file }
302             }
303 0         0 rmdir $dir;
304             }
305              
306             =head1 INTERNAL METHODS
307              
308             Methods intended to be used only witin the scope of Bio::Polloc::*
309              
310             =head2 _rearrange
311              
312             =cut
313              
314             sub _rearrange {
315 1625     1625   1990 my $self = shift;
316 1625         1691 my $order = shift;
317 1625 100 100     6929 return unless $#_>=0 && defined $_[0];
318 1280 100       4150 return @_ unless $_[0] =~ m/^-/;
319 1005 50       1947 push @_, undef unless $#_%2;
320 1005         1077 my %param;
321 1005         1778 while(@_){
322 5144         6388 (my $key = shift) =~ tr/a-z\055/A-Z/d; #deletes all dashes!
323 5144         12463 $param{$key} = shift;
324             }
325 1005         1471 map { $_ = uc($_) } @$order;
  3384         6194  
326 1005         9926 return @param{@$order};
327             }
328              
329             =head2 _load_module
330              
331             =cut
332              
333             sub _load_module {
334 246     246   359 my($self, $name) = @_;
335 246         251 my($module, $load);
336 246         430 $module = "_<$name.pm";
337 246 50       788 return 1 if $main::{$module};
338              
339 246 50       1122 $self->throw("Illegal perl package name", $name) unless $name =~ m/^([\w:]+)$/;
340 246         323 $load = "$name.pm";
341 246         842 my $io = Bio::Polloc::Polloc::IO->new();
342 246         1367 $load = $io->catfile((split /::/, $load));
343 246         536 eval {
344 246         21137 require $load;
345             };
346 246 100       585 $self->throw("Failed to load module. ".$@, $name) if $@;
347 245         646 return 1;
348             }
349              
350             =head2 _register_cleanup_method
351              
352             =cut
353              
354             sub _register_cleanup_method {
355 258     258   330 my($self, $method) = @_;
356 258 50       465 return unless $method;
357 258   50     1332 $self->{'_cleanup_methods'} ||= [];
358 258         296 push @{$self->{'_cleanup_methods'}}, $method;
  258         762  
359             }
360              
361             =head2 _unregister_cleanup_method
362              
363             =cut
364              
365             sub _unregister_cleanup_method {
366 0     0   0 my($self, $method) = @_;
367 0         0 my @keep = grep {$_ ne $method} $self->_cleanup_methods;
  0         0  
368 0         0 $self->{'_cleanup_methods'} = \@keep;
369             }
370              
371             =head2 _cleanup_methods
372              
373             =cut
374              
375             sub _cleanup_methods {
376 584     584   671 my $self = shift;
377 584 50 33     4752 return unless ref $self && $self->isa('HASH');
378 584 100       3240 my $methods = $self->{'_cleanup_methods'} or return;
379 250         791 @$methods;
380             }
381              
382             =head2 DESTROY
383              
384             =cut
385              
386             sub DESTROY {
387 584     584   1854 my $self = shift;
388 584 100       1184 my @cleanup_methods = $self->_cleanup_methods or return;
389 250         434 for my $method (@cleanup_methods){
390 250         640 $method->($self);
391             }
392             }
393              
394             1;