2012-11-27 1 views
14

Utilizzo l'operatore di diamante Perl<> per leggere dai file specificati sulla riga di comando.Quale file è l'operatore di diamante Perl (handle di file null) che sta leggendo attualmente?

Mi piacerebbe essere in grado di segnalare messaggi come "Trouble on line $. of file $FILENAME", ma come posso dire quale file è attualmente utilizzato dal diamante?

+0

Il problema percepito con "pacchetti esterni" è frustrante e assurdo. La maggior parte dei moduli Perl sono solo file sorgente con un'estensione '.pm', e non è necessario alcun processo di installazione.Per impostazione predefinita, '@ INC' include la directory corrente come' .', quindi copiare i file necessari nella stessa directory dell'origine renderà il pacchetto disponibile e soddisferà la dipendenza. – Borodin

+0

@Borodin se qualcosa è disponibile direttamente nella lingua, preferisco saperlo. Così semplice. – PypeBros

+0

Sarebbe perverso raccomandare una soluzione che richiede di scaricare e installare un modulo Perl se lo stesso effetto potrebbe essere ottenuto senza. La tua preferenza dichiarata assomiglia molto al comune incantesimo che una * soluzione * non deve implicare l'installazione di un modulo, il che smentisce il fatto che qualsiasi cosa copiata da una soluzione Stack Overflow sia anche * "esterna" *. Dovresti anche ricordare che ci sono molti moduli * core * che sono installati con Perl di default, e sarebbe duro richiedere una soluzione che li escludesse. – Borodin

risposta

17

Vedi perlvar:

$ARGV 

Contains the name of the current file when reading from <> . 

ma prendere in considerazione anche $. in perlvar. Se lo fai con perl -n, potrebbe non essere come desideri, perché il contatore non viene ripristinato nel caso d'uso perl -n.

$. 

numero di riga corrente per l'ultimo filehandle accesso.

Ogni filehandle in Perl conta il numero di linee che sono state lette da esso. (A seconda del valore di $/, l'idea di Perl di ciò che costituisce una linea potrebbe non corrispondere la vostra.) Quando una linea viene letta da un filehandle (via readline() o <>), o quando tell() o seek() si chiama su di esso, $. diventa un alias per il contatore di riga per quel filehandle.

È possibile regolare il contatore assegnando a $., ma questo non sarà effettivamente spostare il puntatore di ricerca. La localizzazione di $. non localizzerà il conteggio delle righe del filehandle . Invece, localizzerà la nozione di perl di a cui il filehandle $. è attualmente sottoposto a aliasing.

$. viene ripristinato quando il filehandle viene chiuso, ma non quando viene riaperto un file handle aperto senza intervenire close(). Per ulteriori dettagli su , consultare Operatori di I/O in perlop. Poiché <> non esegue mai una chiusura esplicita , i numeri di riga aumentano tra i file ARGV (ma vedi esempi in eof).

È inoltre possibile utilizzare HANDLE->input_line_number(EXPR) per accedere al contatore di linea per un determinato filehandle senza doversi preoccupare di quale gestisce l'ultimo accesso.

Mnemonico: molti programmi utilizzano "." per indicare il numero della linea corrente.

Ecco un esempio:

$ perl -nE 'say "$., $ARGV";' foo.pl bar.pl 
1, foo.pl 
2, foo.pl 
3, foo.pl 
4, foo.pl 
5, foo.pl 
6, foo.pl 
7, foo.pl 
8, foo.pl 
9, foo.pl 
10, foo.pl 
11, foo.pl 
12, foo.pl 
13, bar.pl 
14, bar.pl 
15, bar.pl 

Se si vuole azzerare, è necessario verificare la presenza di eof alla fine del ciclo di lettura (grazie @Borodin). Vedi anche lo perldoc for eof:

+0

sì. Sapevo di $. già. Grazie per $ ARGV: per qualche ragione, mi è sfuggito di vista. – PypeBros

+0

@sylvainulg guarda l'esempio, mi ha confuso molto. Non viene ripristinato se l'handle viene riaperto su un altro file. – simbabque

+0

ok, quindi potrei voler fare '$. = 1 se $ ARGV ne $ lastfilename' per evitare di confondere gli utenti ... – PypeBros