Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

Die inside Try::Tiny blocks

by dd-b (Monk)
on Apr 26, 2013 at 20:52 UTC ( [id://1030894]=perlquestion: print w/replies, xml ) Need Help??

dd-b has asked for the wisdom of the Perl Monks concerning the following question:

I stubbed my toe on the documented behavior of Try::Tiny the other day, and have been working that out. I mostly fixed my code, using the fact that either try or catch block value is returned from the try call (finally block is not). The documentation contains the information -- hidden between the lines and buried deeply at the bottom. Maybe I should take up documentation writing as my next hobby, the "*I* could do better than that" urge is loud.

So then I thought I'd better look at how dies inside the blocks are handled. The documentation doesn't make this clear to me yet.

So, this test program:
#! /usr/bin/perl use Try::Tiny; my $res = try { print "point 1\n"; die "point 1.5\n"; 11; } catch { print "point 2\n"; die "point 2.4\n"; 22; } finally { print "point 3\n"; die "point 3.5\n"; 77; }; print "res $res\n";
Produces this output:
point 1 point 2 point 2.4 point 3

I expect the die "point 1.5\n" statement to take me out of the try block into the catch block, so that's fine. And it's not surprising I don't hit my final print "res $res\n" statement, one of those dies is going to get me out of there eventually.

But how can I hit print "point 3\n" in the finally block without also hitting die "point 3.5\n"? (And if I put another print after the die in the finally block, it is NOT hit.)

What can I reasonably expect about a die command in the catch block, or the finally block?

Another variation emphasizes the weirdness of dieing in the finally block:

#! /usr/bin/perl use Try::Tiny; my $res = try { print "point 1\n"; die "point 1.5\n"; 11; } catch { print "point 2\n"; 22; } finally { print "point 3\n"; die "point 3.5\n"; print "point 3.8\n"; 77; };
produces
point 1 point 2 point 3 res 22

So, my mental model is that the finally block is executed as a subroutine as the next-to-last action before try either returns or re-throws a die out of a catch block, and any die in the finally block is ignored whether or not there was one in the try block. Is this the right model? Can I count on this? The annoying thing about it is that it makes it very hard to use the finally block for cleanup, since lots of modern code counts on using die for error reporting.

I'm running perl 5.10.1 on Centos 6.4, that being the most recent packaged version in the distribution. The point of running "server" distributions is known-compatible packages conservatively chosen, right?

Replies are listed 'Best First'.
Re: Die inside Try::Tiny blocks
by chromatic (Archbishop) on Apr 26, 2013 at 21:17 UTC
    What can I reasonably expect about a die command in the catch block, or the finally block?

    As the documentation suggests, you are responsible for your own error handling in the finally block. That means you need to use eval or try in it (though I shudder at the thought of the latter).

    The point of running "server" distributions is known-compatible packages conservatively chosen, right?

    I think in truth it's that "Installing software is haaaaaaaaaaard." I wouldn't take RHEL's suggestions on what makes for good Perl.

      Yes, I guess those statements about error handling do imply the behavior I'm seeing. They don't immediately make me think of that behavior, though. I'll try to figure out of I can make it clearer and try a doc patch if so.

      Since Try::Tiny says it exists to avoid the mistakes people make using eval for this kind of thing it does seem like using it again inside the the finally block as needed is what the authors had in mind...should be amusing.

      (I only had one place in the code I'm actually working on where I'd messed up use of try blocks, but it was good to run through and check all the ones I'd added to be sure.)

        You're probably doing something far more complicated than you ought to if your finally block can throw an exception. I wouldn't do anything more than logging an error or setting a flag to restart a computation.

Re: Die inside Try::Tiny blocks
by Tommy (Chaplain) on Apr 27, 2013 at 03:29 UTC

    If the documentation is not clear to you and you feel like you have something to add, then by all means do not try to "do it better your self". Instead try to "do it better together" with the author, by submitting a patch on the CPAN RT site for the module or at its git repo which is even easier. Just go to the repository, edit the file to include your documentation changes, and save it. A patch will be automatically generated and sent to the author.

    This is how we all grow and benefit together. The Perl community thrives on the CPAN and the CPAN thrives on the contributions, great and small, of all of us. Sharing is caring!

    Tommy
    A mistake can be valuable or costly, depending on how faithfully you pursue correction

      The documentation is nowhere near so bad that I'd choose to start from scratch, definitely not.

      Thanks for saying how easy it is to propose a patch through GitHub. Yes, I should give in to the urge to improve documentation (or code, but I get the feeling that the documentation isn't up to the code more often).

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1030894]
Approved by ww
Front-paged by Tommy
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others about the Monastery: (4)
As of 2024-04-24 22:29 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found