Add built local::lib
[catagits/Gitalist.git] / local-lib5 / lib / perl5 / 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         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                         }
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
71                 }
72
73                 return;
74         } else {
75                 # no failure, $@ is back to what it was, everything is fine
76                 return $wantarray ? @ret : $ret[0];
77         }
78 }
79
80 sub catch (&) {
81         return $_[0];
82 }
83
84
85 __PACKAGE__
86
87 __END__
88
89 =pod
90
91 =head1 NAME
92
93 Try::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
111 This module provides bare bones C<try>/C<catch> statements that are designed to
112 minimize common mistakes with eval blocks, and NOTHING else.
113
114 This is unlike L<TryCatch> which provides a nice syntax and avoids adding
115 another call stack layer, and supports calling C<return> from the try block to
116 return from the parent subroutine. These extra features come at a cost of a few
117 dependencies, namely L<Devel::Declare> and L<Scope::Upper> which are
118 occasionally problematic, and the additional catch filtering uses L<Moose>
119 type constraints which may not be desirable either.
120
121 The main focus of this module is to provide simple and reliable error handling
122 for those having a hard time installing L<TryCatch>, but who still want to
123 write correct C<eval> blocks without 5 lines of boilerplate each time.
124
125 It's designed to work as correctly as possible in light of the various
126 pathological edge cases (see L<BACKGROUND>) and to be compatible with any style
127 of error values (simple strings, references, objects, overloaded objects, etc).
128
129 =head1 EXPORTS
130
131 All functions are exported by default using L<Exporter>.
132
133 In the future L<Sub::Exporter> may be used to allow the keywords to be renamed,
134 but this technically does not satisfy Adam Kennedy's definition of "Tiny".
135
136 =over 4
137
138 =item try (&;$)
139
140 Takes one mandatory try subroutine and one optional catch subroutine.
141
142 The mandatory subroutine is evaluated in the context of an C<eval> block.
143
144 If no error occurred the value from the first block is returned, preserving
145 list/scalar context.
146
147 If there was an error and the second subroutine was given it will be invoked
148 with the error in C<$_> (localized) and as that block's first and only
149 argument.
150
151 Note that the error may be false, but if that happens the C<catch> block will
152 still be invoked..
153
154 =item catch (&)
155
156 Intended to be used in the second argument position of C<try>.
157
158 Just returns the subroutine it was given.
159
160         catch { ... }
161
162 is the same as
163
164         sub { ... }
165
166 =back
167
168 =head1 BACKGROUND
169
170 There are a number of issues with C<eval>.
171
172 =head2 Clobbering $@
173
174 When you run an eval block and it succeeds, C<$@> will be cleared, potentially
175 clobbering an error that is currently being caught.
176
177 This causes action at a distance, clearing previous errors your caller may have
178 not yet handled.
179
180 C<$@> must be properly localized before invoking C<eval> in order to avoid this
181 issue.
182
183 =head2 Localizing $@ silently masks errors
184
185 Inside an eval block C<die> behaves sort of like:
186
187         sub die {
188                 $@_ = $_[0];
189                 return_undef_from_eval();
190         }
191
192 This means that if you were polite and localized C<$@> you can't die in that
193 scope, or your error will be discarded (printing "Something's wrong" instead).
194
195 The 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
208 This code is wrong:
209
210         if ( $@ ) {
211                 ...
212         }
213
214 because due to the previous caveats it may have been unset.
215
216 C<$@> could also an overloaded error object that evaluates to false, but that's
217 asking for trouble anyway.
218
219 The 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
235 In this case since C<Object::DESTROY> is not localizing C<$@> but still uses
236 C<eval> it will set C<$@> to C<"">.
237
238 The destructor is called when the stack is unwound, after C<die> sets C<$@> to
239 C<"foo at Foo.pm line 42\n">, so by the time C<if ( $@ )> is evaluated it has
240 been cleared by C<eval> in the destructor.
241
242 The workaround for this is even uglier than the previous ones. Even though we
243 can't save the value of C<$@> from code that doesn't localize, we can at least
244 be sure the eval was aborted due to an error:
245
246         my $failed = not eval {
247                 ...
248
249                 return 1;
250         };
251
252 This is because an C<eval> that caught a C<die> will always return a false
253 value.
254
255 =head1 SHINY SYNTAX
256
257 Using Perl 5.10 you can use L<perlsyn/"Switch statements">.
258
259 The C<catch> block is invoked in a topicalizer context (like a C<given> block),
260 but note that you can't return a useful value from C<catch> using the C<when>
261 blocks without an explicit C<return>.
262
263 This is somewhat similar to Perl 6's C<CATCH> blocks. You can use it to
264 concisely match errors:
265
266         try {
267                 require Foo;
268         } catch {
269                 when (/^Can't locate .*?\.pm in \@INC/) { } # ignore
270                 default { die $_ }
271         };
272
273 =head1 CAVEATS
274
275 =over 4
276
277 =item *
278
279 C<try> introduces another caller stack frame. L<Sub::Uplevel> is not used. L<Carp>
280 will report this when using full stack traces. This lack of magic is considered
281 a feature.
282
283 =item *
284
285 The value of C<$_> in the C<catch> block is not guaranteed to be preserved,
286 there is no safe way to ensure this if C<eval> is used unhygenically in
287 destructors. It's only guaranteeed that the C<catch> will be called.
288
289 =back
290
291 =head1 SEE ALSO
292
293 =over 4
294
295 =item L<TryCatch>
296
297 Much more feature complete, more convenient semantics, but at the cost of
298 implementation complexity.
299
300 =item L<autodie>
301
302 Automatic error throwing for builtin functions and more. Also designed to
303 work well with C<given>/C<when>.
304
305 =item L<Throwable>
306
307 A lightweight role for rolling your own exception classes.
308
309 =item L<Error>
310
311 Exception object implementation with a C<try> statement. Does not localize
312 C<$@>.
313
314 =item L<Exception::Class::TryCatch>
315
316 Provides a C<catch> statement, but properly calling C<eval> is your
317 responsibility.
318
319 The C<try> keyword pushes C<$@> onto an error stack, avoiding some of the
320 issues with C<$@> but you still need to localize to prevent clobbering.
321
322 =back
323
324 =head1 VERSION CONTROL
325
326 L<http://github.com/nothingmuch/try-tiny/>
327
328 =head1 AUTHOR
329
330 Yuval Kogman E<lt>nothingmuch@woobling.orgE<gt>
331
332 =head1 COPYRIGHT
333
334         Copyright (c) 2009 Yuval Kogman. All rights reserved.
335         This program is free software; you can redistribute
336         it and/or modify it under the terms of the MIT license.
337
338 =cut
339