My Favorite Modules: Errno

The open or die idiom is fairly ubiquitous in Perl. To be useful, the exception should say something about what went wrong: open ... or die "Open error: $!", for example.

The $! built-in variable (a.k.a. $ERRNO or $OS_ERROR if use English; is in effect) gives you access to the C language errno variable, which through the magic of Perl interpolates an error message appropriate to the error given.

But there are times when some error analysis is in order. Fortunately, $! is a dualvar, so if you access it in numeric context rather than string context, you get the actual numeric value of the error code. But for both portability and maintainability you don't want to compare $! to a numeric literal. Thus, Errno. For example:

use Errno ':POSIX';

open my $foo, '<:encoding(utf-8)', 'foo/bar'
or do {
if ( $! == ENOENT ) { # File not found
die 'Could not find foo/bar';
} else {
die "Could not open foo/bar: $!";
}
};

Because this is Perl, There Is More Than One Way To Do It. The %! hash is keyed by errno symbols, with the element corresponding to the most-recent error being true:

# warn q/$INC{'Errno.pm'} is /, $INC{'Errno.pm'}, "\n";
open my $foo, '<:encoding(utf-8)', 'foo/bar'
  or do {
    if ( $!{ENOENT} ) { # File not found
      die 'Could not find foo/bar';
    } else {
      die "Could not open foo/bar: $!";
    }
  };

Note that Perl loads Errno implicitly when it sees a use of %!. This can be demonstrated by uncommenting the initial warn statement in the snippet.

Previous entries in this series:

  1. if
  2. diagnostics
  3. Term::ReadLine::Perl
  4. re
  5. Devel::NYTProf

Leave a comment

About Tom Wyant

user-pic I blog about Perl.