Corso di Perl

Lavorare con i files: Leggere e scrivere

 

Imparare a leggere e scrivere

Sappiamo già come aprire files in lettura. Negli esempi che seguiranno, per essere sicuri che stiamo aprendo tutti la stessa cosa, userò un file speciale: il file “$0”. La variabile $0 contiene il nome dello script Perl che stiamo eseguendo in quel momendo. Perciò, se per caso salvate uno script con il nome “prova.pl”, la variabile $0 conterrà proprio “prova.pl”. E niente vieta ad uno script di aprire se stesso (in sola lettura, mi raccomando!) mentre è in esecuzione...
Insomma, abbiamo a disposizione un filehandle tutto per noi. Come facciamo a vedere cosa c’è nel file? Provate ad eseguire questo script:

open (PIPPO, "$0");
print <PIPPO>;
close (PIPPO);

Dovreste vedere come output… il programma stesso! Provate invece così:

open (PIPPO, "$0");
$pippo = <PIPPO>;
print $pippo;
close (PIPPO);


Vedrete scritta solo la prima linea. Se, per sbaglio, il vostro script inizia con una linea vuota, non vedrete niente. Forse però così funziona:

open (PIPPO, "$0");
$pippo1 = <PIPPO>;
$pippo2 = <PIPPO>;
print $pippo1;
print $pippo2;
close (PIPPO);


E adesso le linee stampate sono le prime due! Si accende la lampadina?

Spieghiamo adesso l’arcano:
l’operatore “<>” (ad esempio, <PIPPO>, <FILEHANDLE>) prende il filehandle che sta in mezzo ai due segni di maggiore/minore e prova a leggere il file a cui si riferisce. Se si trova in un contesto scalare, come nel secondo esempio, legge solo una linea (cioè si ferma al primo ritorno a capo). Se si trova in un contesto array, come nel primo esempio (ricordatevi che “print” crea un contesto scalare) legge TUTTO il file e ritorna un array delle singole linee di un file. Se non vi ricordate assolutamente cosa siano i contesti scalare ed array, fate riferimento alla lezione numero 8.

Per vedere meglio come funziona il contesto array in questo caso, provate questo script:

open (PIPPO, "$0");
@pippo = <PIPPO>;
print join("*\n", @pippo);
close (PIPPO);


L’assegnazione ad un array costringe <PIPPO> ad essere valutata in un contesto array, e ciò provoca la lettura dell’intero file e il suo spezzettamento in singole righe, che vanno a formare l’array @pippo.

Vi ricordate dell'istruzione join? Join si aspetta come secondo argomento un array, i cui singoli pezzi vengono uniti con "*\n" e scritti sullo schermo. Dovreste vedere qualcosa del genere:

open (PIPPO, "$0");
*
print join("*\n", <PIPPO>);
*
close (PIPPO);


Cosa vuol dire? L'array è stato unito con  un asterisco e un ritorno a capo, ma ogni stringa dell'array conteneva un ritorno a capo, che è stato fedelmente ristampato! Possiamo toglierli di mezzo, ma dovremmo usare istruzioni che ancora non vi ho spiegato e... insomma, per ora accontentiamoci. Per adesso ricordatevi che, quando leggete un file in questo modo, in fondo ad ogni stringa viene posto il ritorno a capo che è servito a riconoscerla.

Vediamo adesso un esempio su come scrivere in un file:

open (PIPPO, “>pippo.txt”);
print PIPPO "Ciao! \n";
close (PIPPO);

Come vedete, per scrivere su un file si usa la solita istruzione print che usiamo per scrivere sullo schermo. Solo che, stavolta, come primo argomento mettiamo il filehandle che vogliamo utilizzare. In questo modo, la stringa finisce nel file e non sullo schermo.
In effetti, scrivere

print "Ciao!\n";

non è altro che un’abbreviazione per

print STDOUT "Ciao!\n";

dove STDOUT è il filehandle di default che rappresenta lo schermo! Si chiama infatti standard output, ed è un filehandle che viene automaticamente aperto dal Perl all’inizio di ogni script. Esistono anche uno standard input e uno standard error, che non mancheremo di utilizzare nelle prossime lezioni... però voglio mostrarvi questo:

print scalar(<STDIN>);

Fate partire questo script di una linea e scrivete qualcosa sulla tastiera.. niente? Premete invio… ricordatevi che “<>” va avanti fino al primo ritorno a capo! Adesso cercate di indovinare perché ho dovuto scrivere “scalar”…

 

Torna all'indice Generale del corso di Corso di Perl di Software Planet