Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using $@ for error message passing in module

Tags:

perl

I've been working on a fork of a CPAN module which is now unmaintained (as far as I've been able to tell). In this module, they use $@ to pass error messages up the stack. In other words, they set $@ if anything goes wrong in any call to subroutines, and they check after the call to see if it is set. I had never seen this variable before, but I thought it was useful, so I started using it the same way in the code. Now I recently read up a bit more about it, and found that its purpose is a bit more narrow than this. Reading perlvar (and other SO questions on the matter) doesn't fully answer this for me, but, is it OK to use $@ this way? Some "punctuation" variables I know should definitely not be used in such a general-purpose way (some even with local), is this one of those cases, or am I OK continuing this practice?

like image 646
insaner Avatar asked Apr 04 '14 06:04

insaner


1 Answers

$@ is not normally explicitly set. Rather, it is automatically set for you when an exception is raised. From perldoc die:

  • die LIST

    die raises an exception. Inside an eval the error message is stuffed into $@ and the eval is terminated with the undefined value. If the exception is outside of all enclosing evals, then the uncaught exception prints LIST to STDERR and exits with a non-zero value. If you need to exit the process with a specific exit code, see exit.

For example,

#!/usr/bin/perl

eval {
    print "Hi\n";
    die "Something went wrong here";
    print "Bye\n";
};
print $@;

prints

Hi
Something went wrong here at ./cr22854919 line 5.

It is permissible to use $@ to pass error messages up the stack in this way, as a kind of try-catch mechanism. However, since it is a global variable, you should process it as soon as possible after an eval { } block to ensure that no other code interferes with your handling of the exception.


The other magic variable commonly used for error handling is $!, which works like errno in C.

Example:

my $path = "/tmp/no-such-file";
open F, '<', $path
    or print STDERR "$path: $!\n";

Output:

/tmp/no-such-file: No such file or directory
like image 64
Alex Trebek Avatar answered Dec 04 '22 02:12

Alex Trebek