Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

return eval { die() } idiom

by lestrrat (Deacon)
on Aug 29, 2003 at 19:27 UTC ( [id://287805]=perlquestion: print w/replies, xml ) Need Help??

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

I'm in a dilemma here. At work, we have a lot of C programmers, and hence they like to code their Perl code in sort of a C-ish way. Which is fine in most cases, but there's one thing that I just fail to see the benefit, and that is an idiom that they use:

sub myfunc { ... return eval { # do bunch of things here... if($err_condition) { die "error"; } return 1; } }

So basically they want to make it such that you can check the return value and check $@ in an errono-like fashion. Which is fine, but it just strikes me as really, really odd.

I just fail to see how it could be better than just simply raising an exception. Why can't I just die()?

If I'm to try and use a simple die/croak instead, I'm going to have to convince a lot of people... Otherwise if I'm going to have to live with it, I want to make sure that I understand the benefits, and that we're not alone in using this.

In all honesty, I may just be too deep into all the Perl-isms, and that I'm missing something obvious. If there are other people who use this idiom, I would realy like to know, and also, why? What advantages do you gain?

TIA.

Replies are listed 'Best First'.
Re: return eval { die() } idiom
by tcf22 (Priest) on Aug 29, 2003 at 19:36 UTC
    I use it sometimes. It is really just a try/catch/throw. I normally use so I don't have to check the return value of a whole bunch of functions. For example:
    eval{ ##Do DB Stuff if($db->Sql($sql)){ die "Error Querying SQL. Error: " . $db->Error(); } ... ## Send email my $sender = new Mail::Sender({smtp => $smtp, on_errors => 'die'})|| die "Failed Mail::Sender object creation: $Mail::Sender +::Error\n"; ## Do more Mail::Sender stuff, which will die on failure ##because of on_errors => 'die' ... }; &write_error_log($@) if($@);

      thanks, but that I understand:

      eval { # blah blah... die ("fooblah"); # or something_that_may_die(); }; if($@) { # do something }

      That's how I would normally use it.

      I'm talking about this: "return eval { BLOCK }", where BLOCK is the main block of your code...

        Dear lestrrat
        AFAIK, the only difference between tfc22's code and yours is the way you handle errors. In essense, both codes do the same thing. I really see no point about where you die() for errors, since you die() for errors somewhere in your code.
        What I see is Just Another Way To Do It.
        Maybe some benchmarking could reveal something more interesting.

        On the other hand, as you mentioned before, the guys who coded the initial snippet use to code C, and the idiom is much more readable to C programmers than it is for smalltalk-based perl programmers (like me). Maybe this is the advantage you're looking for: C programmers that see this kind of construction will more likely recognise it (and feel at home) than programmers with other backgrounds.

        My two pence.

        =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
        monsieur_champs

        I personally don't really like that construct, but I have seen it used. I really think that it is just a matter of preference. Using the return eval construct, makes you function behave more like a built-in function, returning a status and setting an error variable($@) if needed. This can be done many other ways as I'm sure you are aware(TIMTOWTDI).

        I haven't ran Benchmark, so I'm not sure, but this seems like it would be slower than just checking the return status, setting an error variable, then returning.
Re: return eval { die() } idiom
by benn (Vicar) on Aug 30, 2003 at 10:08 UTC
    I think this depends on the general error handling strategy of the whole application. When developing and working out the 'nitty-gritty' in subs, modules etc. (especially with command-line-based apps), I like the code to die there and then.

    Eventually though, once the errors (hopefully!) are down to being only those that are likely to be thrown by strange input/ system failures etc. (rather than buggy code), I'll fit the error handling into the 'bigger picture' - this could be "report to user and die", but it may also be "report to user, but ignore and continue", "report via email to sysadmin and ignore", "report to eveybody in 100m radius and SHUT DOWN THE POWER NOW GOD DAMMIT LETS GET THESE PEOPLE OUTTA HERE!!" etc.

    Where this reporting (or not) happens is then just a matter of personal preference. Some people like to call "Report_Error($error)" everywhere, while some people like to check return values and report in a single place (as part of the 'main loop' logic say). The 'C-style' code you demonstrate is appropriate for the latter - if the sub failed, the error can be propagated up nicely and the 'main logic' can take the appropriate action - trying another sub for instance, rather than having the failing sub dictate its own strategy.

    Cheers, Ben.

Re: return eval { die() } idiom
by bsb (Priest) on Aug 30, 2003 at 15:17 UTC
    So the callers do something like the following?
    myfunc() or print "something bad in myfunc $@\n";
    Instead of:
    eval { myfunc() } or print "something bad in myfunc $@\n";
    I haven't seen this in Perl, that I recall.

    It might make sense sometimes, but I suspect that with 2 or more levels of calling functions you end up doing a whole lot of re-die-ing.

    Interesting anyway.

      Personally, I do something like:
      sub x { # stuff eval { # eval-ed stuff }; if ($@) { die $@ unless UNIVERSAL::isa($@, 'ErrorOrSignalThatICanHandleH +ere'); # Handle the error/signal types I can handle here however I se +e fit }; return 1; }

      Of course, this assumes a library of error and signal classes, but, then again, if you're using eval-die as a throw-catch mechanism, you would have those, right?

      ------
      We are the carpenters and bricklayers of the Information Age.

      The idea is a little like C++ templates, except not quite so brain-meltingly complicated. -- TheDamian, Exegesis 6

      Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others browsing the Monastery: (3)
As of 2024-04-19 21:25 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found