كيف تكون "0" الناتجة عن ReadDir () ليست خاطئة في حالة من الوقت؟

StackOverflow https://stackoverflow.com/questions/843430

سؤال

أنظر أيضا: أين في الوثائق يقول أنه بينما اختبارات ReadDir للخصم؟. (ليس مكرر فقط مرتبط ارتباطا وثيقا.)


كثير من الناس يعاملون الحلقة أدناه على أنها اصطلاح:

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

بدلاً من:

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

لأنه من المفترض مع الإصدار الأخير إذا كان اسم الملف هو "0" (صفر) ، يجب أن ينهي الحلقة ، في حين أنه يعيد "undef" عندما لا يكون هناك المزيد من الملفات.

ولكن في مرحلة ما من الماضي هذا الاختبار defined() توقف عن الضرورة - يبدو أن هناك رمز حالة خاص يسمح للإصدار الأخير بالعمل بغض النظر.

أود أن أعرف كيف يعمل هذا؟

من الغريب ، إذا استبدلت المكالمة readdir() مع دعوة إلى foo() في حين أن:

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

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

ثم الرمز يفعل افعل ما كنت أتوقعه ، وإنهاء الحلقة عند العثور على ملف يسمى "0".

(تم اختباره مع Perl 5.8.9 على MacOS X 10.5.6)

هل كانت مفيدة؟

المحلول

إنه سحر. على وجه التحديد أثناء توثيقه (موثق في perlsyn, perlop, ، وربما أماكن أخرى لا أتذكرها). يتيح لك Perl بعض الرموز المختصرة. إذا كنت تريد أن ترى ما الذي يفعله بيرل خلف ظهرك ، يمكنك استخدامه B::Deparse. فيما يلي ملف يستخدم حلقة الاختزال:

#!/usr/bin/perl

use strict;
use warnings;

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

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

اذا ركضت perl -MO=Deparse filename.pl تحصل على الرمز الذي يرى بيرل:

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
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top