Merge pull request #11 from ilmari/global-destruction
[p5sagit/Try-Tiny.git] / lib / Try / Tiny.pm
index 8e8dd02..62a8ac0 100644 (file)
@@ -1,17 +1,18 @@
 package Try::Tiny;
+use 5.006;
+# ABSTRACT: minimal try/catch with proper preservation of $@
 
 use strict;
 use warnings;
 
-our $VERSION = "0.12";
-$VERSION = eval $VERSION if $VERSION =~ /_/;
-
-use base 'Exporter';
+use Exporter 5.57 'import';
 our @EXPORT = our @EXPORT_OK = qw(try catch finally);
 
 use Carp;
 $Carp::Internal{+__PACKAGE__}++;
 
+BEGIN { eval "use Sub::Name; 1" or *{subname} = sub {1} }
+
 # Need to prototype as @ not $$ because of the way Perl evaluates the prototype.
 # Keeping it at $$ means you only ever get 1 sub because we need to eval in a list
 # context & not a scalar one
@@ -23,7 +24,9 @@ sub try (&;@) {
   # to $failed
   my $wantarray = wantarray;
 
-  my ( $catch, @finally );
+  # work around perl bug by explicitly initializing these, due to the likelyhood
+  # this will be used in global destruction (perl rt#119311)
+  my ( $catch, @finally ) = ();
 
   # find labeled blocks in the argument list.
   # catch and finally tag the blocks by blessing a scalar reference to them.
@@ -48,6 +51,12 @@ sub try (&;@) {
   # not perfect, but we could provide a list of additional errors for
   # $catch->();
 
+  # name the blocks if we have Sub::Name installed
+  my $caller = caller;
+  subname("${caller}::try {...} " => $try);
+  subname("${caller}::catch {...} " => $catch) if $catch;
+  subname("${caller}::finally {...} " => $_) foreach @finally;
+
   # save the value of $@ so we can set $@ back to it in the beginning of the eval
   # and restore $@ after the eval finishes
   my $prev_error = $@;
@@ -105,7 +114,7 @@ sub try (&;@) {
 sub catch (&;@) {
   my ( $block, @rest ) = @_;
 
-  croak 'Useless bare catch()' unless defined wantarray;
+  croak 'Useless bare catch()' unless wantarray;
 
   return (
     bless(\$block, 'Try::Tiny::Catch'),
@@ -116,7 +125,7 @@ sub catch (&;@) {
 sub finally (&;@) {
   my ( $block, @rest ) = @_;
 
-  croak 'Useless bare finally()' unless defined wantarray;
+  croak 'Useless bare finally()' unless wantarray;
 
   return (
     bless(\$block, 'Try::Tiny::Finally'),
@@ -161,10 +170,6 @@ __END__
 
 =pod
 
-=head1 NAME
-
-Try::Tiny - minimal try/catch with proper preservation of $@
-
 =head1 SYNOPSIS
 
 You can use Try::Tiny's C<try> and C<catch> to expect and handle exceptional
@@ -490,7 +495,21 @@ Instead, you should capture the return value:
     my $success = try {
       die;
       1;
+    };
+    return unless $success;
+
+    say "This text WILL NEVER appear!";
+  }
+  # OR
+  sub parent_sub_with_catch {
+    my $success = try {
+      die;
+      1;
     }
+    catch {
+      # do something with $_
+      return undef; #see note
+    };
     return unless $success;
 
     say "This text WILL NEVER appear!";
@@ -602,7 +621,7 @@ issues with C<$@>, but you still need to localize to prevent clobbering.
 I gave a lightning talk about this module, you can see the slides (Firefox
 only):
 
-L<web.archive.org/web/20100628040134/http://nothingmuch.woobling.org/talks/takahashi.xul>
+L<http://web.archive.org/web/20100628040134/http://nothingmuch.woobling.org/talks/takahashi.xul>
 
 Or read the source:
 
@@ -610,17 +629,7 @@ L<http://web.archive.org/web/20100305133605/http://nothingmuch.woobling.org/talk
 
 =head1 VERSION CONTROL
 
-L<http://github.com/nothingmuch/try-tiny/>
-
-=head1 AUTHOR
-
-Yuval Kogman E<lt>nothingmuch@woobling.orgE<gt>
-
-=head1 COPYRIGHT
-
-  Copyright (c) 2009 Yuval Kogman. All rights reserved.
-  This program is free software; you can redistribute
-  it and/or modify it under the terms of the MIT license.
+L<http://github.com/doy/try-tiny/>
 
 =cut