| File | /usr/local/share/perl/5.10.0/Try/Tiny.pm |
| Statements Executed | 6702 |
| Total Time | 0.00810619999999977 seconds |
| Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
|---|---|---|---|---|---|
| 304 | 3 | 3 | 5.97ms | 114ms | Try::Tiny::try |
| 304 | 3 | 3 | 2.06ms | 2.06ms | Try::Tiny::catch |
| 0 | 0 | 0 | 0s | 0s | Try::Tiny::BEGIN |
| 0 | 0 | 0 | 0s | 0s | Try::Tiny::ScopeGuard::DESTROY |
| 0 | 0 | 0 | 0s | 0s | Try::Tiny::ScopeGuard::_new |
| 0 | 0 | 0 | 0s | 0s | Try::Tiny::finally |
| Line | Stmts. | Exclusive Time | Avg. | Code |
|---|---|---|---|---|
| 1 | package Try::Tiny; | |||
| 2 | ||||
| 3 | 3 | 30µs | 10µs | use strict; # spent 9µs making 1 call to strict::import |
| 4 | #use warnings; | |||
| 5 | ||||
| 6 | 3 | 44µs | 15µs | use vars qw(@EXPORT @EXPORT_OK $VERSION @ISA); # spent 70µs making 1 call to vars::import |
| 7 | ||||
| 8 | BEGIN { | |||
| 9 | 2 | 12µs | 6µs | require Exporter; |
| 10 | @ISA = qw(Exporter); | |||
| 11 | 1 | 131µs | 131µs | } |
| 12 | ||||
| 13 | 1 | 800ns | 800ns | $VERSION = "0.07"; |
| 14 | ||||
| 15 | 1 | 20µs | 20µs | $VERSION = eval $VERSION; |
| 16 | ||||
| 17 | 1 | 3µs | 3µs | @EXPORT = @EXPORT_OK = qw(try catch finally); |
| 18 | ||||
| 19 | 1 | 4µs | 4µs | $Carp::Internal{+__PACKAGE__}++; |
| 20 | ||||
| 21 | # Need to prototype as @ not $$ because of the way Perl evaluates the prototype. | |||
| 22 | # Keeping it at $$ means you only ever get 1 sub because we need to eval in a list | |||
| 23 | # context & not a scalar one | |||
| 24 | ||||
| 25 | # spent 114ms (5.97+108) within Try::Tiny::try which was called 304 times, avg 375µs/call:
# 177 times (3.58ms+24.8ms) by Class::MOP::Attribute::_process_accessors or Class::MOP::Attribute::__ANON__[/usr/local/lib/perl/5.10.0/Class/MOP/Attribute.pm:345] at line 345 of /usr/local/lib/perl/5.10.0/Class/MOP/Attribute.pm, avg 160µs/call
# 123 times (2.29ms+58.0ms) by Class::MOP::Class::_post_add_attribute or Class::MOP::Class::__ANON__[/usr/local/lib/perl/5.10.0/Class/MOP/Class.pm:772] at line 772 of /usr/local/lib/perl/5.10.0/Class/MOP/Class.pm, avg 490µs/call
# 4 times (105µs+25.4ms) by Class::MOP::load_first_existing_class or Class::MOP::__ANON__[/usr/local/lib/perl/5.10.0/Class/MOP.pm:124] at line 124 of /usr/local/lib/perl/5.10.0/Class/MOP.pm, avg 6.36ms/call | |||
| 26 | 6076 | 6.20ms | 1µs | my ( $try, @code_refs ) = @_; |
| 27 | ||||
| 28 | # we need to save this here, the eval block will be in scalar context due | |||
| 29 | # to $failed | |||
| 30 | my $wantarray = wantarray; | |||
| 31 | ||||
| 32 | my ( $catch, @finally ); | |||
| 33 | ||||
| 34 | # find labeled blocks in the argument list. | |||
| 35 | # catch and finally tag the blocks by blessing a scalar reference to them. | |||
| 36 | foreach my $code_ref (@code_refs) { | |||
| 37 | next unless $code_ref; | |||
| 38 | ||||
| 39 | my $ref = ref($code_ref); | |||
| 40 | ||||
| 41 | if ( $ref eq 'Try::Tiny::Catch' ) { | |||
| 42 | $catch = ${$code_ref}; | |||
| 43 | } elsif ( $ref eq 'Try::Tiny::Finally' ) { | |||
| 44 | push @finally, ${$code_ref}; | |||
| 45 | } else { | |||
| 46 | 3 | 402µs | 134µs | use Carp; # spent 51µs making 1 call to Exporter::import |
| 47 | confess("Unknown code ref type given '${ref}'. Check your usage & try again"); | |||
| 48 | } | |||
| 49 | } | |||
| 50 | ||||
| 51 | # save the value of $@ so we can set $@ back to it in the beginning of the eval | |||
| 52 | my $prev_error = $@; | |||
| 53 | ||||
| 54 | my ( @ret, $error, $failed ); | |||
| 55 | ||||
| 56 | # FIXME consider using local $SIG{__DIE__} to accumulate all errors. It's | |||
| 57 | # not perfect, but we could provide a list of additional errors for | |||
| 58 | # $catch->(); | |||
| 59 | ||||
| 60 | { | |||
| 61 | # localize $@ to prevent clobbering of previous value by a successful | |||
| 62 | # eval. | |||
| 63 | local $@; | |||
| 64 | ||||
| 65 | # failed will be true if the eval dies, because 1 will not be returned | |||
| 66 | # from the eval body | |||
| 67 | $failed = not eval { | |||
| 68 | $@ = $prev_error; | |||
| 69 | ||||
| 70 | # evaluate the try block in the correct context | |||
| 71 | if ( $wantarray ) { # spent 25.4ms making 4 calls to Class::MOP::__ANON__[/usr/local/lib/perl/5.10.0/Class/MOP.pm:117], avg 6.34ms/call | |||
| 72 | @ret = $try->(); | |||
| 73 | } elsif ( defined $wantarray ) { | |||
| 74 | $ret[0] = $try->(); | |||
| 75 | } else { | |||
| 76 | $try->(); # spent 59.5ms making 123 calls to Class::MOP::Class::__ANON__[/usr/local/lib/perl/5.10.0/Class/MOP/Class.pm:768], avg 484µs/call
# spent 48.8ms making 177 calls to Class::MOP::Attribute::__ANON__[/usr/local/lib/perl/5.10.0/Class/MOP/Attribute.pm:342], avg 276µs/call | |||
| 77 | }; | |||
| 78 | ||||
| 79 | return 1; # properly set $fail to false | |||
| 80 | }; | |||
| 81 | ||||
| 82 | # copy $@ to $error; when we leave this scope, local $@ will revert $@ | |||
| 83 | # back to its previous value | |||
| 84 | $error = $@; | |||
| 85 | } | |||
| 86 | ||||
| 87 | # set up a scope guard to invoke the finally block at the end | |||
| 88 | my @guards = | |||
| 89 | map { Try::Tiny::ScopeGuard->_new($_, $failed ? $error : ()) } | |||
| 90 | @finally; | |||
| 91 | ||||
| 92 | # at this point $failed contains a true value if the eval died, even if some | |||
| 93 | # destructor overwrote $@ as the eval was unwinding. | |||
| 94 | if ( $failed ) { | |||
| 95 | # if we got an error, invoke the catch block. | |||
| 96 | if ( $catch ) { | |||
| 97 | # This works like given($error), but is backwards compatible and | |||
| 98 | # sets $_ in the dynamic scope for the body of C<$catch> | |||
| 99 | for ($error) { | |||
| 100 | return $catch->($error); | |||
| 101 | } | |||
| 102 | ||||
| 103 | # in case when() was used without an explicit return, the C<for> | |||
| 104 | # loop will be aborted and there's no useful return value | |||
| 105 | } | |||
| 106 | ||||
| 107 | return; | |||
| 108 | } else { | |||
| 109 | # no failure, $@ is back to what it was, everything is fine | |||
| 110 | return $wantarray ? @ret : $ret[0]; | |||
| 111 | } | |||
| 112 | } | |||
| 113 | ||||
| 114 | # spent 2.06ms within Try::Tiny::catch which was called 304 times, avg 7µs/call:
# 177 times (1.16ms+0s) by Class::MOP::Attribute::_process_accessors or Class::MOP::Attribute::__ANON__[/usr/local/lib/perl/5.10.0/Class/MOP/Attribute.pm:345] at line 345 of /usr/local/lib/perl/5.10.0/Class/MOP/Attribute.pm, avg 7µs/call
# 123 times (865µs+0s) by Class::MOP::Class::_post_add_attribute or Class::MOP::Class::__ANON__[/usr/local/lib/perl/5.10.0/Class/MOP/Class.pm:772] at line 772 of /usr/local/lib/perl/5.10.0/Class/MOP/Class.pm, avg 7µs/call
# 4 times (40µs+0s) by Class::MOP::load_first_existing_class or Class::MOP::__ANON__[/usr/local/lib/perl/5.10.0/Class/MOP.pm:124] at line 124 of /usr/local/lib/perl/5.10.0/Class/MOP.pm, avg 10µs/call | |||
| 115 | 608 | 1.25ms | 2µs | my ( $block, @rest ) = @_; |
| 116 | ||||
| 117 | return ( | |||
| 118 | bless(\$block, 'Try::Tiny::Catch'), | |||
| 119 | @rest, | |||
| 120 | ); | |||
| 121 | } | |||
| 122 | ||||
| 123 | sub finally (&;@) { | |||
| 124 | my ( $block, @rest ) = @_; | |||
| 125 | ||||
| 126 | return ( | |||
| 127 | bless(\$block, 'Try::Tiny::Finally'), | |||
| 128 | @rest, | |||
| 129 | ); | |||
| 130 | } | |||
| 131 | ||||
| 132 | { | |||
| 133 | 1 | 900ns | 900ns | package Try::Tiny::ScopeGuard; |
| 134 | ||||
| 135 | sub _new { | |||
| 136 | shift; | |||
| 137 | bless [ @_ ]; | |||
| 138 | } | |||
| 139 | ||||
| 140 | sub DESTROY { | |||
| 141 | my @guts = @{ shift() }; | |||
| 142 | my $code = shift @guts; | |||
| 143 | $code->(@guts); | |||
| 144 | } | |||
| 145 | } | |||
| 146 | ||||
| 147 | __PACKAGE__ | |||
| 148 | ||||
| 149 | 1 | 10µs | 10µs | __END__ |
| 150 | ||||
| 151 | =pod | |||
| 152 | ||||
| 153 | =head1 NAME | |||
| 154 | ||||
| 155 | Try::Tiny - minimal try/catch with proper localization of $@ | |||
| 156 | ||||
| 157 | =head1 SYNOPSIS | |||
| 158 | ||||
| 159 | # handle errors with a catch handler | |||
| 160 | try { | |||
| 161 | die "foo"; | |||
| 162 | } catch { | |||
| 163 | warn "caught error: $_"; # not $@ | |||
| 164 | }; | |||
| 165 | ||||
| 166 | # just silence errors | |||
| 167 | try { | |||
| 168 | die "foo"; | |||
| 169 | }; | |||
| 170 | ||||
| 171 | =head1 DESCRIPTION | |||
| 172 | ||||
| 173 | This module provides bare bones C<try>/C<catch>/C<finally> statements that are designed to | |||
| 174 | minimize common mistakes with eval blocks, and NOTHING else. | |||
| 175 | ||||
| 176 | This is unlike L<TryCatch> which provides a nice syntax and avoids adding | |||
| 177 | another call stack layer, and supports calling C<return> from the try block to | |||
| 178 | return from the parent subroutine. These extra features come at a cost of a few | |||
| 179 | dependencies, namely L<Devel::Declare> and L<Scope::Upper> which are | |||
| 180 | occasionally problematic, and the additional catch filtering uses L<Moose> | |||
| 181 | type constraints which may not be desirable either. | |||
| 182 | ||||
| 183 | The main focus of this module is to provide simple and reliable error handling | |||
| 184 | for those having a hard time installing L<TryCatch>, but who still want to | |||
| 185 | write correct C<eval> blocks without 5 lines of boilerplate each time. | |||
| 186 | ||||
| 187 | It's designed to work as correctly as possible in light of the various | |||
| 188 | pathological edge cases (see L<BACKGROUND>) and to be compatible with any style | |||
| 189 | of error values (simple strings, references, objects, overloaded objects, etc). | |||
| 190 | ||||
| 191 | If the try block dies, it returns the value of the last statement executed in | |||
| 192 | the catch block, if there is one. Otherwise, it returns C<undef> in scalar | |||
| 193 | context or the empty list in list context. The following two examples both | |||
| 194 | assign C<"bar"> to C<$x>. | |||
| 195 | ||||
| 196 | my $x = try { die "foo" } catch { "bar" }; | |||
| 197 | ||||
| 198 | my $x = eval { die "foo" } || "bar"; | |||
| 199 | ||||
| 200 | You can add finally blocks making the following true. | |||
| 201 | ||||
| 202 | my $x; | |||
| 203 | try { die 'foo' } finally { $x = 'bar' }; | |||
| 204 | try { die 'foo' } catch { warn "Got a die: $_" } finally { $x = 'bar' }; | |||
| 205 | ||||
| 206 | Finally blocks are always executed making them suitable for cleanup code | |||
| 207 | which cannot be handled using local. You can add as many finally blocks to a | |||
| 208 | given try block as you like. | |||
| 209 | ||||
| 210 | =head1 EXPORTS | |||
| 211 | ||||
| 212 | All functions are exported by default using L<Exporter>. | |||
| 213 | ||||
| 214 | If you need to rename the C<try>, C<catch> or C<finally> keyword consider using | |||
| 215 | L<Sub::Import> to get L<Sub::Exporter>'s flexibility. | |||
| 216 | ||||
| 217 | =over 4 | |||
| 218 | ||||
| 219 | =item try (&;@) | |||
| 220 | ||||
| 221 | Takes one mandatory try subroutine, an optional catch subroutine & finally | |||
| 222 | subroutine. | |||
| 223 | ||||
| 224 | The mandatory subroutine is evaluated in the context of an C<eval> block. | |||
| 225 | ||||
| 226 | If no error occurred the value from the first block is returned, preserving | |||
| 227 | list/scalar context. | |||
| 228 | ||||
| 229 | If there was an error and the second subroutine was given it will be invoked | |||
| 230 | with the error in C<$_> (localized) and as that block's first and only | |||
| 231 | argument. | |||
| 232 | ||||
| 233 | C<$@> does B<not> contain the error. Inside the C<catch> block it has the same | |||
| 234 | value it had before the C<try> block was executed. | |||
| 235 | ||||
| 236 | Note that the error may be false, but if that happens the C<catch> block will | |||
| 237 | still be invoked. | |||
| 238 | ||||
| 239 | Once all execution is finished then the finally block if given will execute. | |||
| 240 | ||||
| 241 | =item catch (&;$) | |||
| 242 | ||||
| 243 | Intended to be used in the second argument position of C<try>. | |||
| 244 | ||||
| 245 | Returns a reference to the subroutine it was given but blessed as | |||
| 246 | C<Try::Tiny::Catch> which allows try to decode correctly what to do | |||
| 247 | with this code reference. | |||
| 248 | ||||
| 249 | catch { ... } | |||
| 250 | ||||
| 251 | Inside the catch block the caught error is stored in C<$_>, while previous | |||
| 252 | value of C<$@> is still available for use. This value may or may not be | |||
| 253 | meaningful depending on what happened before the C<try>, but it might be a good | |||
| 254 | idea to preserve it in an error stack. | |||
| 255 | ||||
| 256 | For code that captures C<$@> when throwing new errors (i.e. | |||
| 257 | L<Class::Throwable>), you'll need to do: | |||
| 258 | ||||
| 259 | local $@ = $_; | |||
| 260 | ||||
| 261 | =item finally (&;$) | |||
| 262 | ||||
| 263 | try { ... } | |||
| 264 | catch { ... } | |||
| 265 | finally { ... }; | |||
| 266 | ||||
| 267 | Or | |||
| 268 | ||||
| 269 | try { ... } | |||
| 270 | finally { ... }; | |||
| 271 | ||||
| 272 | Or even | |||
| 273 | ||||
| 274 | try { ... } | |||
| 275 | finally { ... } | |||
| 276 | catch { ... }; | |||
| 277 | ||||
| 278 | Intended to be the second or third element of C<try>. Finally blocks are always | |||
| 279 | executed in the event of a successful C<try> or if C<catch> is run. This allows | |||
| 280 | you to locate cleanup code which cannot be done via C<local()> e.g. closing a file | |||
| 281 | handle. | |||
| 282 | ||||
| 283 | When invoked, the finally block is passed the error that was caught. If no | |||
| 284 | error was caught, it is passed nothing. In other words, the following code | |||
| 285 | does just what you would expect: | |||
| 286 | ||||
| 287 | try { | |||
| 288 | die_sometimes(); | |||
| 289 | } catch { | |||
| 290 | # ...code run in case of error | |||
| 291 | } finally { | |||
| 292 | if (@_) { | |||
| 293 | print "The try block died with: @_\n"; | |||
| 294 | } else { | |||
| 295 | print "The try block ran without error.\n"; | |||
| 296 | } | |||
| 297 | }; | |||
| 298 | ||||
| 299 | B<You must always do your own error handling in the finally block>. C<Try::Tiny> will | |||
| 300 | not do anything about handling possible errors coming from code located in these | |||
| 301 | blocks. | |||
| 302 | ||||
| 303 | In the same way C<catch()> blesses the code reference this subroutine does the same | |||
| 304 | except it bless them as C<Try::Tiny::Finally>. | |||
| 305 | ||||
| 306 | =back | |||
| 307 | ||||
| 308 | =head1 BACKGROUND | |||
| 309 | ||||
| 310 | There are a number of issues with C<eval>. | |||
| 311 | ||||
| 312 | =head2 Clobbering $@ | |||
| 313 | ||||
| 314 | When you run an eval block and it succeeds, C<$@> will be cleared, potentially | |||
| 315 | clobbering an error that is currently being caught. | |||
| 316 | ||||
| 317 | This causes action at a distance, clearing previous errors your caller may have | |||
| 318 | not yet handled. | |||
| 319 | ||||
| 320 | C<$@> must be properly localized before invoking C<eval> in order to avoid this | |||
| 321 | issue. | |||
| 322 | ||||
| 323 | More specifically, C<$@> is clobbered at the beginning of the C<eval>, which | |||
| 324 | also makes it impossible to capture the previous error before you die (for | |||
| 325 | instance when making exception objects with error stacks). | |||
| 326 | ||||
| 327 | For this reason C<try> will actually set C<$@> to its previous value (before | |||
| 328 | the localization) in the beginning of the C<eval> block. | |||
| 329 | ||||
| 330 | =head2 Localizing $@ silently masks errors | |||
| 331 | ||||
| 332 | Inside an eval block C<die> behaves sort of like: | |||
| 333 | ||||
| 334 | sub die { | |||
| 335 | $@ = $_[0]; | |||
| 336 | return_undef_from_eval(); | |||
| 337 | } | |||
| 338 | ||||
| 339 | This means that if you were polite and localized C<$@> you can't die in that | |||
| 340 | scope, or your error will be discarded (printing "Something's wrong" instead). | |||
| 341 | ||||
| 342 | The workaround is very ugly: | |||
| 343 | ||||
| 344 | my $error = do { | |||
| 345 | local $@; | |||
| 346 | eval { ... }; | |||
| 347 | $@; | |||
| 348 | }; | |||
| 349 | ||||
| 350 | ... | |||
| 351 | die $error; | |||
| 352 | ||||
| 353 | =head2 $@ might not be a true value | |||
| 354 | ||||
| 355 | This code is wrong: | |||
| 356 | ||||
| 357 | if ( $@ ) { | |||
| 358 | ... | |||
| 359 | } | |||
| 360 | ||||
| 361 | because due to the previous caveats it may have been unset. | |||
| 362 | ||||
| 363 | C<$@> could also be an overloaded error object that evaluates to false, but | |||
| 364 | that's asking for trouble anyway. | |||
| 365 | ||||
| 366 | The classic failure mode is: | |||
| 367 | ||||
| 368 | sub Object::DESTROY { | |||
| 369 | eval { ... } | |||
| 370 | } | |||
| 371 | ||||
| 372 | eval { | |||
| 373 | my $obj = Object->new; | |||
| 374 | ||||
| 375 | die "foo"; | |||
| 376 | }; | |||
| 377 | ||||
| 378 | if ( $@ ) { | |||
| 379 | ||||
| 380 | } | |||
| 381 | ||||
| 382 | In this case since C<Object::DESTROY> is not localizing C<$@> but still uses | |||
| 383 | C<eval>, it will set C<$@> to C<"">. | |||
| 384 | ||||
| 385 | The destructor is called when the stack is unwound, after C<die> sets C<$@> to | |||
| 386 | C<"foo at Foo.pm line 42\n">, so by the time C<if ( $@ )> is evaluated it has | |||
| 387 | been cleared by C<eval> in the destructor. | |||
| 388 | ||||
| 389 | The workaround for this is even uglier than the previous ones. Even though we | |||
| 390 | can't save the value of C<$@> from code that doesn't localize, we can at least | |||
| 391 | be sure the eval was aborted due to an error: | |||
| 392 | ||||
| 393 | my $failed = not eval { | |||
| 394 | ... | |||
| 395 | ||||
| 396 | return 1; | |||
| 397 | }; | |||
| 398 | ||||
| 399 | This is because an C<eval> that caught a C<die> will always return a false | |||
| 400 | value. | |||
| 401 | ||||
| 402 | =head1 SHINY SYNTAX | |||
| 403 | ||||
| 404 | Using Perl 5.10 you can use L<perlsyn/"Switch statements">. | |||
| 405 | ||||
| 406 | The C<catch> block is invoked in a topicalizer context (like a C<given> block), | |||
| 407 | but note that you can't return a useful value from C<catch> using the C<when> | |||
| 408 | blocks without an explicit C<return>. | |||
| 409 | ||||
| 410 | This is somewhat similar to Perl 6's C<CATCH> blocks. You can use it to | |||
| 411 | concisely match errors: | |||
| 412 | ||||
| 413 | try { | |||
| 414 | require Foo; | |||
| 415 | } catch { | |||
| 416 | when (/^Can't locate .*?\.pm in \@INC/) { } # ignore | |||
| 417 | default { die $_ } | |||
| 418 | }; | |||
| 419 | ||||
| 420 | =head1 CAVEATS | |||
| 421 | ||||
| 422 | =over 4 | |||
| 423 | ||||
| 424 | =item * | |||
| 425 | ||||
| 426 | C<@_> is not available within the C<try> block, so you need to copy your | |||
| 427 | arglist. In case you want to work with argument values directly via C<@_> | |||
| 428 | aliasing (i.e. allow C<$_[1] = "foo">), you need to pass C<@_> by reference: | |||
| 429 | ||||
| 430 | sub foo { | |||
| 431 | my ( $self, @args ) = @_; | |||
| 432 | try { $self->bar(@args) } | |||
| 433 | } | |||
| 434 | ||||
| 435 | or | |||
| 436 | ||||
| 437 | sub bar_in_place { | |||
| 438 | my $self = shift; | |||
| 439 | my $args = \@_; | |||
| 440 | try { $_ = $self->bar($_) for @$args } | |||
| 441 | } | |||
| 442 | ||||
| 443 | =item * | |||
| 444 | ||||
| 445 | C<return> returns from the C<try> block, not from the parent sub (note that | |||
| 446 | this is also how C<eval> works, but not how L<TryCatch> works): | |||
| 447 | ||||
| 448 | sub bar { | |||
| 449 | try { return "foo" }; | |||
| 450 | return "baz"; | |||
| 451 | } | |||
| 452 | ||||
| 453 | say bar(); # "baz" | |||
| 454 | ||||
| 455 | =item * | |||
| 456 | ||||
| 457 | C<try> introduces another caller stack frame. L<Sub::Uplevel> is not used. L<Carp> | |||
| 458 | will not report this when using full stack traces, though, because | |||
| 459 | C<%Carp::Internal> is used. This lack of magic is considered a feature. | |||
| 460 | ||||
| 461 | =item * | |||
| 462 | ||||
| 463 | The value of C<$_> in the C<catch> block is not guaranteed to be the value of | |||
| 464 | the exception thrown (C<$@>) in the C<try> block. There is no safe way to | |||
| 465 | ensure this, since C<eval> may be used unhygenically in destructors. The only | |||
| 466 | guarantee is that the C<catch> will be called if an exception is thrown. | |||
| 467 | ||||
| 468 | =item * | |||
| 469 | ||||
| 470 | The return value of the C<catch> block is not ignored, so if testing the result | |||
| 471 | of the expression for truth on success, be sure to return a false value from | |||
| 472 | the C<catch> block: | |||
| 473 | ||||
| 474 | my $obj = try { | |||
| 475 | MightFail->new; | |||
| 476 | } catch { | |||
| 477 | ... | |||
| 478 | ||||
| 479 | return; # avoid returning a true value; | |||
| 480 | }; | |||
| 481 | ||||
| 482 | return unless $obj; | |||
| 483 | ||||
| 484 | =item * | |||
| 485 | ||||
| 486 | C<$SIG{__DIE__}> is still in effect. | |||
| 487 | ||||
| 488 | Though it can be argued that C<$SIG{__DIE__}> should be disabled inside of | |||
| 489 | C<eval> blocks, since it isn't people have grown to rely on it. Therefore in | |||
| 490 | the interests of compatibility, C<try> does not disable C<$SIG{__DIE__}> for | |||
| 491 | the scope of the error throwing code. | |||
| 492 | ||||
| 493 | =item * | |||
| 494 | ||||
| 495 | Lexical C<$_> may override the one set by C<catch>. | |||
| 496 | ||||
| 497 | For example Perl 5.10's C<given> form uses a lexical C<$_>, creating some | |||
| 498 | confusing behavior: | |||
| 499 | ||||
| 500 | given ($foo) { | |||
| 501 | when (...) { | |||
| 502 | try { | |||
| 503 | ... | |||
| 504 | } catch { | |||
| 505 | warn $_; # will print $foo, not the error | |||
| 506 | warn $_[0]; # instead, get the error like this | |||
| 507 | } | |||
| 508 | } | |||
| 509 | } | |||
| 510 | ||||
| 511 | =back | |||
| 512 | ||||
| 513 | =head1 SEE ALSO | |||
| 514 | ||||
| 515 | =over 4 | |||
| 516 | ||||
| 517 | =item L<TryCatch> | |||
| 518 | ||||
| 519 | Much more feature complete, more convenient semantics, but at the cost of | |||
| 520 | implementation complexity. | |||
| 521 | ||||
| 522 | =item L<autodie> | |||
| 523 | ||||
| 524 | Automatic error throwing for builtin functions and more. Also designed to | |||
| 525 | work well with C<given>/C<when>. | |||
| 526 | ||||
| 527 | =item L<Throwable> | |||
| 528 | ||||
| 529 | A lightweight role for rolling your own exception classes. | |||
| 530 | ||||
| 531 | =item L<Error> | |||
| 532 | ||||
| 533 | Exception object implementation with a C<try> statement. Does not localize | |||
| 534 | C<$@>. | |||
| 535 | ||||
| 536 | =item L<Exception::Class::TryCatch> | |||
| 537 | ||||
| 538 | Provides a C<catch> statement, but properly calling C<eval> is your | |||
| 539 | responsibility. | |||
| 540 | ||||
| 541 | The C<try> keyword pushes C<$@> onto an error stack, avoiding some of the | |||
| 542 | issues with C<$@>, but you still need to localize to prevent clobbering. | |||
| 543 | ||||
| 544 | =back | |||
| 545 | ||||
| 546 | =head1 LIGHTNING TALK | |||
| 547 | ||||
| 548 | I gave a lightning talk about this module, you can see the slides (Firefox | |||
| 549 | only): | |||
| 550 | ||||
| 551 | L<http://nothingmuch.woobling.org/talks/takahashi.xul?data=yapc_asia_2009/try_tiny.txt> | |||
| 552 | ||||
| 553 | Or read the source: | |||
| 554 | ||||
| 555 | L<http://nothingmuch.woobling.org/talks/yapc_asia_2009/try_tiny.yml> | |||
| 556 | ||||
| 557 | =head1 VERSION CONTROL | |||
| 558 | ||||
| 559 | L<http://github.com/nothingmuch/try-tiny/> | |||
| 560 | ||||
| 561 | =head1 AUTHOR | |||
| 562 | ||||
| 563 | Yuval Kogman E<lt>nothingmuch@woobling.orgE<gt> | |||
| 564 | ||||
| 565 | =head1 COPYRIGHT | |||
| 566 | ||||
| 567 | Copyright (c) 2009 Yuval Kogman. All rights reserved. | |||
| 568 | This program is free software; you can redistribute | |||
| 569 | it and/or modify it under the terms of the MIT license. | |||
| 570 | ||||
| 571 | =cut | |||
| 572 |