remove stale version control link in pod
[p5sagit/Try-Tiny.git] / lib / Try / Tiny.pm
index 601637a..39664d3 100644 (file)
@@ -2,7 +2,7 @@ package Try::Tiny;
 use 5.006;
 # ABSTRACT: minimal try/catch with proper preservation of $@
 
-our $VERSION = '0.23';
+our $VERSION = '0.27';
 
 use strict;
 use warnings;
@@ -29,6 +29,8 @@ BEGIN {
   *_HAS_SUBNAME = ($su || $sn) ? sub(){1} : sub(){0};
 }
 
+my %_finally_guards;
+
 # 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
@@ -72,6 +74,15 @@ sub try (&;@) {
   _subname("${caller}::try {...} " => $try)
     if _HAS_SUBNAME;
 
+  # set up scope guards to invoke the finally blocks at the end.
+  # this should really be a function scope lexical variable instead of
+  # file scope + local but that causes issues with perls < 5.20 due to
+  # perl rt#119311
+  local $_finally_guards{guards} = [
+    map { Try::Tiny::ScopeGuard->_new($_) }
+    @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 = $@;
@@ -99,14 +110,12 @@ sub try (&;@) {
   $error = $@;
   $@ = $prev_error;
 
-  # set up a scope guard to invoke the finally block at the end
-  my @guards =
-    map { Try::Tiny::ScopeGuard->_new($_, $failed ? $error : ()) }
-    @finally;
-
   # at this point $failed contains a true value if the eval died, even if some
   # destructor overwrote $@ as the eval was unwinding.
   if ( $failed ) {
+    # pass $error to the finally blocks
+    push @$_, $error for @{$_finally_guards{guards}};
+
     # if we got an error, invoke the catch block.
     if ( $catch ) {
       # This works like given($error), but is backwards compatible and
@@ -464,6 +473,8 @@ value.
 
 Using Perl 5.10 you can use L<perlsyn/"Switch statements">.
 
+=for stopwords topicalizer
+
 The C<catch> block is invoked in a topicalizer context (like a C<given> block),
 but note that you can't return a useful value from C<catch> using the C<when>
 blocks without an explicit C<return>.
@@ -485,7 +496,7 @@ concisely match errors:
 =item *
 
 C<@_> is not available within the C<try> block, so you need to copy your
-arglist. In case you want to work with argument values directly via C<@_>
+argument list. In case you want to work with argument values directly via C<@_>
 aliasing (i.e. allow C<$_[1] = "foo">), you need to pass C<@_> by reference:
 
   sub foo {
@@ -553,11 +564,13 @@ C<try> introduces another caller stack frame. L<Sub::Uplevel> is not used. L<Car
 will not report this when using full stack traces, though, because
 C<%Carp::Internal> is used. This lack of magic is considered a feature.
 
+=for stopwords unhygienically
+
 =item *
 
 The value of C<$_> in the C<catch> block is not guaranteed to be the value of
 the exception thrown (C<$@>) in the C<try> block.  There is no safe way to
-ensure this, since C<eval> may be used unhygenically in destructors.  The only
+ensure this, since C<eval> may be used unhygienically in destructors.  The only
 guarantee is that the C<catch> will be called if an exception is thrown.
 
 =item *
@@ -605,7 +618,7 @@ confusing behavior:
 
 Note that this behavior was changed once again in L<Perl5 version 18
 |https://metacpan.org/module/perldelta#given-now-aliases-the-global-_>.
-However, since the entirety of lexical C<$_> is now L<considired experimental
+However, since the entirety of lexical C<$_> is now L<considered experimental
 |https://metacpan.org/module/perldelta#Lexical-_-is-now-experimental>, it
 is unclear whether the new version 18 behavior is final.
 
@@ -655,9 +668,4 @@ Or read the source:
 
 L<http://web.archive.org/web/20100305133605/http://nothingmuch.woobling.org/talks/yapc_asia_2009/try_tiny.yml>
 
-=head1 VERSION CONTROL
-
-L<http://github.com/doy/try-tiny/>
-
 =cut
-