2013-06-29 9 views
8

Il documentation for the open function mostra la sintassi di open() come:Perché la documentazione Perl open() utilizza due diversi stili FILEHANDLE?

  • FILEHANLDE aperto, ESPR
  • aperto FILEHANDLE, MODE, ESPR
  • aperto FILEHANDLE, MODE, ESPR, LISTA
  • aperto FILEHANDLE, MODE, avente
  • aperta FILEHANDLE

giù negli esempi che hanno posti dove una normale variabile $ -prefixed viene utilizzato per l'handle di file:

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

e anche esempi in cui viene usato un bareword:

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

Una domanda è qual è il nome di ogni stile come in " Sto usando _ _ per un filehandle "in ogni caso? L'altro è, , perché hanno iniziato a utilizzare le parole nude per open() nella documentazione? Sembra che gli usi successivi non implichino il normale nome file open() s. Il modulo $ -prefixed non è accettabile in quelle istanze?

+1

ottima domanda, sono sempre stato irritato da quella sintassi – qwwqwwq

+0

Un pò fastidioso da fare 'aprire (STDOUT," | less ")' in qualsiasi altro modo. – tchrist

risposta

20

Il modulo bareword è essenzialmente un retaggio storico per compatibilità con le versioni precedenti. Usare una variabile lessicale è praticamente sempre la cosa giusta da fare nel nuovo codice.

→ per inciso, è un $x lessicale variabile scalare , dove FOO è, come hai detto, ha chiamato un bareword

Dettagli/Digressione

Solo per completezza, come ha sottolineato nel @Joe_Z i commenti, gli oggetti lessicali di filehandle sono "relativamente nuovi", come parte della riscrittura piuttosto importante tra Perl 5.005 e 5.6 (hanno persino guadagnato interi ordini di grandezza in quel numero di versione ...).

Tuttavia, tecnicamente, la parola chiave FOO (o, ad esempio, STDIN) viene interpretata in uno spazio dei nomi separato solo per i filehandle. Dal momento che non v'è un sigillo (come $ @ % &) per lo spazio dei nomi filehandle, ci sono solo due modi per fare riferimento a un filehandle in quel namespace:

  • È possibile fare riferimento ad esso nello slot indiretta oggetto di alcune funzioni, come print, chi (dietro le quinte) intende dedurre che una parola chiave deve fare riferimento a un filehandle, per ragioni storiche;
  • È possibile utilizzare un typeglob, ad esempio *FOO, che fa riferimento a "qualsiasi cosa in qualsiasi spazio dei nomi che si trova associato al simbolo FOO.

Si noti che in alcune lingue, come il C o Scheme, un unico simbolo non ha un tipo sigilli, e così tutti i simboli può essere legato in un solo modo (ad esempio, non si può avere una variabile denominata printf e una funzione denominata printf in C ... generalmente), mentre in Perl o (es) Common Lisp, lo stesso simbolo foo può essere associato a molte cose diverse; la distinzione è che Perl in realtà richiede l'uso di sigilli per disambiguare "quale foo vuoi dire" nella maggior parte dei contesti. $foo, @foo = @foo[ $x .. $y], $foo[ $n ], %foo = @foo{ $k1, $k2 } = $foo{ $k }, &foo e simili.

Utilizzando bareword come filehandle, però, si perde alcune abilità:

in modo significativo, al fine di impegnare in locale o lessicalmente (anziché a livello globale), è necessario legare ogni simbolo in ogni spazio dei nomi, perché non c'è sigillo disponibile. Pertanto, my $foo e my @foo possono vivere in due diversi scratchpad (ambiti), dove forse uno sopravvive all'altro; ma my *foo includerebbe entrambi, così come il filehandle foo (e potenzialmente altri casi d'angolo oscuri, come gli specifiers format, anche se non lo giurerei).

È anche estremamente difficile passare un filehandle in stile bareword in una funzione e simili.

Fondamentalmente, le bareword ereditano tutti i lati negativi dello scope globale e non presentano nessuno dei vantaggi delle variabili lessicali.

perldoc perldata ha una bella sezione sul Typeglob e Filehandle che probabilmente spiega queste cose un po 'più chiaro, pure. Non ho la mia copia a portata di mano, ma credo che anche la Camel entri più in dettaglio sull'argomento.

+5

+1: l'uso di handle di file lessicali è "il modo per farlo" anche se è Perl così TMTOWTDI (c'è più di un modo per farlo). –

+1

@JonathanLeffler sia un punto di forza sia un difetto. – jordanm

+0

coz Sono uno skool un po 'vecchio Ho occasionalmente usato i filehand in stile glob nelle risposte e invariabilmente ottengo commenti negativi su questo :) Accetto che i filehandle lessicali siano migliori ma è una dura abitudine da rompere! – Vorsprung

2

Come BPRocock detto, my $x è preferito in questi giorni, mentre FOO è considerato obsoleto perché FOO è una sorta di variabili globali in modo che possa entrare in conflitto con i nomi utilizzati in un altro luogo. C'è un altro motivo per cui $x è incoraggiato: $x sarà automaticamente close ed alla fine dell'ambito.