Frage

Siehe auch: Wo in der Dokumentation heißt es, dass während Tests auf Definitionstests testet?. (Kein Duplikat; Nur eng verwandt.)


Viele Menschen behandeln die unten stehende Schleife als idiomatisch:

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

Anstatt von:

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

Denn angeblich mit der letzteren Version, wenn der Dateiname nur "0" (Null) ist, sollte er die Schleife beenden, während er 'undef' zurückgibt, wenn keine Dateien mehr vorhanden sind.

Irgendwann in der Vergangenheit dieses Tests für defined() Hör auf notwendig zu sein - es scheint Sonderfallcode zu geben, mit dem die letztere Version trotzdem funktioniert.

Ich würde gerne wissen, wie das funktioniert?

Seltsamerweise ersetze ich den Anruf an readdir() mit einem Anruf bei foo() stattdessen:

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

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

dann der Code tut Tun Sie, was ich erwarten würde, und beenden Sie die Schleife, wenn eine Datei namens "0" gefunden wird.

(getestet mit Perl 5.8.9 auf macOS x 10.5.6)

War es hilfreich?

Lösung

Es ist Magie. Speziell während der Magie (dokumentiert in perlsyn, perlop, und wahrscheinlich an andere Orte, an die ich mich nicht erinnere). Perl erlaubt Ihnen bestimmte Kurznotationen. Wenn Sie sehen möchten, was Perl hinter Ihrem Rücken tut B::Deparse. Hier ist eine Datei, die die Kurzschleife verwendet:

#!/usr/bin/perl

use strict;
use warnings;

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

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

Wenn du läufst perl -MO=Deparse filename.pl Sie erhalten den Code, den Perl sieht:

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
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top