PROGRAMMAZIONE CON PERL


INDICE DEGLI ARGOMENTI




2. Introduzione al Perl

In questo capitolo eviteremo di approfondire la trattazione teorica degli argomenti, per cercare di dare una visione sintetica ed orientata ad aspetti più prettamente pratici e sintattici, che ci possano introdurre all'uso del linguaggio.


2.1. Finalità del Perl

Il Perl (Processing Estraction Report Language) è un linguaggio finalizzato principalmente alla trattazione di stringhe e file di testo. Ciò che in Perl è estremamente naturale fare è effettuare ricerche di sequenze di caratteri all'interno di stringhe (pattern matching), sostituzioni di sottostringhe (pattern substitution), operazioni su file di testo strutturati in campi e record oppure non strutturati.

Per questi motivi il Perl è utilizzato pesantemente nella scrittura di procedure CGI installate su un server web, o per lo sviluppo di procedure di manutenzione delle attività di un server. Per gli stessi motivi il Perl non è invece indicato per sviluppare procedure di puro calcolo scientifico o comunque programmi che richiedano una elevata velocità e precisione nell'effettuare calcoli o elaborazioni numeriche complesse.

2.2. Intestazione di un programma

Abbiamo detto che il Perl è un linguaggio interpretato, quindi ogni script in Perl richiede di essere lanciato attraverso l'interprete per poter essere eseguito. Consideriamo il seguente esempio elementare, costituito da un'unica riga di programma:

print "Salve a tutti\n";

Innanzi tutto dovremo scrivere questo 'programma' con un editor su un file di testo, quindi, una volta salvato il file su disco, ad esempio con il nome salve.pl, potremo passarlo all'interprete attraverso il comando:

$ perl salve.pl
Salve a tutti
$ _

Questo comando comunica al sistema di lanciare l'interprete Perl e di passargli come input il contenuto del file salve.pl. L'output del programma viene visualizzato sul terminale dell'utente, quindi lo script termina e viene visualizzato nuovamente il prompt del sistema. La sequenza di controllo '\n' inserita alla fine del messaggio da stampare indica all'interprete di inserire un ritorno a capo (newline) in quella posizione.

Un modo più comodo per richiamare l'interprete Perl ed eseguire un certo script è quello di specificare direttamente nell'intestazione dello script il nome dell'interprete che dovrà eseguirlo. La sintassi da utilizzare è in questo caso quella consueta degli shell-script UNIX. Supponiamo ad esempio che l'interprete Perl sia il file /usr/local/bin/perl; il nostro programmino potrà essere riscritto nel modo seguente:

#!/usr/local/bin/perl
print "Salve a tutti\n";

La prima riga del file inizia con la sequenza '#!' (cancelletto e punto esclamativo) seguita dal nome dell'interprete che dovrà eseguire il programma. Affinché la shell UNIX possa eseguire lo script, dovranno essere impostati i diritti di esecuzione su questo file con il comando chmod. Ad esempio, supponiamo di voler rendere eseguibile il nostro script per tutti gli utenti del sistema, consentendo anche a chiunque di leggere il contenuto del file, ma riservando il diritto di modificare lo script solo al proprietario del file stesso. Il comando da impartire sarà il seguente:

$chmod 755 salve.pl

$_

Per eseguire lo script a questo punto sarà sufficiente digitarne il nome:

$ salve.pl
Salve a tutti
$_

2.3. Istruzioni di base

Abbiamo già visto l'istruzione print, che ci permette di stampare l'output dei nostri script. Questa istruzione è piuttosto potente e permette di formattare l'output in vari modi utilizzando una serie di caratteri di controllo che vedremo in maggiore dettaglio nelle prossime pagine.

Le variabili scalari in Perl sono precedute da un simbolo ``$'', in modo da distinguerle da liste ed array. Il Perl non distingue tra variabili numeriche e stringhe: su entrambe è consentito fare le stesse operazioni, lasciando all'interprete il compito di assegnare un valore numerico o stringa al contenuto delle variabili a seconda del contesto in cui queste sono usate.

Il seguente script è una banale evoluzione dello script precedente:

#!/usr/local/bin/perl
# semplice script di esempio
$nome = "Marco";
print "Buongiorno $nome\n";

Il cancelletto è utilizzato in Perl per introdurre delle linee di commento; quindi dopo un simbolo '#' potete inserire ogni tipo di commento che possa aiutare voi o qualcun altro a comprendere anche a distanza di tempo il funzionamento dello script. L'interprete Perl eviterà di analizzare e di tradurre ogni parola che segue il simbolo '#' fino alla fine della riga.

L'istruzione complementare a quella di stampa è quella di lettura, che consente di assegnare alle variabili dello script dei valori digitati dall'operatore o letti da un file. Il seguente programmino è una ulteriore evoluzione dell'esempio precedente e fa uso dell'istruzione di lettura:

#!/usr/local/bin/perl
# un altro esempio elementare
print "Come ti chiami? ";
$nome = <STDIN>;
print "Buongiorno $nome\n";

Lanciando in esecuzione quest'ultima versione del programma salve.pl, il sistema ci chiede di inserire il nostro nome mediante la tastiera del terminale, e quando avremo battuto RETURN per segnalare la fine del nostro inserimento, visualizzerà il consueto messaggio di buongiorno. Il simbolo <STDIN> è infatti l'handler del file di input standard, un file sempre aperto in lettura durante tutta l'esecuzione del programma e che rappresenta generalmente la tastiera del terminale dell'utente. Con l'istruzione $nome=<STDIN> si assegna alla variabile $nome la linea di input proveniente dal canale di input standard, compreso il carattere di 'fine riga'.

$ salve.pl
Come ti chiami? Marco
Buongiorno Marco
$ _

È possibile redirigere il contenuto di un file attraverso il canale dello standard input utilizzando le funzionalità di redirezione e di piping messi a disposizione dalla shell di comandi del sistema operativo. Ad esempio supponiamo di aver creato un file di testo (chiamato nome) con il nostro editor, in cui abbiamo inserito soltanto una parola, ad esempio 'Marco'. Allora potremo redirigere il contenuto di questo file verso il canale di input standard del nostro programma, nel seguente modo:

$ salve.pl < nome
Come ti chiami? Buongiorno Marco
$ _

Allo stesso modo in cui redirigiamo l'input standard, possiamo anche redirigere verso un file il canale di output standard, in modo da memorizzare su file ogni messaggio che il nostro programma avrebbe altrimenti visualizzato sullo schermo del terminale. Il seguente comando non produce alcun output:

$ salve.pl < nome > output
$ _

Infatti ciò che il programma doveva leggere in input gli è stato passato attraverso il file nome, mentre l'output è stato scritto nel file output.

2.4. Input/output su file

I canali standard di comunicazione di ogni programma sono tre e ad ognuno di questi è associato un handler:

<STDIN> standard input
<STDOUT> standard output
<STDERR> standard error
Tab. 1: I file handler standard

Così come ogni input avviene di default attraverso <STDIN>, così anche l'output viene emesso attraverso <STDOUT>; in alcuni casi è opportuno dichiarare esplicitamente il canale di output:

print STDOUT "Buongiorno $nome\n";

Il canale <STDERR> è simile a <STDIN>, ma viene solitamente utilizzato per visualizzare i messaggi di errore in modo tale che, se anche lo standard output è rediretto attraverso un file, il messaggio di errore viene visualizzato ugualmente sul terminale dell'utente o sulla console del sistema.

Oltre a questi file handler standard che non è necessario aprire o chiudere esplicitamente, è possibile aprire anche un canale di comunicazione verso un normale file di testo sull'unità di memoria di massa.

Prima di poterlo utilizzare, un file deve essere aperto dichiarandone anche l'uso che se ne intende fare: il file infatti può essere aperto in modalità differenti:

read: open(handle, "<nome") si possono effettuare solo operazioni di lettura dal file specificato;
write: open(handle, ">nome") si possono effettuare soltanto operazioni di scrittura sul file; se il file già esiste verrà cancellato e ne verrà creato uno nuovo;
append: open(handle, ">>nome") si possono effettuare solo operazioni di scrittura aggiungendo dati in coda al file; se il file già esiste in questo caso non verrà cancellato, se non esiste verrà creato.
Tab. 2: Modalità di apertura di un file

Il seguente script legge tutte le linee di un file di testo e le visualizza sullo schermo del terminale. Viene fatto uso della struttura di controllo while che ancora non è stata descritta; per il momento basti sapere che questa struttura consente di ripetere un certo blocco di istruzioni fintanto che una certa condizione non risulta verificata.

#!/usr/local/bin/perl
# simpcat.pl: versione semplificata di 'cat'
print STDERR "nome del file: ";
$filename = <STDIN>;
open(FILE, "< $filename");
while (!eof(FILE)) {
  $riga = <FILE>;
  print "$riga";
}

Al solo scopo di cominciare ad introdurre alcuni dei comandi che diventeranno di uso comune nelle prossime pagine, possiamo riscrivere in maniera equivalente lo script precedente come segue:

#!/usr/local/bin/perl
# simpcat.pl: versione semplificata di 'cat'
$filename = $ARGV[0];
open(FILE, "< $filename") || die "Errore!\n\n";
while ($riga = <FILE>) {
  print "$riga";
}

Nel primo esempio il programma chiede di inserire il nome del file da visualizzare, mentre nel secondo caso si aspetta che il nome gli venga passato come parametro. Inoltre, nella seconda versione, se il file risulta impossibile da aprire lo script visualizza il messaggio 'Errore!' e l'esecuzione ha termine.

Già da queste due versioni equivalenti di un esempio così elementare si intravede la grande libertà lasciata dal Perl al programmatore: non c'è mai un solo modo per compiere una certa operazione in Perl.



Capitolo 3



(C) 2000 for spaRtan