err has asked for the wisdom of the Perl Monks concerning the following question:

Hi there,
I am using Try::Tiny for catching dies in my script. But I've some problems to return from the sub the try..catch - block is in.
Here's some sample:

use Try::Tiny; sub foo { try { die; } catch { print 'error'; return; }; print 'no_err'; } foo;

This code outputs: "errorno_err". So as you can see it does not return from the sub itself, only from the catch block.
Anybody has an idea how to get the desired behavior?

Thank you for help!

Replies are listed 'Best First'.
Re: Try::Tiny - return in catch from sub
by jethro (Monsignor) on Nov 26, 2010 at 14:03 UTC
    Read the Try::Tiny documentation:

    return returns from the try block, not from the parent sub (note that this is also how eval works, but not how TryCatch works):

    I would return a value from the try block that signals error or no error, and put the subs return() outside of the try block

Re: Try::Tiny - return in catch from sub
by mjscott2702 (Pilgrim) on Nov 26, 2010 at 14:06 UTC
    The doc for that module says it supports a return from the "try" block, doesn't mention the "catch" block - you could try setting a flag inside the catch (defined at the sub level) and return if that flag is set e.g.

    sub foo { my $error = 0; try { die; } catch { print "error\n"; $error = 1; } return if $error; print "no_err\n"; }

    I agree from a program flow point-of-view, it would be better if the return inside the catch worked as expected - it may be that the "catch" is itself similar to a sub, and the return is returning from that?

      um, it says what try returns, what catch returns ... see this example
      try { die_sometimes(); } catch { # ...code run in case of error } finally { if (@_) { print "The try block died with: @_\n"; } else { print "The try block ran without error.\n"; } };
      if you want to return from your sub from within a try/catch then use as directed
      use TryCatch; sub foo { my ($self) = @_; try { die Some::Class->new(code => 404 ) if $self->not_found; return "return value from foo"; } catch (Some::Class $e where { $_->code > 100 } ) { } }
      Try::Tiny is for when TryCatch is too much, it is not a drop in replacement, mind the caveats
        um, not in the CPAN documentation:

        This module provides bare bones try/catch/finally statements that are designed to minimize common mistakes with eval blocks, and NOTHING else. This is unlike TryCatch which provides a nice syntax and avoids adding another call stack layer, and supports calling return from the try block to return from the parent subroutine.

Re: Try::Tiny - return in catch from sub
by ikegami (Patriarch) on Nov 26, 2010 at 17:28 UTC
    It's a limitation of the feature Try::Tiny uses to provide that syntax.
    try { die; } catch { print 'error'; return; # Not very useful! };
    is the same as
    &try( sub { die; }, &catch( sub { print 'error'; return; # Not very useful! }, ), );

    Placing a return in the the sub you're passing to try or the sub you're passing to catch will only exit that sub (if and when it's called).

    Zephram is doing awesome work with the Perl parser which will provide clean means of providing modules like Try::Tiny without this issue.

    There currently exists such a module, but it uses some trickier means of doing this.

Re: Try::Tiny - return in catch from sub
by JavaFan (Canon) on Nov 26, 2010 at 14:04 UTC
    The argument to catch is a sub. You're returning from that sub. This is documented in the Try::Tiny manual page. It also suggests to use TryCatch if you want to return from the try/catch blocks.