Frage

Ich habe einigen schrecklichen Code gesehen in Perl geschrieben, aber ich kann nicht machen Kopf noch Schwanz dies ein:

select((select(s),$|=1)[0])

Es ist in einigem Netzwerk-Code, den wir mit einem Server zu kommunizieren und ich nehme an, es ist etwas mit Pufferung zu tun (da es setzt $|).

Aber ich kann nicht herausfinden, warum mehrere select Anrufe es gibt oder die Array-Referenz. Kann mir jemand helfen?

War es hilfreich?

Lösung

Es ist ein böses kleines Idiom für Autoflushing auf einem Dateihandle andere als STDOUT Einstellung.

select() nimmt den mitgelieferten Dateihandle und (im Wesentlichen) ersetzt STDOUT mit ihm, und es gibt die alte Dateihandle, wenn es fertig ist.

So (select($s),$|=1) die Dateikennung umleitet (erinnern Sie select die alte zurück) und setzt Autoflushing ($| = 1). Er tut dies in einer Liste ((...)[0]) und gibt den ersten Wert (die das Ergebnis des select Anrufs ist - das Original STDOUT), und dann geht die , die zurück in einer anderen select die ursprüngliche STDOUT Dateihandle wieder einzusetzen . Puh.

Aber jetzt Sie verstehen es (na ja, vielleicht;)), dies zu tun, statt:

use IO::Handle;
$fh->autoflush;

Andere Tipps

Die Art und Weise einen Code, um herauszufinden, ist es auseinander zu pflücken. Sie wissen, dass Sachen in Klammern vor dem Material geschieht außerhalb. Dies ist die gleiche Art und Weise Sie heraus würde herauszufinden, welcher Code in anderen Sprachen tut.

Das erste Bit ist dann:

( select(s), $|=1 )

Diese Liste hat zwei Elemente, die die Ergebnisse von zwei Operationen sind: eine der s Dateihandle als Standard wählen und anschließend auf einer $| auf einen wahren Wert gesetzt. Die $| ist eine der pro-Dateihandle Variablen, die nur auf die aktuell ausgewählte Dateihandle anwenden (siehe Verstehen Sie globale Variablen in Die effektiven Perler ). Am Ende haben Sie eine Liste aus zwei Elementen:. Die vorherige Standarddateihandle (das Ergebnis der select) und 1

Der nächste Teil ist eine wörtliche Liste Scheibe das Produkt in dem Index ziehen 0:

( PREVIOUS_DEFAULT, 1 )[0]

Das Ergebnis davon ist das einzige Element, das vorherige Standarddateihandle ist.

Der nächste Teil nimmt das Ergebnis der Scheibe und nutzt es als Argument für einen anderen Anruf select

 select( PREVIOUS_DEFAULT );

So in der Tat, haben Sie $| auf einem Dateihandle gesetzt und am Ende wieder da, wo Sie mit der Standard-Dateikennung gestartet.

select($fh)

Wählen Sie einen neuen Standard-Datei-Handle. Siehe http://perldoc.perl.org/functions/select.html

(select($fh), $|=1)

Schalten Sie Autoflushing. Siehe http://perldoc.perl.org/perlvar.html

(select($fh), $|=1)[0]

Gibt den ersten Wert dieses Tupels.

select((select($fh), $|=1)[0])

select es, das heißt die alte Standard-Datei-Handle wiederherstellen.


Entspricht

$oldfh = select($fh);
$| = 1;
select($oldfh);

, was bedeutet,

use IO::Handle;
$fh->autoflush(1);

, wie in der Perldoc Seite gezeigt.

In einem anderen Veranstaltungsort, schlug ich einmal, dass eine verständlichere Version wäre also:

for ( select $fh ) { $| = 1; select $_ }

Auf diese Weise bleibt der einzige Vorteil des kompakten Idiom, dass keine variablen Bedürfnisse in den umgebenden Rahmen deklariert werden.

Oder wenn Sie mit $_ nicht bequem sind, können Sie es wie folgt schreiben:

for my $prevfh ( select $fh ) { $| = 1; select $prevfh }

Der Umfang der $prevfh ist mit dem for Block begrenzt. (Aber wenn Sie Perl schreiben Sie haben wirklich keine Entschuldigung über $_ schreckhaft zu sein.)

Es ist übermäßig klug Code zum Einschalten Pufferspülung am Griff s und dann erneut die Auswahl des aktuellen Griffes.

Siehe perldoc -f select für mehr.

Bitte überprüfen Sie perldoc -f wählen . Zur Bedeutung von $|, überprüfen Sie bitte Perldoc perlvar

Es ist overoptimization überspringen IO Laden :: Handle.

use IO::Handle;
$fh->autoflush(1);

ist viel besser lesbar.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top