2009-05-09 26 views
6

Xem thêm: Where in the documentation does it say that while tests readdir for definedness?. (Không phải là một bản sao, chỉ cần liên quan chặt chẽ.)Kết quả "0" từ readdir() không sai trong điều kiện thời gian như thế nào?


Nhiều người đối xử với các vòng lặp bên dưới là thành ngữ:

while (defined(my $file = readdir($dir)) { 
    ... 
} 

thay vì:

while (my $file = readdir($dir)) { 
    ... 
} 

vì cho là với cái sau phiên bản nếu tên tập tin chỉ là "0" (số không) nó sẽ chấm dứt vòng lặp, trong khi nó trả về 'undef' khi không có tệp nào khác.

Tuy nhiên, tại một số điểm trong quá khứ thử nghiệm này cho defined() dừng là cần thiết - dường như có mã trường hợp đặc biệt cho phép phiên bản thứ hai hoạt động bất kể.

Tôi muốn biết cách hoạt động của tính năng này?

Tò mò, nếu tôi thay thế các cuộc gọi đến readdir() với một cuộc gọi đến foo() thay vì:

sub foo 
{ 
    my ($dir) = @_; 
    return readdir($dir); 
} 

while (my $file = foo($dir)) { 
    ... 
} 

sau đó mã không làm những gì tôi mong đợi, và chấm dứt vòng lặp khi một tập tin có tên là "0 " được tìm thấy.

(được kiểm tra bằng Perl 5.8.9 trên MacOS X 10.5.6)

Trả lời

11

Đó là điều kỳ diệu. Cụ thể trong khi phép thuật (được ghi trong perlsyn, perlop và có thể là những nơi khác mà tôi không nhớ). Perl cho phép bạn ký hiệu viết tắt nhất định. Nếu bạn muốn xem những gì Perl đang làm đằng sau lưng bạn, bạn có thể sử dụng B::Deparse. Đây là một tập tin có sử dụng vòng lặp tốc ký:

#!/usr/bin/perl 

use strict; 
use warnings; 

opendir my $dir, "/tmp" or die "$!"; 

while (my $file = readdir($dir)) { 
    print "$file\n"; 
} 

Nếu bạn chạy perl -MO=Deparse filename.pl bạn lấy mã Perl thấy:

use warnings; 
use strict 'refs'; 
die "$!" unless opendir my $dir, '/tmp'; 
while (defined(my $file = readdir $dir)) { 
    do { 
     print "$file\n" 
    }; 
} 
filename.pl syntax OK 
+3

+1 cho B :: Deparse - sẽ thực sự hữu ích nếu ai đó có thể cung cấp liên kết đến tài liệu cụ thể. Tôi không thể tìm thấy nó trong người đàn ông perlsyn. – Alnitak

+0

Nhấp B :: Deparse cho tài liệu trên đó, nhấp vào perlsyn để được đưa đến phần perlsyn ghi lại hành vi (tìm kiếm "Perl ngắn gọn cho phiên bản được viết rõ ràng hơn:"). Có tài liệu tốt hơn ở đâu đó trong đó nhưng tôi không thể nhớ ở đâu. –

+0

Thêm một liên kết đến phần perlop cũng bao gồm điều này, nhưng vẫn không có tài liệu cụ thể về lý do tại sao readdir được điều trị tương tự. –

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