Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

canonical doc explaing need for "eval { ... } or do {...}" construct

by LanX (Saint)
on May 09, 2022 at 13:36 UTC ( [id://11143695]=perlquestion: print w/replies, xml ) Need Help??

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

Hi

Today I had to explain to colleagues again that

eval { SOME_RISKY_CODE }; if( $@ ) { DEAL_WITH_ERROR }

isn't good praxis and why

eval { ... ; 1 } or do {...}

should be preferred.

I promised to send some authoritative canonical text, preferably from perldoc, justifying it.

Lamentably does eval not be attempting any effort in that direction.

The only approximate thing I found was the motivation explained in Try::Tiny

So what's the canonical blog or discussion I could refer too?

Cheers Rolf
(addicted to the Perl Programming Language :)
Wikisyntax for the Monastery

Replies are listed 'Best First'.
Re: canonical doc explaing need for "eval { ... } or do {...}" construct
by pryrt (Abbot) on May 09, 2022 at 13:52 UTC
    according to my bookmark, Bug in eval in pre-5.14 shows an example of the bug in practice, and provides a link to perl514delta, directing you to the sections on $@, which explain that prior to 5.14, $@ could be clobbered. I don't know if that's sufficient enough for you and your colleagues.

    addendum: that conversation also has an anonymonk-link to a couple of rt issues with verbiage that says it's still dangerous even after 5.14's improvements.

Re: canonical doc explaing need for "eval { ... } or do {...}" construct
by karlgoethebier (Abbot) on May 10, 2022 at 11:05 UTC
Re: canonical doc explaing need for "eval { ... } or do {...}" construct
by Discipulus (Canon) on May 10, 2022 at 11:08 UTC
    Hello LanX,

    it is already linked, but for me this by them is canonical enough for me :)

    Lamentably our docs are at least suboptimal: why dont you fork perldoc and add a paragraph in eval ? I'm sure you can phrase it correctly.

    After the PR you can point your collegues to standard documentation.

    L*

    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
      Thank you all! :)

      I think the overall best solution is to mention Try::Tiny in the perldocs.

      eval { ...; 1 } or do {...} might be a good solution if you hate dependencies and want backwards compatibility.

      But it's just too much boilerplate to keep in mind.

      Me too, I forgot about the ;1 part when starting this thread.

      But I'm worried about compatibility issues with Try::Tiny and the new try feature in 5.36.

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

        But I'm worried about compatibility issues with Try::Tiny and the new try feature in 5.36.

        According to MetaCPAN there are 15,409 dists depending ultimately on Try::Tiny. I credit those steering the good ship Perl with enough nous to realise that breaking this would be an absolute no-go.


        🦛

        I think the overall best solution is to mention Try::Tiny in the perldocs.

        hmmm, the Perl docs probably should be in the business of recommending specific non-core modules.

        Especially since Perl is getting a try keyword...

Re: canonical doc explaing need for "eval { ... } or do {...}" construct
by cavac (Parson) on May 10, 2022 at 07:57 UTC

    Personally, i usually use something like this:

    use English; ... my $evalok = 0; eval { SOME_RISKY_CODE $evalok = 1; }; if(!$evalok) { print "Something bad happened: ", $EVAL_ERROR, "\n"; work_around_the_problem_or_give_up(); }

    This may be a good or bad solution. But at least for me, it makes it easier and faster to visually scan the code later in its life cycle and see how it's meant to flow and if there is error handling in place.

    perl -e 'use Crypt::Digest::SHA256 qw[sha256_hex]; print substr(sha256_hex("the Answer To Life, The Universe And Everything"), 6, 2), "\n";'
Re: canonical doc explaing need for "eval { ... } or do {...}" construct
by eyepopslikeamosquito (Archbishop) on May 10, 2022 at 10:37 UTC
Re: canonical doc explaing need for "eval { ... } or do {...}" construct
by ikegami (Patriarch) on May 11, 2022 at 14:18 UTC

    Since 5.28, it doesn't matter.

    Before, especially before 5.14, $@ could get clobbered, so if eval { ... ; 1 } was more reliable.


    There was a time where it was possible for $@ to get cleared or replaced before eval returned.

    package Mod { DESTROY { eval { } } } eval { my $x = bless( {}, "Mod" ); die( "xxx\n" ); }; print $@ || "[undef]\n";
    $ 5.12t/bin/perl a.pl [undef]

    This has been fixed.

    $ 5.14t/bin/perl a.pl xxx

    So, using eval { ...; 1 } and checking the result of eval was more reliable. And it was promoted as the more reliable solution for this reason. There was an attempt to fix in 5.14, but edge cases were only fixed in 5.28.


    Updated to cover edge cases found later, as per choroba's reply.

      > Since 5.14, it doesn't matter.

      Have you followed the links provided in this thread? E.g. Re: Bug in eval in pre-5.14. 5.14 is not safe.

      map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]

        I had not. Thanks. I have adjusted my post.

Re: canonical doc explaing need for "eval { ... } or do {...}" construct
by Anonymous Monk on May 10, 2022 at 07:25 UTC

      hrm, I thought you didn't like tye.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others imbibing at the Monastery: (4)
As of 2024-04-20 16:05 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found