in reply to Re: Setting $! to custom values
in thread Setting $! to custom values

No, please no. $@ is for eval errors. Not user-level errors. When you mix those up, you make it much harder to program for evals.

Please, don't be like the IO::* Modules. Wrong.

-- Randal L. Schwartz, Perl hacker
Be sure to read my standard disclaimer if this is a reply.


Update: Note the docs on this:
$@ The Perl syntax error message from the last eval() operato +r. If $@ is the null string, the last eval() parsed and executed correctly (although the operations you invoked may have fa +iled in the normal fashion). (Mnemonic: Where was the syntax er +ror "at"?) Warning messages are not collected in this variable. You c +an, however, set up a routine to process warnings by setting $SIG{__WARN__} as described below. Also see "Error Indicators".
Nowhere does it say that it's for user errors. And if you set $@ in the middle of your code, you lose the eval error!

Replies are listed 'Best First'.
Re: •Re: Re: Setting $! to custom values
by sauoq (Abbot) on Nov 04, 2003 at 02:50 UTC

    I'm not sure I see your point. How exactly do you define a "user-level" error?

    What is the significant difference between the two subs in the following code?

    sub foo { eval { my $m = shift; die $m; }; return; } sub bar { my $m = shift; $@ = $m . ' at ' . __FILE__ . ' line ' . __LINE__ . "\n"; return } foo("foo message"); print "foo $@"; bar("bar message"); print "bar $@";
    It seems to me that whenever you use die() to throw exceptions expecting (or requiring) your users to use eval() to catch those exceptions you are, essentially, just setting $@ for them.

    I don't see how it could hurt anything to set it explicitly as long as you document that your code uses it to return an error. That's not to say I'm a fan of this approach (I'm not), but I am suspicious of your claim that it would "make it much harder to program for evals."

    And if you set $@ in the middle of your code, you lose the eval error!

    But, if you want to rely on $@, you had better inspect it immediately after your eval() anyway. That is, unless you trust everyone else's code to always localize $@ and be free from compile time errors in their eval BLOCKs.

    -sauoq
    "My two cents aren't worth a dime.";
    

      die is better in the case of uncaught exceptions. If a subroutine just sets $@ and another programer blindly calls it without checking $@ after it runs, the program goes on. Whereas with a die, the programmer will know that they are a bozo as soon as that code path is tested and fix their code.

      ----
      I wanted to explore how Perl's closures can be manipulated, and ended up creating an object system by accident.
      -- Schemer

      : () { :|:& };:

      Note: All code is untested, unless otherwise stated

Re: •Re: Re: Setting $! to custom values
by diotalevi (Canon) on Nov 04, 2003 at 22:28 UTC
    Of course $@ is for user errors! That's the entire point behind putting useful messages or objects into die. Just because I didn't use die() to set $@ (and trigger the exception handler, if any) doesn't mean I'm not intending for $@ to be a place to look for my error.