2013-06-29 21 views
8

Die documentation for the open function zeigt die Syntax von open() als:Warum verwendet Perl open() Dokumentation zwei verschiedene FILEHANDLE-Stile?

  • offenem FILEHANDLE, EXPR
  • offene FILEHANDLE, MODE, EXPR
  • offene FILEHANDLE, MODE, EXPR, LIST
  • offener FILEHANDLE, MODE, REFERENCE
  • offen FILEHANDLE

unten in den Beispielen haben sie Orte wo ein normaler $ -prefixed Variable für die Datei-Handle verwendet wird:

open(my $fh, "<", "input.txt") 

und auch Beispiele, bei denen ein Bareword verwendet wird:

open(FOO, "|tr '[a-z]' '[A-Z]'"); 

Eine Frage ist, was der Name jeder Art wie in "ist Ich verwende _ _ für ein Dateihandle "in jedem Fall? Das andere ist, Warum haben sie begonnen, bare Wörter für open() in der Dokumentation zu verwenden? Es scheint, dass die späteren Verwendungen alle nicht normalen Dateinamen beinhalten open() s. Ist das $ -fixierte Formular in diesen Fällen nicht akzeptabel?

+1

große Frage, ich war schon immer verärgert von dieser Syntax – qwwqwwq

+0

Irgendwie ärgerlich zu tun 'offen (STDOUT," | less ")' in irgendeiner anderen Weise als das. – tchrist

Antwort

20

Das Bareword-Formular ist im Wesentlichen nur historisches Erbe für die Abwärtskompatibilität. Die Verwendung einer lexikalischen Variablen ist immer die richtige Sache für neuen Code.

→ übrigens $x ist ein lexikalischer Skalarvariable, wo FOO ist, wie Sie sagten, eine Bareword genannt

Details/Exkurs

Nur der Vollständigkeit halber, wie @Joe_Z wies darauf hin, in die Kommentare, die lexikalischen Dateihandle-Objekte sind "relativ neu", als Teil der ziemlich wichtigen Neuschreibung zwischen Perl 5.005 und 5.6 (sie haben sogar ganze Größenordnungen in dieser Versionsnummer erreicht ...).

Jedoch wird das Bareword FOO (oder beispielsweise STDIN) technisch in einem separaten Namespace nur für Dateihandles interpretiert. Da es keinen sigil (wie $ @ % &) für die Dateikennung Namespace ist, gibt es nur zwei Möglichkeiten, um einen Dateihandle in diesem Namespace zu verweisen:

  • Sie es in dem indirekten Objekt Schlitz bestimmter Funktionen beziehen, wie print, wer (hinter den Kulissen) folgern wird, dass sich ein Bareword aus historischen Gründen auf ein Dateihandle beziehen muss;
  • Sie können einen typeglob wie *FOO verwenden, der sich auf "alles in einem beliebigen Namensraum bezieht, der zufällig an das Symbol FOO gebunden ist.

Beachten Sie, dass in einigen Sprachen wie C oder Schema, ein einzelnes Symbol keine Art sigils hat, und so können alle Symbole nur auf eine Weise gebunden werden (zB kann man nicht eine Variable printf und eine Funktion printf Namen genannt haben in C ... allgemein), während in Perl oder (z) Common Lisp, das gleiche Symbol foo kann an viele verschiedene Dinge gebunden sein; Der Unterschied besteht darin, dass Perl tatsächlich verlangt, dass Sie in den meisten Kontexten sigils verwenden, um zu disambiguieren, "welches foo Sie meinen". $foo, @foo = @foo[ $x .. $y], $foo[ $n ], %foo = @foo{ $k1, $k2 } = $foo{ $k }, &foo und dergleichen.

von Barewords als Handles, aber verlieren Sie einige Fähigkeiten:

Deutlich, um sie lokal oder lexikalisch zu binden (statt global), Sie jedes Symbol in jedem Namensraum binden müssen, weil Es ist kein Siegel verfügbar. So können und my @foo in zwei verschiedenen Scratchpads (Scopes) leben, wobei einer den anderen überlebt; aber my *foo würde sowohl diese als auch das Dateihandle foo (und möglicherweise andere obskure Eckfälle, wie format Spezifizierer, obwohl ich es nicht schwören würde).

Es ist auch ungeheuer schwierig, ein Bareword-Stil-Dateihandle in eine Funktion und dergleichen zu übergeben.

Grundsätzlich erben Barcodes alle Nachteile des globalen Gültigkeitsbereichs und haben keinen der Vorteile von lexikalischen Variablen.

perldoc perldata hat einen schönen Abschnitt über Typeglobs und Dateihandles, die diese Dinge wahrscheinlich auch etwas deutlicher erklärt. Ich habe meine Kopie nicht griffbereit, aber ich glaube, die Kamel geht auch detaillierter auf das Thema ein.

+5

+1: Die Verwendung von lexikalischen Datei-Handles ist "der Weg, es zu tun", obwohl es Perl ist, also TMTOWTDI (es gibt mehr als eine Möglichkeit, es zu tun). –

+1

@ JonathanLeffler beides, ein starker Punkt und ein Fehler. – jordanm

+0

coz Ich bin ein bisschen alt skool Ich habe gelegentlich verwendet Glob Style-Dateihandles in Antworten und immer negative Kommentare zu bekommen :) Stimmen Sie zu, dass lexikalische Dateihandles sind besser, aber es ist eine harte Gewohnheit zu brechen! – Vorsprung

2

Wie BPRocock sagte my $x in diesen Tagen bevorzugt wird, während FOO veraltet angesehen wird, weil FOO eine Art globale Variablen ist, damit es mit Namen an einem anderen Ort verwendet in Konflikt geraten könnte. Es gibt einen anderen Grund $x wird empfohlen: $x wird automatisch close Ed am Ende des Bereichs sein.