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