2015-01-20 15 views
6

Tôi đang cố gắng để hiểu tại sao IO::File dường như không làm việc với use autodie:Perl Does IO :: File có hoạt động với Autodie không?

Ví dụ # 1: Kiểm tra chương trình sử dụng 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"); 
} 

này không thành công với:

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

Có vẻ như autodie đang hoạt động.

Ví dụ # 2: chương trình thử nghiệm tương tự, nhưng bây giờ sử dụng 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"); 
} 

này không thành công với:

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

Hình như autodie không bắt xấu IO::File->new mở.

Tuy nhiên, theo như tôi có thể biết, IO::File->new sử dụng open bên dưới. Đây là mã từ 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); 
} 

Điều gì gây ra autodie không hoạt động như mong đợi?

+5

Sự hiểu biết của tôi là 'autodie' được lexically scoped. Do đó nó thay đổi các cuộc gọi thành 'mở' trong tệp của bạn, nhưng không thay đổi trong IO :: Tệp. – tjd

+0

Tôi muốn Perldoc cụ thể hơn một chút - hoặc là «IO :: File' hoặc« autodie' Perldoc. Autodie cho biết phạm vi từ vựng của nó, nhưng sau đó đi trước để cho thấy cách sử dụng nó trong các khối. Cảnh báo cũng bị lốm đốm một cách lố bịch, nhưng tôi đoán tôi đã không nhận ra điều đó trước đây. Cảm ơn câu trả lời của bạn. Nó làm cho việc sử dụng 'autodie' hữu ích hơn một chút. –

+0

@David W., Cái gì? Không. Autodie sẽ hoàn toàn vô ích nếu nó là tất cả hoặc không có gì cho toàn bộ thông dịch viên của bạn. – ikegami

Trả lời

5

autodie bị lốm đốm. Do đó, các cuộc gọi này sẽ thay đổi (kết thúc tốt đẹp) thành open trong tệp của bạn, nhưng không phải trong phạm vi IO::File.

Các vấn đề liên quan