Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perl Does IO::File work with Autodie?

Tags:

io

perl

I'm trying to understand why IO::File doesn't seem to work with use autodie:

Example #1: Test program using open:

#! /usr/bin/env perl
#
use strict;
use warnings;
use feature qw(say);
use autodie;
use IO::File;

open( my $fh, "<", "bogus_file" );
# my $fh = IO::File->new( "bogus_file", "r" );
while ( my $line = $fh->getline )  {
    chomp $line;
    say qq(Line = "$line");
}

This fails with:

Can't open 'bogus_file' for reading: 'No such file or directory' at ./test.pl line 9

It looks like autodie is working.

Example #2: Same test program, but now using IO::File:

#! /usr/bin/env perl
#
use strict;
use warnings;
use feature qw(say);
use autodie;
use IO::File;

# open( my $fh, "<", "bogus_file" );
my $fh = IO::File->new( "bogus_file", "r" );
while ( my $line = $fh->getline )  {
    chomp $line;
    say qq(Line = "$line");
}

This fails with:

Can't call method "getline" on an undefined value at ./test.pl line 11.

Looks like autodie didn't catch the bad IO::File->new open.

Yet, as far as I can tell, IO::File->new uses open underneath. Here's the code from IO::File:

sub new {
    my $type = shift;
    my $class = ref($type) || $type || "IO::File";
    @_ >= 0 && @_ <= 3
        or croak "usage: $class->new([FILENAME [,MODE [,PERMS]]])";
    my $fh = $class->SUPER::new();
    if (@_) {
        $fh->open(@_)   # <-- Calls "open" method to open file.
            or return undef;
    }
    $fh;
}

sub open {
    @_ >= 2 && @_ <= 4 or croak 'usage: $fh->open(FILENAME [,MODE [,PERMS]])';
    my ($fh, $file) = @_;
    if (@_ > 2) {
        my ($mode, $perms) = @_[2, 3];
        if ($mode =~ /^\d+$/) {
            defined $perms or $perms = 0666;
            return sysopen($fh, $file, $mode, $perms);
        } elsif ($mode =~ /:/) {
            return open($fh, $mode, $file) if @_ == 3;
            croak 'usage: $fh->open(FILENAME, IOLAYERS)';
        } else {
            #  <--- Just a standard "open" statement...
            return open($fh, IO::Handle::_open_mode_string($mode), $file);
        }
    }
    open($fh, $file);
}

What's causing autodie not to work as expected?

like image 477
David W. Avatar asked Jan 20 '15 18:01

David W.


1 Answers

autodie is lexically scoped. Therefore it changes (wraps) calls to open in your file, but not within IO::File.

like image 180
tjd Avatar answered Oct 02 '22 06:10

tjd