From: Yuval Kogman Date: Fri, 22 Jan 2010 20:04:47 +0000 (+0100) Subject: Restore list context for catch and fix a bug in finally with no catch X-Git-Tag: Try-Tiny-0.04~2 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=82ef0e611ffa07a8a92bcdee2591cb738243b1ea;p=p5sagit%2FTry-Tiny.git Restore list context for catch and fix a bug in finally with no catch --- diff --git a/lib/Try/Tiny.pm b/lib/Try/Tiny.pm index 65c8867..b0bdcf1 100644 --- a/lib/Try/Tiny.pm +++ b/lib/Try/Tiny.pm @@ -84,6 +84,9 @@ sub try (&;@) { $error = $@; } + # set up a scope guard to invoke the finally block at the end + my $guard = $finally && bless \$finally, "Try::Tiny::ScopeGuard"; + # at this point $failed contains a true value if the eval died, even if some # destructor overwrote $@ as the eval was unwinding. if ( $failed ) { @@ -92,13 +95,7 @@ sub try (&;@) { # This works like given($error), but is backwards compatible and # sets $_ in the dynamic scope for the body of C<$catch> for ($error) { - my $catch_return = $catch->($error); - - # Finally blocks run after all other blocks so it is executed here - $finally->() if ( $finally ); - - #And return whatever catch returned - return $catch_return; + return $catch->($error); } # in case when() was used without an explicit return, the C @@ -107,9 +104,6 @@ sub try (&;@) { return; } else { - # Execute finally block once we decided we worked - $finally->() if ( $finally ); - # no failure, $@ is back to what it was, everything is fine return $wantarray ? @ret : $ret[0]; } @@ -133,6 +127,11 @@ sub finally (&;@) { ); } +sub Try::Tiny::ScopeGuard::DESTROY { + my $self = shift; + $$self->(); +} + __PACKAGE__ __END__ diff --git a/t/basic.t b/t/basic.t index ba71ed3..022c604 100644 --- a/t/basic.t +++ b/t/basic.t @@ -3,7 +3,7 @@ use strict; #use warnings; -use Test::More tests => 24; +use Test::More tests => 26; BEGIN { use_ok 'Try::Tiny' }; @@ -72,8 +72,12 @@ throws_ok { is( $@, "magic", '$@ untouched' ); } -is( scalar(try { "foo", "bar", "gorch" }), "gorch", "scalar context" ); -is_deeply( [ try {qw(foo bar gorch)} ], [qw(foo bar gorch)], "list context" ); +is( scalar(try { "foo", "bar", "gorch" }), "gorch", "scalar context try" ); +is_deeply( [ try {qw(foo bar gorch)} ], [qw(foo bar gorch)], "list context try" ); + +is( scalar(try { die } catch { "foo", "bar", "gorch" }), "gorch", "scalar context catch" ); +is_deeply( [ try { die } catch {qw(foo bar gorch)} ], [qw(foo bar gorch)], "list context catch" ); + { my ($sub) = catch { my $a = $_; }; diff --git a/t/finally.t b/t/finally.t index d8bd0d4..1310633 100644 --- a/t/finally.t +++ b/t/finally.t @@ -3,7 +3,7 @@ use strict; #use warnings; -use Test::More tests => 7; +use Test::More tests => 8; BEGIN { use_ok 'Try::Tiny' };