Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

$@ can't be relied on?

by sherab (Scribe)
on Nov 17, 2009 at 19:49 UTC ( [id://807771]=perlquestion: print w/replies, xml ) Need Help??

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

Hello esteemed monks, I was using the perl critic on the code below....

eval { # # Prepare the SQL Statment # my $sth = $dbh->prepare($sql) or die "Can't prepare SQL statemen +t: $DBI::errstr"; # # Execute the SQL Statment # my $rc = $sth->execute(@values) or die "Can't execute SQL statem +ent: $DBI::errstr"; # # Fetch the result # $data = $sth->fetchall_arrayref({}); $sth->finish; # # check for problems which may have terminated the fetch early # die "Can't query result: $sth->errstr" if $sth->err; }; if ($@) { print STDERR "ERROR [query_database()]: $@"; return 0; }

I got the notice that "You can't depend upon the value of $@/$EVAL_ERROR to tell whether an eval failed."
Is that because this traps the last syntax error and not warning messages?. Any advice on $@ would be appreciated.



Got a LOT of great answers. Monks you are the best!

Replies are listed 'Best First'.
Re: $@ can't be relied on?
by jettero (Monsignor) on Nov 17, 2009 at 19:53 UTC
    That's correct. There are rare cases where it doesn't work. The correct way to do this is as follows:
    my $res = eval { might_explode(); 1 }; die "omgish: $@\n" unless $res; # Also, why invoke print and exit whe +n this will do?

    Note that die $@ if $@ almost always works. I can't recall the example case I saw, but it's reproducible stuff. It's not like it just randomly doesn't work. Well, maybe with threads.

    EDIT: Oh, right. Below, JavaFan gives an example of a case where it doesn't work. Instead of local $@; die, you can easily see there being a function() or an $obj->method that does the equivalent of that without your realizing it. I believe that's what I actually ran into (years ago).

    -Paul

      eval { might_explode(); 1 } or die "omgish: $@\n"; __END__ omgish: Undefined subroutine &main::might_explode called at - line 2.
Re: $@ can't be relied on?
by JavaFan (Canon) on Nov 17, 2009 at 21:38 UTC
    Easiest case where it doesn't work:
    eval {local $@; die}; if ($@) {say "eval failed"} else {say "eval succeeded"} __END__ eval succeeded
Re: $@ can't be relied on?
by JadeNB (Chaplain) on Nov 17, 2009 at 20:24 UTC
Re: $@ can't be relied on?
by przemo (Scribe) on Nov 17, 2009 at 20:37 UTC

    Take a look at a source of a neat module Try::Tiny, which has "safe eval"-ing as the only goal. Can be used as a replacement of own eval-s. Does more or less what other respondents wrote, plus localizing $@.

Re: $@ can't be relied on?
by mje (Curate) on Nov 17, 2009 at 20:31 UTC

    I believe the cases where this might not work is for instance if something goes out of scope in the eval and a DESTROY is called - it could do something else that might change $@.

Log In?
Username:
Password:

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

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

    No recent polls found