Profile of /usr/local/lib/perl5/site_perl/5.10.1/Exception/Class.pm

← Index
NYTProf Performance Profile «block view•line view•sub view»
For 05.Domain_and_Item.t
Run on Tue May 4 17:21:41 2010
Reported on Tue May 4 17:22:22 2010

File | /usr/local/lib/perl5/site_perl/5.10.1/Exception/Class.pm
Statements Executed | 439
Statement Execution Time | 2.45ms

Subroutines — ordered by exclusive time
Calls | P | F | Exclusive Time | Inclusive Time | Subroutine
--- | --- | --- | --- | --- | ---
1 | 1 | 1 | 1.18ms | 5.51ms | Exception::Class::::BEGIN@7Exception::Class::BEGIN@7
8 | 2 | 1 | 883µs | 1.33ms | Exception::Class::::_make_subclassException::Class::_make_subclass
43 | 1 | 1 | 235µs | 291µs | Exception::Class::::caughtException::Class::caught
2 | 2 | 2 | 141µs | 1.52ms | Exception::Class::::importException::Class::import
1 | 1 | 1 | 39µs | 39µs | Exception::Class::::BEGIN@3Exception::Class::BEGIN@3
2 | 1 | 1 | 30µs | 375µs | Exception::Class::::_make_parentsException::Class::_make_parents
2 | 1 | 2 | 18µs | 18µs | Exception::Class::::CORE:sortException::Class::CORE:sort (opcode)
1 | 1 | 1 | 8µs | 36µs | Exception::Class::::BEGIN@8Exception::Class::BEGIN@8
8 | 1 | 2 | 8µs | 8µs | Exception::Class::::CORE:substException::Class::CORE:subst (opcode)
1 | 1 | 1 | 7µs | 19µs | Exception::Class::::BEGIN@45Exception::Class::BEGIN@45
1 | 1 | 1 | 7µs | 18µs | Exception::Class::::BEGIN@168Exception::Class::BEGIN@168
1 | 1 | 1 | 7µs | 17µs | Exception::Class::::BEGIN@78Exception::Class::BEGIN@78
1 | 1 | 1 | 6µs | 9µs | Exception::Class::::BEGIN@5Exception::Class::BEGIN@5
1 | 1 | 1 | 4µs | 4µs | Exception::Class::::BEGIN@11Exception::Class::BEGIN@11
0 | 0 | 0 | 0s | 0s | Exception::Class::::ClassesException::Class::Classes
0 | 0 | 0 | 0s | 0s | Exception::Class::::__ANON__[:169]Exception::Class::__ANON__[:169]

Call graph for these subroutines as a Graphviz dot language file.

Line | State ments | Time on line | Calls | Time in subs | Code
--- | --- | --- | --- | --- | ---
1 |  |  |  |  | package Exception::Class;
2 |  |  |  |  |
3 | 3 | 52µs | 1 | 39µs | # spent 39µs within Exception::Class::BEGIN@3 which was called # once (39µs+0s) by SimpleDB::Class::Exception::BEGIN@46 at line 3 use 5.008001; # spent 39µs making 1 call to Exception::Class::BEGIN@3
4 |  |  |  |  |
5 | 3 | 18µs | 2 | 11µs | # spent 9µs (6+2) within Exception::Class::BEGIN@5 which was called # once (6µs+2µs) by SimpleDB::Class::Exception::BEGIN@46 at line 5 use strict; # spent 9µs making 1 call to Exception::Class::BEGIN@5 # spent 2µs making 1 call to strict::import
6 |  |  |  |  |
7 | 3 | 116µs | 1 | 5.51ms | # spent 5.51ms (1.18+4.33) within Exception::Class::BEGIN@7 which was called # once (1.18ms+4.33ms) by SimpleDB::Class::Exception::BEGIN@46 at line 7 use Exception::Class::Base; # spent 5.51ms making 1 call to Exception::Class::BEGIN@7
8 | 3 | 34µs | 2 | 63µs | # spent 36µs (8+27) within Exception::Class::BEGIN@8 which was called # once (8µs+27µs) by SimpleDB::Class::Exception::BEGIN@46 at line 8 use Scalar::Util qw(blessed); # spent 36µs making 1 call to Exception::Class::BEGIN@8 # spent 27µs making 1 call to Exporter::import
9 |  |  |  |  |
10 | 1 | 100ns |  |  | our $BASE_EXC_CLASS;
11 | 1 | 125µs | 1 | 4µs | # spent 4µs within Exception::Class::BEGIN@11 which was called # once (4µs+0s) by SimpleDB::Class::Exception::BEGIN@46 at line 11 BEGIN { $BASE_EXC_CLASS ||= 'Exception::Class::Base'; } # spent 4µs making 1 call to Exception::Class::BEGIN@11
12 |  |  |  |  |
13 | 1 | 500ns |  |  | our $VERSION = '1.29';
14 |  |  |  |  |
15 | 1 | 200ns |  |  | our %CLASSES;
16 |  |  |  |  |
17 |  |  |  |  | sub import
18 |  |  |  |  | # spent 1.52ms (141µs+1.38) within Exception::Class::import which was called 2 times, avg 760µs/call: # once (76µs+787µs) by SimpleDB::Class::Exception::BEGIN@46 at line 48 of ../lib/SimpleDB/Class/Exception.pm # once (65µs+591µs) by SimpleDB::Client::Exception::BEGIN@55 at line 57 of SimpleDB/Client/Exception.pm {
19 | 90 | 135µs |  |  | my $class = shift;
20 |  |  |  |  |
21 |  |  |  |  | local $Exception::Class::Caller = caller();
22 |  |  |  |  |
23 |  |  |  |  | my %c;
24 |  |  |  |  |
25 |  |  |  |  | my %needs_parent;
26 |  |  |  |  | while (my $subclass = shift)
27 |  |  |  |  | {
28 |  |  |  |  | my $def = ref $_[0] ? shift : {};
29 |  |  |  |  | $def->{isa} = $def->{isa} ? ( ref $def->{isa} ? $def->{isa} : [$def->{isa}] ) : [];
30 |  |  |  |  |
31 |  |  |  |  | $c{$subclass} = $def;
32 |  |  |  |  | }
33 |  |  |  |  |
34 |  |  |  |  | # We need to sort by length because if we check for keys in the
35 |  |  |  |  | # Foo::Bar:: stash, this creates a "Bar::" key in the Foo:: stash!
36 |  |  |  |  | MAKE_CLASSES:
37 |  |  |  |  | foreach my $subclass ( sort { length $a <=> length $b } keys %c ) # spent 18µs making 2 calls to Exception::Class::CORE:sort, avg 9µs/call
38 |  |  |  |  | {
39 |  |  |  |  | my $def = $c{$subclass};
40 |  |  |  |  |
41 |  |  |  |  | # We already made this one.
42 |  |  |  |  | next if $CLASSES{$subclass};
43 |  |  |  |  |
44 |  |  |  |  | {
45 | 3 | 124µs | 2 | 30µs | # spent 19µs (7+12) within Exception::Class::BEGIN@45 which was called # once (7µs+12µs) by SimpleDB::Class::Exception::BEGIN@46 at line 45 no strict 'refs'; # spent 19µs making 1 call to Exception::Class::BEGIN@45 # spent 12µs making 1 call to strict::unimport
46 |  |  |  |  | foreach my $parent (@{ $def->{isa} })
47 |  |  |  |  | {
48 |  |  |  |  | unless ( keys %{"$parent\::"} )
49 |  |  |  |  | {
50 |  |  |  |  | $needs_parent{$subclass} = { parents => $def->{isa},
51 |  |  |  |  | def => $def };
52 |  |  |  |  | next MAKE_CLASSES;
53 |  |  |  |  | }
54 |  |  |  |  | }
55 |  |  |  |  | }
56 |  |  |  |  |
57 |  |  |  |  | $class->_make_subclass( subclass => $subclass, # spent 985µs making 6 calls to Exception::Class::_make_subclass, avg 164µs/call
58 |  |  |  |  | def => $def || {},
59 |  |  |  |  | );
60 |  |  |  |  | }
61 |  |  |  |  |
62 |  |  |  |  | foreach my $subclass (keys %needs_parent)
63 |  |  |  |  | {
64 |  |  |  |  | # This will be used to spot circular references.
65 |  |  |  |  | my %seen;
66 |  |  |  |  | $class->_make_parents( \%needs_parent, $subclass, \%seen ); # spent 375µs making 2 calls to Exception::Class::_make_parents, avg 188µs/call
67 |  |  |  |  | }
68 |  |  |  |  | }
69 |  |  |  |  |
70 |  |  |  |  | sub _make_parents
71 |  |  |  |  | # spent 375µs (30+345) within Exception::Class::_make_parents which was called 2 times, avg 188µs/call: # 2 times (30µs+345µs) by Exception::Class::import at line 66, avg 188µs/call {
72 | 20 | 25µs |  |  | my $class = shift;
73 |  |  |  |  | my $needs = shift;
74 |  |  |  |  | my $subclass = shift;
75 |  |  |  |  | my $seen = shift;
76 |  |  |  |  | my $child = shift; # Just for error messages.
77 |  |  |  |  |
78 | 3 | 320µs | 2 | 27µs | # spent 17µs (7+10) within Exception::Class::BEGIN@78 which was called # once (7µs+10µs) by SimpleDB::Class::Exception::BEGIN@46 at line 78 no strict 'refs'; # spent 17µs making 1 call to Exception::Class::BEGIN@78 # spent 10µs making 1 call to strict::unimport
79 |  |  |  |  |
80 |  |  |  |  | # What if someone makes a typo in specifying their 'isa' param?
81 |  |  |  |  | # This should catch it. Either it's been made because it didn't
82 |  |  |  |  | # have missing parents OR it's in our hash as needing a parent.
83 |  |  |  |  | # If neither of these is true then the _only_ place it is
84 |  |  |  |  | # mentioned is in the 'isa' param for some other class, which is
85 |  |  |  |  | # not a good enough reason to make a new class.
86 |  |  |  |  | die "Class $subclass appears to be a typo as it is only specified in the 'isa' param for $child\n"
87 |  |  |  |  | unless exists $needs->{$subclass} || $CLASSES{$subclass} || keys %{"$subclass\::"};
88 |  |  |  |  |
89 |  |  |  |  | foreach my $c ( @{ $needs->{$subclass}{parents} } )
90 |  |  |  |  | {
91 |  |  |  |  | # It's been made
92 |  |  |  |  | next if $CLASSES{$c} || keys %{"$c\::"};
93 |  |  |  |  |
94 |  |  |  |  | die "There appears to be some circularity involving $subclass\n"
95 |  |  |  |  | if $seen->{$subclass};
96 |  |  |  |  |
97 |  |  |  |  | $seen->{$subclass} = 1;
98 |  |  |  |  |
99 |  |  |  |  | $class->_make_parents( $needs, $c, $seen, $subclass );
100 |  |  |  |  | }
101 |  |  |  |  |
102 |  |  |  |  | return if $CLASSES{$subclass} || keys %{"$subclass\::"};
103 |  |  |  |  |
104 |  |  |  |  | $class->_make_subclass( subclass => $subclass, # spent 345µs making 2 calls to Exception::Class::_make_subclass, avg 172µs/call
105 |  |  |  |  | def => $needs->{$subclass}{def} );
106 |  |  |  |  | }
107 |  |  |  |  |
108 |  |  |  |  | sub _make_subclass
109 |  |  |  |  | # spent 1.33ms (883µs+446µs) within Exception::Class::_make_subclass which was called 8 times, avg 166µs/call: # 6 times (645µs+340µs) by Exception::Class::import at line 57, avg 164µs/call # 2 times (239µs+106µs) by Exception::Class::_make_parents at line 104, avg 172µs/call {
110 | 168 | 428µs |  |  | my $class = shift;
111 |  |  |  |  | my %p = @_;
112 |  |  |  |  |
113 |  |  |  |  | my $subclass = $p{subclass};
114 |  |  |  |  | my $def = $p{def};
115 |  |  |  |  |
116 |  |  |  |  | my $isa;
117 |  |  |  |  | if ($def->{isa})
118 |  |  |  |  | {
119 |  |  |  |  | $isa = ref $def->{isa} ? join ' ', @{ $def->{isa} } : $def->{isa};
120 |  |  |  |  | }
121 |  |  |  |  | $isa ||= $BASE_EXC_CLASS;
122 |  |  |  |  |
123 |  |  |  |  | my $version_name = 'VERSION';
124 |  |  |  |  |
125 |  |  |  |  | my $code = <<"EOPERL";
126 |  |  |  |  | package $subclass;
127 |  |  |  |  |
128 |  |  |  |  | use base qw($isa);
129 |  |  |  |  |
130 |  |  |  |  | our \$$version_name = '1.1';
131 |  |  |  |  |
132 |  |  |  |  | 1;
133 |  |  |  |  |
134 |  |  |  |  | EOPERL
135 |  |  |  |  |
136 |  |  |  |  |
137 |  |  |  |  | if ($def->{description})
138 |  |  |  |  | {
139 |  |  |  |  | (my $desc = $def->{description}) =~ s/([\\\'])/\\$1/g; # spent 8µs making 8 calls to Exception::Class::CORE:subst, avg 1µs/call
140 |  |  |  |  | $code .= <<"EOPERL";
141 |  |  |  |  | sub description
142 |  |  |  |  | {
143 |  |  |  |  | return '$desc';
144 |  |  |  |  | }
145 |  |  |  |  | EOPERL
146 |  |  |  |  | }
147 |  |  |  |  |
148 |  |  |  |  | my @fields;
149 |  |  |  |  | if ( my $fields = $def->{fields} )
150 |  |  |  |  | {
151 |  |  |  |  | @fields = UNIVERSAL::isa($fields, 'ARRAY') ? @$fields : $fields; # spent 4µs making 5 calls to UNIVERSAL::isa, avg 780ns/call
152 |  |  |  |  |
153 |  |  |  |  | $code .=
154 |  |  |  |  | "sub Fields { return (\$_[0]->SUPER::Fields, " .
155 |  |  |  |  | join(", ", map { "'$_'" } @fields) . ") }\n\n";
156 |  |  |  |  |
157 |  |  |  |  | foreach my $field (@fields)
158 |  |  |  |  | {
159 |  |  |  |  | $code .= sprintf("sub %s { \$_[0]->{%s} }\n", $field, $field);
160 |  |  |  |  | }
161 |  |  |  |  | }
162 |  |  |  |  |
163 |  |  |  |  | if ( my $alias = $def->{alias} )
164 |  |  |  |  | {
165 |  |  |  |  | die "Cannot make alias without caller"
166 |  |  |  |  | unless defined $Exception::Class::Caller;
167 |  |  |  |  |
168 | 3 | 169µs | 2 | 29µs | # spent 18µs (7+11) within Exception::Class::BEGIN@168 which was called # once (7µs+11µs) by SimpleDB::Class::Exception::BEGIN@46 at line 168 no strict 'refs'; # spent 18µs making 1 call to Exception::Class::BEGIN@168 # spent 11µs making 1 call to strict::unimport
169 |  |  |  |  | *{"$Exception::Class::Caller\::$alias"} = sub { $subclass->throw(@_) };
170 |  |  |  |  | }
171 |  |  |  |  |
172 | 1 | 589µs | 21 | 800µs | eval $code; # spent 358µs making 8 calls to base::import, avg 45µs/call # spent 81µs making 1 call to SimpleDB::Client::Exception::BEGIN@3 # spent 57µs making 1 call to SimpleDB::Class::Exception::ObjectNotFound::BEGIN@3 # spent 55µs making 1 call to SimpleDB::Client::Exception::Response::BEGIN@3 # spent 50µs making 1 call to SimpleDB::Class::Exception::BEGIN@3 # spent 48µs making 1 call to SimpleDB::Class::Exception::InvalidObject::BEGIN@3 # spent 48µs making 1 call to SimpleDB::Client::Exception::Connection::BEGIN@3 # spent 47µs making 1 call to SimpleDB::Class::Exception::Connection::BEGIN@3 # spent 46µs making 1 call to SimpleDB::Class::Exception::InvalidParam::BEGIN@3 # spent 8µs making 5 calls to Exception::Class::Base::Fields, avg 2µs/call
173 |  |  |  |  |
174 |  |  |  |  | die $@ if $@;
175 |  |  |  |  |
176 |  |  |  |  | $CLASSES{$subclass} = 1;
177 |  |  |  |  | }
178 |  |  |  |  |
179 |  |  |  |  | sub caught
180 |  |  |  |  | # spent 291µs (235+56) within Exception::Class::caught which was called 43 times, avg 7µs/call: # 43 times (235µs+56µs) by Exception::Class::Base::caught at line 214 of Exception/Class/Base.pm, avg 7µs/call {
181 | 134 | 313µs |  |  | my $e = $@;
182 |  |  |  |  |
183 |  |  |  |  | return $e unless $_[1];
184 |  |  |  |  |
185 |  |  |  |  | return unless blessed($e) && $e->isa( $_[1] ); # spent 50µs making 43 calls to Scalar::Util::blessed, avg 1µs/call # spent 6µs making 5 calls to UNIVERSAL::isa, avg 1µs/call
186 |  |  |  |  | return $e;
187 |  |  |  |  | }
188 |  |  |  |  |
189 |  |  |  |  | sub Classes { sort keys %Exception::Class::CLASSES }
190 |  |  |  |  |
191 | 1 | 4µs |  |  | 1;
192 |  |  |  |  |
193 |  |  |  |  | __END__
194 |  |  |  |  |
195 |  |  |  |  | =head1 NAME
196 |  |  |  |  |
197 |  |  |  |  | Exception::Class - A module that allows you to declare real exception classes in Perl
198 |  |  |  |  |
199 |  |  |  |  | =head1 SYNOPSIS
200 |  |  |  |  |
201 |  |  |  |  | use Exception::Class
202 |  |  |  |  | ( 'MyException',
203 |  |  |  |  |
204 |  |  |  |  | 'AnotherException' =>
205 |  |  |  |  | { isa => 'MyException' },
206 |  |  |  |  |
207 |  |  |  |  | 'YetAnotherException' =>
208 |  |  |  |  | { isa => 'AnotherException',
209 |  |  |  |  | description => 'These exceptions are related to IPC' },
210 |  |  |  |  |
211 |  |  |  |  | 'ExceptionWithFields' =>
212 |  |  |  |  | { isa => 'YetAnotherException',
213 |  |  |  |  | fields => [ 'grandiosity', 'quixotic' ],
214 |  |  |  |  | alias => 'throw_fields',
215 |  |  |  |  | },
216 |  |  |  |  | );
217 |  |  |  |  |
218 |  |  |  |  | # try
219 |  |  |  |  | eval { MyException->throw( error => 'I feel funny.' ) };
220 |  |  |  |  |
221 |  |  |  |  | my $e;
222 |  |  |  |  | # catch
223 |  |  |  |  | if ( $e = Exception::Class->caught('MyException') )
224 |  |  |  |  | {
225 |  |  |  |  | warn $e->error, "\n", $e->trace->as_string, "\n";
226 |  |  |  |  | warn join ' ', $e->euid, $e->egid, $e->uid, $e->gid, $e->pid, $e->time;
227 |  |  |  |  |
228 |  |  |  |  | exit;
229 |  |  |  |  | }
230 |  |  |  |  | elsif ( $e = Exception::Class->caught('ExceptionWithFields') )
231 |  |  |  |  | {
232 |  |  |  |  | $e->quixotic ? do_something_wacky() : do_something_sane();
233 |  |  |  |  | }
234 |  |  |  |  | else
235 |  |  |  |  | {
236 |  |  |  |  | $e = Exception::Class->caught();
237 |  |  |  |  | ref $e ? $e->rethrow : die $e;
238 |  |  |  |  | }
239 |  |  |  |  |
240 |  |  |  |  | # use an alias - without parens subroutine name is checked at
241 |  |  |  |  | # compile time
242 |  |  |  |  | throw_fields error => "No strawberry", grandiosity => "quite a bit";
243 |  |  |  |  |
244 |  |  |  |  | =head1 DESCRIPTION
245 |  |  |  |  |
246 |  |  |  |  | Exception::Class allows you to declare exception hierarchies in your
247 |  |  |  |  | modules in a "Java-esque" manner.
248 |  |  |  |  |
249 |  |  |  |  | It features a simple interface allowing programmers to 'declare'
250 |  |  |  |  | exception classes at compile time. It also has a base exception
251 |  |  |  |  | class, L<Exception::Class::Base>, that can be easily extended.
252 |  |  |  |  |
253 |  |  |  |  | It is designed to make structured exception handling simpler and
254 |  |  |  |  | better by encouraging people to use hierarchies of exceptions in their
255 |  |  |  |  | applications, as opposed to a single catch-all exception class.
256 |  |  |  |  |
257 |  |  |  |  | This module does not implement any try/catch syntax. Please see the
258 |  |  |  |  | "OTHER EXCEPTION MODULES (try/catch syntax)" section for more
259 |  |  |  |  | information on how to get this syntax.
260 |  |  |  |  |
261 |  |  |  |  | You will also want to look at the documentation for
262 |  |  |  |  | L<Exception::Class::Base>, which is the default base class for all
263 |  |  |  |  | exception objects created by this module.
264 |  |  |  |  |
265 |  |  |  |  | =head1 DECLARING EXCEPTION CLASSES
266 |  |  |  |  |
267 |  |  |  |  | Importing C<Exception::Class> allows you to automagically create
268 |  |  |  |  | L<Exception::Class::Base> subclasses. You can also create subclasses
269 |  |  |  |  | via the traditional means of defining your own subclass with C<@ISA>.
270 |  |  |  |  | These two methods may be easily combined, so that you could subclass
271 |  |  |  |  | an exception class defined via the automagic import, if you desired
272 |  |  |  |  | this.
273 |  |  |  |  |
274 |  |  |  |  | The syntax for the magic declarations is as follows:
275 |  |  |  |  |
276 |  |  |  |  | 'MANDATORY CLASS NAME' => \%optional_hashref
277 |  |  |  |  |
278 |  |  |  |  | The hashref may contain the following options:
279 |  |  |  |  |
280 |  |  |  |  | =over 4
281 |  |  |  |  |
282 |  |  |  |  | =item * isa
283 |  |  |  |  |
284 |  |  |  |  | This is the class's parent class. If this isn't provided then the
285 |  |  |  |  | class name in C<$Exception::Class::BASE_EXC_CLASS> is assumed to be
286 |  |  |  |  | the parent (see below).
287 |  |  |  |  |
288 |  |  |  |  | This parameter lets you create arbitrarily deep class hierarchies.
289 |  |  |  |  | This can be any other L<Exception::Class::Base> subclass in your
290 |  |  |  |  | declaration I<or> a subclass loaded from a module.
291 |  |  |  |  |
292 |  |  |  |  | To change the default exception class you will need to change the
293 |  |  |  |  | value of C<$Exception::Class::BASE_EXC_CLASS> I<before> calling
294 |  |  |  |  | C<import()>. To do this simply do something like this:
295 |  |  |  |  |
296 |  |  |  |  | BEGIN { $Exception::Class::BASE_EXC_CLASS = 'SomeExceptionClass'; }
297 |  |  |  |  |
298 |  |  |  |  | If anyone can come up with a more elegant way to do this please let me
299 |  |  |  |  | know.
300 |  |  |  |  |
301 |  |  |  |  | CAVEAT: If you want to automagically subclass an
302 |  |  |  |  | L<Exception::Class::Base> subclass loaded from a file, then you
303 |  |  |  |  | I<must> compile the class (via use or require or some other magic)
304 |  |  |  |  | I<before> you import C<Exception::Class> or you'll get a compile time
305 |  |  |  |  | error.
306 |  |  |  |  |
307 |  |  |  |  | =item * fields
308 |  |  |  |  |
309 |  |  |  |  | This allows you to define additional attributes for your exception
310 |  |  |  |  | class. Any field you define can be passed to the C<throw()> or
311 |  |  |  |  | C<new()> methods as additional parameters for the constructor. In
312 |  |  |  |  | addition, your exception object will have an accessor method for the
313 |  |  |  |  | fields you define.
314 |  |  |  |  |
315 |  |  |  |  | This parameter can be either a scalar (for a single field) or an array
316 |  |  |  |  | reference if you need to define multiple fields.
317 |  |  |  |  |
318 |  |  |  |  | Fields will be inherited by subclasses.
319 |  |  |  |  |
320 |  |  |  |  | =item * alias
321 |  |  |  |  |
322 |  |  |  |  | Specifying an alias causes this class to create a subroutine of the
323 |  |  |  |  | specified name in the I<caller's> namespace. Calling this subroutine
324 |  |  |  |  | is equivalent to calling C<< <class>->throw(@_) >> for the given
325 |  |  |  |  | exception class.
326 |  |  |  |  |
327 |  |  |  |  | Besides convenience, using aliases also allows for additional compile
328 |  |  |  |  | time checking. If the alias is called I<without parentheses>, as in
329 |  |  |  |  | C<throw_fields "an error occurred">, then Perl checks for the
330 |  |  |  |  | existence of the C<throw_fields()> subroutine at compile time. If
331 |  |  |  |  | instead you do C<< ExceptionWithFields->throw(...) >>, then Perl
332 |  |  |  |  | checks the class name at runtime, meaning that typos may sneak
333 |  |  |  |  | through.
334 |  |  |  |  |
335 |  |  |  |  | =item * description
336 |  |  |  |  |
337 |  |  |  |  | Each exception class has a description method that returns a fixed
338 |  |  |  |  | string. This should describe the exception I<class> (as opposed to
339 |  |  |  |  | any particular exception object). This may be useful for debugging if
340 |  |  |  |  | you start catching exceptions you weren't expecting (particularly if
341 |  |  |  |  | someone forgot to document them) and you don't understand the error
342 |  |  |  |  | messages.
343 |  |  |  |  |
344 |  |  |  |  | =back
345 |  |  |  |  |
346 |  |  |  |  | The C<Exception::Class> magic attempts to detect circular class
347 |  |  |  |  | hierarchies and will die if it finds one. It also detects missing
348 |  |  |  |  | links in a chain, for example if you declare Bar to be a subclass of
349 |  |  |  |  | Foo and never declare Foo.
350 |  |  |  |  |
351 |  |  |  |  | =head1 Catching Exceptions
352 |  |  |  |  |
353 |  |  |  |  | C<Exception::Class> provides some syntactic sugar for catching
354 |  |  |  |  | exceptions in a safe manner:
355 |  |  |  |  |
356 |  |  |  |  | eval { ... }
357 |  |  |  |  |
358 |  |  |  |  | if ( my $e = Exception::Class->caught('My::Error') )
359 |  |  |  |  | {
360 |  |  |  |  | cleanup();
361 |  |  |  |  | do_something_with_exception($e);
362 |  |  |  |  | }
363 |  |  |  |  |
364 |  |  |  |  | The C<caught()> method takes a class name and returns an exception
365 |  |  |  |  | object if the last thrown exception is of the given class, or a
366 |  |  |  |  | subclass of that class. If it is not given any arguments, it simply
367 |  |  |  |  | returns C<$@>.
368 |  |  |  |  |
369 |  |  |  |  | You should B<always> make a copy of the exception object, rather than
370 |  |  |  |  | using C<$@> directly. This is necessary because if your C<cleanup()>
371 |  |  |  |  | function uses C<eval>, or calls something which uses it, then C<$@> is
372 |  |  |  |  | overwritten. Copying the exception preserves it for the call to
373 |  |  |  |  | C<do_something_with_exception()>.
374 |  |  |  |  |
375 |  |  |  |  | Exception objects also provide a caught method so you can write:
376 |  |  |  |  |
377 |  |  |  |  | if ( my $e = My::Error->caught() )
378 |  |  |  |  | {
379 |  |  |  |  | cleanup();
380 |  |  |  |  | do_something_with_exception($e);
381 |  |  |  |  | }
382 |  |  |  |  |
383 |  |  |  |  | =head2 Uncatchable Exceptions
384 |  |  |  |  |
385 |  |  |  |  | Internally, the C<caught()> method will call C<isa()> on the exception
386 |  |  |  |  | object. You could make an exception "uncatchable" by overriding
387 |  |  |  |  | C<isa()> in that class like this:
388 |  |  |  |  |
389 |  |  |  |  | package Exception::Uncatchable;
390 |  |  |  |  |
391 |  |  |  |  | sub isa { shift->rethrow }
392 |  |  |  |  |
393 |  |  |  |  | Of course, this only works if you always call
394 |  |  |  |  | C<< Exception::Class->caught() >> after an C<eval>.
395 |  |  |  |  |
396 |  |  |  |  | =head1 USAGE RECOMMENDATION
397 |  |  |  |  |
398 |  |  |  |  | If you're creating a complex system that throws lots of different
399 |  |  |  |  | types of exceptions, consider putting all the exception declarations
400 |  |  |  |  | in one place. For an app called Foo you might make a
401 |  |  |  |  | C<Foo::Exceptions> module and use that in all your code. This module
402 |  |  |  |  | could just contain the code to make C<Exception::Class> do its
403 |  |  |  |  | automagic class creation. Doing this allows you to more easily see
404 |  |  |  |  | what exceptions you have, and makes it easier to keep track of them.
405 |  |  |  |  |
406 |  |  |  |  | This might look something like this:
407 |  |  |  |  |
408 |  |  |  |  | package Foo::Bar::Exceptions;
409 |  |  |  |  |
410 |  |  |  |  | use Exception::Class ( Foo::Bar::Exception::Senses =>
411 |  |  |  |  | { description => 'sense-related exception' },
412 |  |  |  |  |
413 |  |  |  |  | Foo::Bar::Exception::Smell =>
414 |  |  |  |  | { isa => 'Foo::Bar::Exception::Senses',
415 |  |  |  |  | fields => 'odor',
416 |  |  |  |  | description => 'stinky!' },
417 |  |  |  |  |
418 |  |  |  |  | Foo::Bar::Exception::Taste =>
419 |  |  |  |  | { isa => 'Foo::Bar::Exception::Senses',
420 |  |  |  |  | fields => [ 'taste', 'bitterness' ],
421 |  |  |  |  | description => 'like, gag me with a spoon!' },
422 |  |  |  |  |
423 |  |  |  |  | ... );
424 |  |  |  |  |
425 |  |  |  |  | You may want to create a real module to subclass
426 |  |  |  |  | L<Exception::Class::Base> as well, particularly if you want your
427 |  |  |  |  | exceptions to have more methods.
428 |  |  |  |  |
429 |  |  |  |  | =head2 Subclassing Exception::Class::Base
430 |  |  |  |  |
431 |  |  |  |  | As part of your usage of C<Exception::Class>, you may want to create
432 |  |  |  |  | your own base exception class which subclasses
433 |  |  |  |  | L<Exception::Class::Base>. You should feel free to subclass any of
434 |  |  |  |  | the methods documented above. For example, you may want to subclass
435 |  |  |  |  | C<new()> to add additional information to your exception objects.
436 |  |  |  |  |
437 |  |  |  |  | =head1 Exception::Class FUNCTIONS
438 |  |  |  |  |
439 |  |  |  |  | The C<Exception::Class> method offers one function, C<Classes()>,
440 |  |  |  |  | which is not exported. This method returns a list of the classes that
441 |  |  |  |  | have been created by calling the C<Exception::Class> import() method.
442 |  |  |  |  | Note that this is I<all> the subclasses that have been created, so it
443 |  |  |  |  | may include subclasses created by things like CPAN modules, etc. Also
444 |  |  |  |  | note that if you simply define a subclass via the normal Perl method
445 |  |  |  |  | of setting C<@ISA> or C<use base>, then your subclass will not be
446 |  |  |  |  | included.
447 |  |  |  |  |
448 |  |  |  |  | =head1 OTHER EXCEPTION MODULES (try/catch syntax)
449 |  |  |  |  |
450 |  |  |  |  | If you are interested in adding try/catch/finally syntactic sugar to
451 |  |  |  |  | your code then I recommend you check out U. Arun Kumar's C<Error.pm>
452 |  |  |  |  | module, which implements this syntax. It also includes its own base
453 |  |  |  |  | exception class, C<Error::Simple>.
454 |  |  |  |  |
455 |  |  |  |  | If you would prefer to use the L<Exception::Class::Base> class
456 |  |  |  |  | included with this module, you'll have to add this to your code
457 |  |  |  |  | somewhere:
458 |  |  |  |  |
459 |  |  |  |  | push @Exception::Class::Base::ISA, 'Error'
460 |  |  |  |  | unless Exception::Class::Base->isa('Error');
461 |  |  |  |  |
462 |  |  |  |  | It's a hack but apparently it works.
463 |  |  |  |  |
464 |  |  |  |  | =head1 SUPPORT
465 |  |  |  |  |
466 |  |  |  |  | Please submit bugs to the CPAN RT system at
467 |  |  |  |  | http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Exception%3A%3AClass or
468 |  |  |  |  | via email at bug-exception-class@rt.cpan.org.
469 |  |  |  |  |
470 |  |  |  |  | =head1 DONATIONS
471 |  |  |  |  |
472 |  |  |  |  | If you'd like to thank me for the work I've done on this module,
473 |  |  |  |  | please consider making a "donation" to me via PayPal. I spend a lot of
474 |  |  |  |  | free time creating free software, and would appreciate any support
475 |  |  |  |  | you'd care to offer.
476 |  |  |  |  |
477 |  |  |  |  | Please note that B<I am not suggesting that you must do this> in order
478 |  |  |  |  | for me to continue working on this particular software. I will
479 |  |  |  |  | continue to do so, inasmuch as I have in the past, for as long as it
480 |  |  |  |  | interests me.
481 |  |  |  |  |
482 |  |  |  |  | Similarly, a donation made in this way will probably not make me work
483 |  |  |  |  | on this software much more, unless I get so many donations that I can
484 |  |  |  |  | consider working on free software full time, which seems unlikely at
485 |  |  |  |  | best.
486 |  |  |  |  |
487 |  |  |  |  | To donate, log into PayPal and send money to autarch@urth.org or use
488 |  |  |  |  | the button on this page:
489 |  |  |  |  | L<http://www.urth.org/~autarch/fs-donation.html>
490 |  |  |  |  |
491 |  |  |  |  | =head1 AUTHOR
492 |  |  |  |  |
493 |  |  |  |  | Dave Rolsky, E<gt>autarch@urth.orgE<lt>
494 |  |  |  |  |
495 |  |  |  |  | =head1 COPYRIGHT
496 |  |  |  |  |
497 |  |  |  |  | Copyright (c) 2000-2009 David Rolsky. All rights reserved. This
498 |  |  |  |  | program is free software; you can redistribute it and/or modify it
499 |  |  |  |  | under the same terms as Perl itself.
500 |  |  |  |  |
501 |  |  |  |  | The full text of the license can be found in the LICENSE file included
502 |  |  |  |  | with this module.
503 |  |  |  |  |
504 |  |  |  |  | =cut
|  |  |  |  | # spent 18µs within Exception::Class::CORE:sort which was called 2 times, avg 9µs/call: # 2 times (18µs+0s) by Exception::Class::import at line 37 of Exception/Class.pm, avg 9µs/call sub Exception::Class::CORE:sort; # xsub
|  |  |  |  | # spent 8µs within Exception::Class::CORE:subst which was called 8 times, avg 1µs/call: # 8 times (8µs+0s) by Exception::Class::_make_subclass at line 139 of Exception/Class.pm, avg 1µs/call sub Exception::Class::CORE:subst; # xsub