File Coverage

blib/lib/Class/AutoClass/Root.pm
Criterion Covered Total %
statement 67 93 72.0
branch 13 32 40.6
condition 5 14 35.7
subroutine 13 16 81.2
pod 7 7 100.0
total 105 162 64.8


line stmt bran cond sub pod time code
1             package Class::AutoClass::Root;
2 13     13   22152 use strict;
  13         25  
  13         723  
3              
4             =head1 NAME
5              
6             Class::AutoClass::Root
7              
8             =head1 SYNOPSIS
9             # Here's how to throw and catch an exception using the eval-based syntax.
10              
11             $obj->throw("This is an exception");
12              
13             eval {
14             $obj->throw("This is catching an exception");
15             };
16              
17             if( $@ ) {
18             print "Caught exception";
19             } else {
20             print "no exception";
21             }
22              
23             =head1 DESCRIPTION
24             This class provides some basic functionality for Class::* classes.
25              
26             This package is borrowed from bioperl project (http://bioperl.org/). Because of the
27             formidable size of the bioperl library, Root.pm is included here with modifications.
28             These modifications were to pare its functioanlity down for its simple job here
29             (removing routines that are out of context and removing references to bioperl to avoid confusion).
30              
31             Functions originally from Steve Chervitz of bioperl. Refactored by Ewan
32             Birney of bioperl. Re-refactored by Lincoln Stein of bioperl.
33              
34             =head2 Throwing Exceptions
35              
36             One of the functionalities that Class::AutoClass::Root provides is the
37             ability to throw() exceptions with pretty stack traces.
38              
39             =head1 CONTACT
40              
41             contact: Chris Cavnor -> ccavnor@systemsbiology.org
42              
43             =head1 APPENDIX
44              
45             The rest of the documentation details each of the object
46             methods. Internal methods are usually preceded with a _
47              
48             =cut
49              
50             #'
51              
52 13     13   74 use vars qw(@ISA $DEBUG $ID $Revision $VERSION $VERBOSITY $ERRORLOADED @EXPORT);
  13         26  
  13         1518  
53 13     13   68 use strict;
  13         22  
  13         852  
54              
55             BEGIN {
56              
57 13     13   30 $ID = 'Class::AutoClass::Root';
58 13         41 $VERSION = 1.0;
59 13         28 $Revision = '';
60 13         135 $DEBUG = 0;
61 13         22 $VERBOSITY = 0;
62 13         19195 $ERRORLOADED = 0;
63             }
64              
65              
66              
67             =head2 new
68              
69             Purpose : generic instantiation function can be overridden if
70             special needs of a module cannot be done in _initialize
71              
72             =cut
73              
74             sub new {
75 1     1 1 13 my $class = shift;
76 1         3 my $self = {};
77 1   33     8 bless $self, ref($class) || $class;
78              
79 1 50       5 if(@_ > 1) {
80             # if the number of arguments is odd but at least 3, we'll give
81             # it a try to find -verbose
82 0 0       0 shift if @_ % 2;
83 0         0 my %param = @_;
84 0   0     0 $self->verbose($param{'-VERBOSE'} || $param{'-verbose'});
85             }
86 1         4 return $self;
87             }
88            
89             =head2 verbose
90              
91             Title : verbose
92             Usage : $self->verbose(1)
93             Function: Sets verbose level for how ->warn behaves
94             -1 = no warning
95             0 = standard, small warning
96             1 = warning with stack trace
97             2 = warning becomes throw
98             Returns : The current verbosity setting (integer between -1 to 2)
99             Args : -1,0,1 or 2
100              
101              
102             =cut
103              
104             sub verbose {
105 3     3 1 6 my ($self,$value) = @_;
106             # allow one to set global verbosity flag
107 3 50       12 return $DEBUG if $DEBUG;
108 3 50       8 return $VERBOSITY unless ref $self;
109            
110 3 100 66     22 if (defined $value || ! defined $self->{'_root_verbose'}) {
111 1   50     7 $self->{'_root_verbose'} = $value || 0;
112             }
113 3         11 return $self->{'_root_verbose'};
114             }
115              
116             sub _register_for_cleanup {
117 0     0   0 my ($self,$method) = @_;
118 0 0       0 if($method) {
119 0 0       0 if(! exists($self->{'_root_cleanup_methods'})) {
120 0         0 $self->{'_root_cleanup_methods'} = [];
121             }
122 0         0 push(@{$self->{'_root_cleanup_methods'}},$method);
  0         0  
123             }
124             }
125              
126             sub _unregister_for_cleanup {
127 0     0   0 my ($self,$method) = @_;
128 0         0 my @methods = grep {$_ ne $method} $self->_cleanup_methods;
  0         0  
129 0         0 $self->{'_root_cleanup_methods'} = \@methods;
130             }
131              
132              
133             sub _cleanup_methods {
134 69     69   98 my $self = shift;
135 69 50 33     656 return unless ref $self && $self->isa('HASH');
136 69 50       7334 my $methods = $self->{'_root_cleanup_methods'} or return;
137 0         0 @$methods;
138              
139             }
140              
141             =head2 throw
142              
143             Title : throw
144             Usage : $obj->throw("throwing exception message")
145             Function: Throws an exception, which, if not caught with an eval brace
146             will provide a nice stack trace to STDERR with the message
147             Returns : nothing
148             Args : A string giving a descriptive error message
149              
150              
151             =cut
152              
153             sub throw{
154 1     1 1 466 my ($self,$string) = @_;
155              
156 1         4 my $std = $self->_stack_trace_dump();
157              
158 1         10 my $out = "\n-------------------- EXCEPTION --------------------\n".
159             "MSG: ".$string."\n".$std."-------------------------------------------\n";
160 1         8 die $out;
161              
162             }
163              
164             =head2 stack_trace
165              
166             Title : stack_trace
167             Usage : @stack_array_ref= $self->stack_trace
168             Function: gives an array to a reference of arrays with stack trace info
169             each coming from the caller(stack_number) call
170             Returns : array containing a reference of arrays
171             Args : none
172              
173              
174             =cut
175              
176             sub stack_trace{
177 3     3 1 506 my ($self) = @_;
178              
179 3         10 my $i = 0;
180 3         4 my @out;
181             my $prev;
182 3         25 while( my @call = caller($i++)) {
183             # major annoyance that caller puts caller context as
184             # function name. Hence some monkeying around...
185 9         17 $prev->[3] = $call[3];
186 9         11 push(@out,$prev);
187 9         62 $prev = \@call;
188             }
189 3         6 $prev->[3] = 'toplevel';
190 3         5 push(@out,$prev);
191 3         9 return @out;
192             }
193              
194             =head2 _stack_trace_dump
195              
196             Title : _stack_trace_dump
197             Usage :
198             Function:
199             Example :
200             Returns :
201             Args :
202              
203              
204             =cut
205              
206             sub _stack_trace_dump{
207 2     2   3 my ($self) = @_;
208              
209 2         14 my @stack = $self->stack_trace();
210              
211 2         5 shift @stack;
212 2         15 shift @stack;
213 2         5 shift @stack;
214              
215 2         7 my $out;
216 2         4 my ($module,$function,$file,$position);
217            
218              
219 2         4 foreach my $stack ( @stack) {
220 4         6 ($module,$file,$position,$function) = @{$stack};
  4         13  
221 4         18 $out .= "STACK $function $file:$position\n";
222             }
223              
224 2         14 return $out;
225             }
226              
227              
228             =head2 deprecated
229              
230             Title : deprecated
231             Usage : $obj->deprecated("Method X is deprecated");
232             Function: Prints a message about deprecation
233             unless verbose is < 0 (which means be quiet)
234             Returns : none
235             Args : Message string to print to STDERR
236              
237             =cut
238              
239             sub deprecated{
240 1     1 1 1128 my ($self,$msg) = @_;
241 1 50       4 if( $self->verbose >= 0 ) {
242 1         5 print STDERR $msg, "\n", $self->_stack_trace_dump;
243             }
244             }
245              
246             =head2 warn
247              
248             Title : warn
249             Usage : $object->warn("Warning message");
250             Function: Places a warning. What happens now is down to the
251             verbosity of the object (value of $obj->verbose)
252             verbosity 0 or not set => small warning
253             verbosity -1 => no warning
254             verbosity 1 => warning with stack trace
255             verbosity 2 => converts warnings into throw
256             Example :
257             Returns :
258             Args :
259              
260             =cut
261              
262             sub warn{
263 2     2 1 1035 my ($self,$string) = @_;
264            
265 2         4 my $verbose;
266 2 50       50 if( $self->can('verbose') ) {
267 2         6 $verbose = $self->verbose;
268             } else {
269 0         0 $verbose = 0;
270             }
271              
272 2 50       11 if( $verbose == 2 ) {
    50          
    50          
273 0         0 $self->throw($string);
274             } elsif( $verbose == -1 ) {
275 0         0 return;
276             } elsif( $verbose == 1 ) {
277 0         0 my $out = "\n-------------------- WARNING ---------------------\n".
278             "MSG: ".$string."\n";
279 0         0 $out .= $self->_stack_trace_dump;
280            
281 0         0 print STDERR $out;
282 0         0 return;
283             }
284              
285 2         7 my $out = "\n-------------------- WARNING ---------------------\n".
286             "MSG: ".$string."\n".
287             "---------------------------------------------------\n";
288 2         6 print STDERR $out;
289             }
290              
291             =head2 debug
292              
293             Title : debug
294             Usage : $obj->debug("This is debugging output");
295             Function: Prints a debugging message when verbose is > 0
296             Returns : none
297             Args : message string(s) to print to STDERR
298              
299             =cut
300              
301             sub debug{
302 0     0 1 0 my ($self,@msgs) = @_;
303            
304 0 0       0 if( $self->verbose > 0 ) {
305 0         0 print STDERR join("", @msgs);
306             }
307             }
308              
309             sub DESTROY {
310 69     69   20803 my $self = shift;
311 69 50       342 my @cleanup_methods = $self->_cleanup_methods or return;
312 0           for my $method (@cleanup_methods) {
313 0           $method->($self);
314             }
315             }
316              
317              
318              
319             1;
320