Mention Sub::Import in docs
[p5sagit/Try-Tiny.git] / lib / Try / Tiny.pm
1 package Try::Tiny;
2
3 use strict;
4 #use warnings;
5
6 use vars qw(@EXPORT @EXPORT_OK $VERSION @ISA);
7
8 BEGIN {
9         require Exporter;
10         @ISA = qw(Exporter);
11 }
12
13 $VERSION = "0.02";
14
15 $VERSION = eval $VERSION;
16
17 @EXPORT = @EXPORT_OK = qw(try catch);
18
19 sub try (&;$) {
20         my ( $try, $catch ) = @_;
21
22         # we need to save this here, the eval block will be in scalar context due
23         # to $failed
24         my $wantarray = wantarray;
25
26         # save the value of $@ so we can set $@ back to it in the beginning of the eval
27         my $prev_error = $@;
28
29         my ( @ret, $error, $failed );
30
31         # FIXME consider using local $SIG{__DIE__} to accumulate all errors. It's
32         # not perfect, but we could provide a list of additional errors for
33         # $catch->();
34
35         {
36                 # localize $@ to prevent clobbering of previous value by a successful
37                 # eval.
38                 local $@;
39
40                 # failed will be true if the eval dies, because 1 will not be returned
41                 # from the eval body
42                 $failed = not eval {
43                         $@ = $prev_error;
44
45                         # evaluate the try block in the correct context
46                         if ( $wantarray ) {
47                                 @ret = $try->();
48                         } elsif ( defined $wantarray ) {
49                                 $ret[0] = $try->();
50                         } else {
51                                 $try->();
52                         };
53
54                         return 1; # properly set $fail to false
55                 };
56
57                 # copy $@ to $error; when we leave this scope, local $@ will revert $@
58                 # back to its previous value
59                 $error = $@;
60         }
61
62         # at this point $failed contains a true value if the eval died, even if some
63         # destructor overwrote $@ as the eval was unwinding.
64         if ( $failed ) {
65                 # if we got an error, invoke the catch block.
66                 if ( $catch ) {
67                         # This works like given($error), but is backwards compatible and
68                         # sets $_ in the dynamic scope for the body of C<$catch>
69                         for ($error) {
70                                 return $catch->($error);
71                         }
72
73                         # in case when() was used without an explicit return, the C<for>
74                         # loop will be aborted and there's no useful return value
75                 }
76
77                 return;
78         } else {
79                 # no failure, $@ is back to what it was, everything is fine
80                 return $wantarray ? @ret : $ret[0];
81         }
82 }
83
84 sub catch (&) {
85         return $_[0];
86 }
87
88
89 __PACKAGE__
90
91 __END__
92
93 =pod
94
95 =head1 NAME
96
97 Try::Tiny - minimal try/catch with proper localization of $@
98
99 =head1 SYNOPSIS
100
101         # handle errors with a catch handler
102         try {
103                 die "foo";
104         } catch {
105                 warn "caught error: $_";
106         };
107
108         # just silence errors
109         try {
110                 die "foo";
111         };
112
113 =head1 DESCRIPTION
114
115 This module provides bare bones C<try>/C<catch> statements that are designed to
116 minimize common mistakes with eval blocks, and NOTHING else.
117
118 This is unlike L<TryCatch> which provides a nice syntax and avoids adding
119 another call stack layer, and supports calling C<return> from the try block to
120 return from the parent subroutine. These extra features come at a cost of a few
121 dependencies, namely L<Devel::Declare> and L<Scope::Upper> which are
122 occasionally problematic, and the additional catch filtering uses L<Moose>
123 type constraints which may not be desirable either.
124
125 The main focus of this module is to provide simple and reliable error handling
126 for those having a hard time installing L<TryCatch>, but who still want to
127 write correct C<eval> blocks without 5 lines of boilerplate each time.
128
129 It's designed to work as correctly as possible in light of the various
130 pathological edge cases (see L<BACKGROUND>) and to be compatible with any style
131 of error values (simple strings, references, objects, overloaded objects, etc).
132
133 =head1 EXPORTS
134
135 All functions are exported by default using L<Exporter>.
136
137 If you need to rename the C<try> or C<catch> keyword consider using
138 L<Sub::Import> to get L<Sub::Exporter>'s flexibility.
139
140 =over 4
141
142 =item try (&;$)
143
144 Takes one mandatory try subroutine and one optional catch subroutine.
145
146 The mandatory subroutine is evaluated in the context of an C<eval> block.
147
148 If no error occurred the value from the first block is returned, preserving
149 list/scalar context.
150
151 If there was an error and the second subroutine was given it will be invoked
152 with the error in C<$_> (localized) and as that block's first and only
153 argument.
154
155 Note that the error may be false, but if that happens the C<catch> block will
156 still be invoked.
157
158 =item catch (&)
159
160 Intended to be used in the second argument position of C<try>.
161
162 Just returns the subroutine it was given.
163
164         catch { ... }
165
166 is the same as
167
168         sub { ... }
169
170 Inside the catch block the previous value of C<$@> is still available for use.
171 This value may or may not be meaningful depending on what happened before the
172 C<try>, but it might be a good idea to preserve it in an error stack.
173
174 =back
175
176 =head1 BACKGROUND
177
178 There are a number of issues with C<eval>.
179
180 =head2 Clobbering $@
181
182 When you run an eval block and it succeeds, C<$@> will be cleared, potentially
183 clobbering an error that is currently being caught.
184
185 This causes action at a distance, clearing previous errors your caller may have
186 not yet handled.
187
188 C<$@> must be properly localized before invoking C<eval> in order to avoid this
189 issue.
190
191 More specifically, C<$@> is clobbered at the begining of the C<eval>, which
192 also makes it impossible to capture the previous error before you die (for
193 instance when making exception objects with error stacks).
194
195 For this reason C<try> will actually set C<$@> to its previous value (before
196 the localization) in the beginning of the C<eval> block.
197
198 =head2 Localizing $@ silently masks errors
199
200 Inside an eval block C<die> behaves sort of like:
201
202         sub die {
203                 $@ = $_[0];
204                 return_undef_from_eval();
205         }
206
207 This means that if you were polite and localized C<$@> you can't die in that
208 scope, or your error will be discarded (printing "Something's wrong" instead).
209
210 The workaround is very ugly:
211
212         my $error = do {
213                 local $@;
214                 eval { ... };
215                 $@;
216         };
217
218         ...
219         die $error;
220
221 =head2 $@ might not be a true value
222
223 This code is wrong:
224
225         if ( $@ ) {
226                 ...
227         }
228
229 because due to the previous caveats it may have been unset.
230
231 C<$@> could also be an overloaded error object that evaluates to false, but
232 that's asking for trouble anyway.
233
234 The classic failure mode is:
235
236         sub Object::DESTROY {
237                 eval { ... }
238         }
239
240         eval {
241                 my $obj = Object->new;
242
243                 die "foo";
244         };
245
246         if ( $@ ) {
247
248         }
249
250 In this case since C<Object::DESTROY> is not localizing C<$@> but still uses
251 C<eval>, it will set C<$@> to C<"">.
252
253 The destructor is called when the stack is unwound, after C<die> sets C<$@> to
254 C<"foo at Foo.pm line 42\n">, so by the time C<if ( $@ )> is evaluated it has
255 been cleared by C<eval> in the destructor.
256
257 The workaround for this is even uglier than the previous ones. Even though we
258 can't save the value of C<$@> from code that doesn't localize, we can at least
259 be sure the eval was aborted due to an error:
260
261         my $failed = not eval {
262                 ...
263
264                 return 1;
265         };
266
267 This is because an C<eval> that caught a C<die> will always return a false
268 value.
269
270 =head1 SHINY SYNTAX
271
272 Using Perl 5.10 you can use L<perlsyn/"Switch statements">.
273
274 The C<catch> block is invoked in a topicalizer context (like a C<given> block),
275 but note that you can't return a useful value from C<catch> using the C<when>
276 blocks without an explicit C<return>.
277
278 This is somewhat similar to Perl 6's C<CATCH> blocks. You can use it to
279 concisely match errors:
280
281         try {
282                 require Foo;
283         } catch {
284                 when (/^Can't locate .*?\.pm in \@INC/) { } # ignore
285                 default { die $_ }
286         };
287
288 =head1 CAVEATS
289
290 =over 4
291
292 =item *
293
294 C<try> introduces another caller stack frame. L<Sub::Uplevel> is not used. L<Carp>
295 will report this when using full stack traces. This lack of magic is considered
296 a feature.
297
298 =item *
299
300 The value of C<$_> in the C<catch> block is not guaranteed to be preserved,
301 there is no safe way to ensure this if C<eval> is used unhygenically in
302 destructors. It's only guaranteed that the C<catch> will be called.
303
304 =back
305
306 =head1 SEE ALSO
307
308 =over 4
309
310 =item L<TryCatch>
311
312 Much more feature complete, more convenient semantics, but at the cost of
313 implementation complexity.
314
315 =item L<autodie>
316
317 Automatic error throwing for builtin functions and more. Also designed to
318 work well with C<given>/C<when>.
319
320 =item L<Throwable>
321
322 A lightweight role for rolling your own exception classes.
323
324 =item L<Error>
325
326 Exception object implementation with a C<try> statement. Does not localize
327 C<$@>.
328
329 =item L<Exception::Class::TryCatch>
330
331 Provides a C<catch> statement, but properly calling C<eval> is your
332 responsibility.
333
334 The C<try> keyword pushes C<$@> onto an error stack, avoiding some of the
335 issues with C<$@>, but you still need to localize to prevent clobbering.
336
337 =back
338
339 =head1 LIGHTNING TALK
340
341 I gave a lightning talk about this module, you can see the slides (Firefox
342 only):
343
344 L<http://nothingmuch.woobling.org/talks/takahashi.xul?data=try_tiny.txt>
345
346 Or read the source:
347
348 L<http://nothingmuch.woobling.org/talks/yapc_asia_2009/try_tiny.yml>
349
350 =head1 VERSION CONTROL
351
352 L<http://github.com/nothingmuch/try-tiny/>
353
354 =head1 AUTHOR
355
356 Yuval Kogman E<lt>nothingmuch@woobling.orgE<gt>
357
358 =head1 COPYRIGHT
359
360         Copyright (c) 2009 Yuval Kogman. All rights reserved.
361         This program is free software; you can redistribute
362         it and/or modify it under the terms of the MIT license.
363
364 =cut
365