in reply to Question on "Effective Perl Programming"

According to the eval documentation, "If there was no error, $@ is guaranteed to be a null string." According to True or False? A Quick Reference Guide, the only expressions that would be false but not a null string are undef and 0 (or "0").

I think the only way there could be an error that is not caught by "if ($@)" would be if you were to throw an exception that uses overload to generate a false value in that case. That is to say, I think "if ($@)" would work in every case except where the code in the eval does something deliberately mean or it has a really unlikely bug.

Replies are listed 'Best First'.
Re^2: Question on "Effective Perl Programming"
by perrin (Chancellor) on Sep 06, 2007 at 03:33 UTC
    Amusingly enough, if you use Exception::Class and throw an error without a message, it has an overload that will stringify to undef, so "if ($@)" will in fact fail. The test against empty string will work though, even in this case. (And by the way, don't throw an Exception::Class error without a message.)

      Maybe I'm not reading your description correctly, or maybe our versions of Exception::Class differ, but I don't see the behavior you're describing. Quite the opposite, in fact. The boolean test sees the exception, but the test against '' can't see it (because it stringifies to '').

      use Exception::Class ( 'MyException' => { description => '' } ); eval { MyException->throw( message => '' ); }; if ($@) { print "I see you, exception class (boolean)!\n"; } else { print "Nothing to see here (boolean).\n"; } if ( $@ ne '' ) { print "I see you, exception class (ne '')!\n"; } else { print "Nothing to see here (ne '').\n"; } __END__ I see you, exception class (boolean)! Nothing to see here (ne '').

      My version is 1.2, and I see this in it:

      use overload # an exception is always true bool => sub { 1 }, '""' => 'as_string', fallback => 1;
        Don't supply a message:
        MyException->throw()
        This seemed like a reasonable thing to do at the time, since I was only looking at the class name, not the message.