Perl (acronimo di Practical Extraction and Report Language), รจ un linguaggio versatile che puรฒ essere utilizzato sia per scivere applicativi lato server (ed in particolare scripts CGI) che per creare software piรน avanzati compatibili con i file system dei piรน diffusi sistemi operativi in circolazione.
Questo linguaggio รจ stato ideato dallo sviluppatore Larry Wall seguendo due principi fondamentali: il primo si basa sul motto "Thereโs more than one way to do it", cioรจ "Esiste piรน di un modo per ottenere uno stesso risultato"; il secondo si basa sullโesigenza di mettere a disposizione degli sviluppatori un semplice strumento con cui poter produrre applicativi senza far ricorso a linguaggi troppo avanzati.
Alla luce dellโevoluzione di cui il Perl ha goduto in questi anni, possiamo dire che i due principi fondanti che hanno ispirato lโautore sono stati pienamente rispettati. Esso permette di affrontare diverse metodologie di approccio per la soluzione delle problematiche di sviluppo e, nello stesso tempo, di creare applicativi in modo piรน semplice e veloce di quanto non consentano altri linguaggi piรน ostici come C e C++.
Per essere chiari, Perl non รจ un "concorrente" degli ultimi due linguaggi citati, ma una risorsa a cui ricorrere quando vogliamo creare applicativi per cui sarebbe "frustrante" affrontare lunghe sessioni di lavoro in C e C++. Quindi, per citare Larry Wall, se siete "pigri" e "impazienti", Perl รจ il linguaggio che fร per voi.
Procurarsi Perl non รจ difficile, lo troverete disponibile gratuitamente nella sezione download di Perl.org; al momento, lโultima versione stabile รจ la 5.8.7 e puรฒ essere utilizzata sia nel sua ambiente naturale, UNIX, che in altri sistemi diffusi con Linux, MAC e Windows.
Lโinstallazione e la configurazione di Perl non presentano alcuna difficoltร : se utilizzate Linux, nella stragrande maggioranza dei casi esso sarร giร installato e pronto da utilizzare; se utilizzate Windows, potrete procurarvi lโapposito pacchetto auto-installante allโindirizzo indicato e seguire la procedura guidata.
Perl รจ un linguaggio Open Source, questo significa che il suo codice sorgente รจ "aperto" a chiunque, dotato di capacitร e di buona volontร , voglia partecipare volontariamente al suo sviluppo.
Nelle pagine che seguiranno descriveremo le basi di questo linguaggio cercando di introdurre logiche, meccanismi e costrutti che stanno alla base del Perl.
Il nostro primo script in Perl
La sintassi del Perl รจ estremamente semplice, il lettore non avrร quindi particolari difficoltร nel comprendere la funzione del breve esempio di scripting che proponiamo nelle righe seguenti:
#!/usr/local/bin/perl
#
# Il nostro primo script in Perl
#
print 'Funziona!';
Analizziamo il nostro piccolo applicativo nelle sue singole parti. Innanzitutto, abbiamo una parte introduttiva che รจ presente in tutti gli script creati con Perl:
#!/usr/local/bin/perl
La sintassi in certi casi puรฒ variare a seconda delle impostazioni del file system presenti nella macchina utilizzata, in Windows potrebbe essere per esempio "#!C:\perl\bin\perl.exe", ma la logica di base รจ sempre la stessa. Questa stringa, riferita al precorso in cui si trova lโesecutore del Perl, comunica unโistruzione al sistema operativo indicandogli quale operazione svolgere nel momento in cui il file contenente il codice deve essere eseguito; nello specifico, la riga introduttiva eprime un comando che invia il file ".pl" (chiamiamolo come vogliamo, "funziona.pl" vร benissimo, conta lโestensione) allโesecutore Perl.
In secondo luogo, introduciamo i commenti, unโopportunitร importante e troppo spesso trascurata per tenere continuamente traccia dei vari passaggi utilizzati in sede di digitazione del codice; i commenti non vengono eseguiti nรจ vengono visualizzati, sono semplicemente dei pro-memoria utili per ricordare dove e perchรฉ abbiamo inserito determinati frammenti di listato.
I commenti, vengono introdotti tra le righe di uno script attraverso il simbolo del cancelletto (#), questโultimo deve precedere i commenti, tutto ciรฒ che si trova compreso tra il cancelletto e la fine della riga non dovrร essere eseguito nรจ stampato a video. La riga introduttiva in cui viene passato il file allโesecutore Perl, costituisce naturalmente unโeccezione in quanto, nonostante sia preceduta dal cancelletto, viene comunque eseguita. Se si desidera scrivere di seguito piรน righe di commenti, sarร necessario inserire allโinizio di ogni riga un cancelletto come nellโesempio che proponiamo di seguito:
#!/usr/local/bin/perl
#
# commento
# commento
# commento
#
istruzione;
Eโ molto importante non dimenticarsi di porre il simbolo del cancelletto allโinizio di ogni commento, diversamente lโesecutore del Perl potrebbe interpretare quanto scritto come parte integrante del codice e restituire un errore.
Passiamo ora alla parte finale del nostro piccolo script, si tratta di unโistruzione che determina in output la visualizzazione di una breve stringa di testo:
print 'Funziona!';
print รจ un costrutto nativo del Perl che viene utilizzato per la stampa a video degli output, nel nostro caso gli รจ stata passata come parametro la stringa "Funziona!" la cui visualizzazione รจ lo scopo finale dello script.
Sono ora da sottolineare due particolaritร che riguardano la sintassi Perl in generale. Innanzitutto la stringa รจ stata delimitata da apici (โFunziona!โ), questo รจ un elemento fondamentale in quanto in mancanza degli apici lโesecutore Perl non sarebbe in grado di riconoscerla come tale. In secondo luogo, lโistruzione รจ stata conclusa con un punto e virgola, si tratta anche in questo caso di un elemento necessario, in quanto il punto e virgola "chiude" unโistruzione rendendola eseguibile.
Eseguire uno script in Perl
Coloro che hanno anche soltanto un pรฒ pratica nellโutilizzo del linguaggio di scripting server side PHP, osservando il codice del breve script proposto nella lezione precedente, avranno certamente notato le numerose affinitร esistenti tra la sintassi di questo linguaggio e quella utilizzabile per digitare listati scritti in Perl.
Potremmo quindi "tradurre" lo script dal Perl in PHP introducendo alcune lievi modifiche fra le righe:
<?
#Stampare a video una stringa con PHP
print 'Funziona!';
?>
Come si potrร notare, in PHP rispetto al Perl abbiamo lo stesso modo di inserire commenti (tramite il cancelletto), la stessa funzione per la visualizzazione delle stringhe (print), la stessa procedura per delimitare le stringhe (utilizzare gli apici) e infine, lo stesso segno per chiudere le istruzioni (il punto e virgola).
Le similitudini non si fermano qui, infatti, che sia vero o no il Perl รจ da molti ritenuto come una specie di "PHP semplificato". Vi sono comunque delle differenze importanti che vanno in ogni caso sottolineate.
Gli script in Perl, per esempio, vengono eseguiti tramite procedure differenti rispetto a quelle utilizzate per PHP. Un volta digitato il codice con il nostro editor di testo preferito (non importa quale, ma le alternative "semplici" come il Vim di Linux sono sempre le migliori per digitare codice "pulito"), dovremo salvare lo script in un file ".pl". Ora, dovremo rendere lโapplicativo eseguibile, per far questo sarร necessario impostare i relativi permessi sul programma utilizzando lโapposita istruzione da Shell:
chmod u+x nome_programma
Nellโ istruzione proposta, abbiamo innanzitutto il comando chmod (abbreviazione di change mode) che serve per settare i permessi sui file; vi sono poi gli argomenti (opzioni) u (user) e x (execute); infine, abbiamo il parametro da passare al comando nellโistruzione, cioรจ il nome del nostro programma.
Una volta impostati i permessi di esecuzione potremo eseguire il nostro script tramite lโistruzione:
./nome_programa
come alternativa possiamo digitare anche:
perl nome_programa
oppure, piรน semplicemnte:
nome_programa
A questo punto lo script verrร eseguito, se il codice รจ stato salvato correttamente verrร stampata a video la stringa attesa; nel momento in cui entrerร in azione lโesecutore Perl, il sorgente verrร in primo luogo compilato e sarร lโoutput del processo di compilazione ad essere eseguito. I tempi di attesa variano a seconda della complessitร dellโapplicativo, ma nel nostro caso saranno naturalmente minimi.
Nel caso in cui il nostro codice sia stato scritto in modo corretto, dovremmo ricevere una notifica di errore, ma รจ altrettanto probabile che il sistema non ci comunichi nulla e si limiti a non eseguire il programma. Vi รจ comunque la possibilitร di richiedere al sistema dei messaggi riguardanti lo stato e gli esiti dellโesecuzione:
perl -w nome_programma
Sarร inoltre possibile eseguire lo script in debugging tramite la seguente istruzione:
perl -d nome_programma
Le variabili
Una variabile, รจ descrivibile come un "contenitore di informazioni", si tratta infatti di un elemento del linguaggio che attraverso una precisa sintassi svolge la funzione di rappresentare un determinato valore assegnato ad esso.
Le variabili possono rappresentare diversi tipi di valori, รจ possibile infatti stabilire per esse sia valori numerici (interi, decimali, negativi, positivi..), sia sequenze di caratteri alfabetici, numerici o simbolici dette stringhe.
Per "dichiarare" una variabile, cioรจ per renderla "esistente", รจ necessario dare ad essa un nome preceduto dal simbolo del dollaro ("$") e assegnare a questo nome un valore tramite il segno "=" (uguale) chiamato "operatore di assegnazione".
Il nome da utilizzare per dichiarare una variabile puรฒ essere costituito sia da numeri che da lettere dellโalfabeto, รจ inoltre possibile utilizzare lโunderscore (ad esempio: "$var_1"). Non รจ possibile che il nome di una variabile cominci con un numero, nรจ porre lโunderscore subito dopo il dollaro ("$_" รจ un costrutto particolare da utilizzare in altri casi).
Perl รจ un linguaggio case sensitive, quindi รจ in grado di distinguere tra lettere minuscole e maiuscole, ne consegue che "$var" e "$Var" verranno considerate come due variabili ben distinte.
Il processo di assegnazione di un valore stringa ad una variabile avviene in questo modo:
$var = 'stringa';
Invece, lโassegnazione di un valore numerico ad una variabile dovrร avvenire in questโaltro modo:
$var = 56
Quindi utilizzeremo gli apici per indicare che il valore che stiamo assegnando รจ un stringa, mentre gli ometteremo per assegnare un valore numerico. Ne consegue che anche un numero potrร essere assegnato come valore stringa ad una variabile semplicemente utilizzando gli apici:
$var = '109';
Gli Array
Fondamentalmente gli array sono anchโessi delle variabili, ma di un tipo particolare, infatti, con questo termine usiamo identificare una variabile che racchiude in sรจ (a cui sono stati assegnati) piรน valori.
Per dichiarare un array si utilizza una sintassi molto simile a quella che viene impiegata per le variabili, in questo caso, perรฒ, dovremo sostituire il dollaro con una chiocciola ("@") ed elencare i valori da assegnare allโarray ponendoli tra parentesi tonde e suddividendoli tramite una virgola. Quindi, nel caso in cui volessimo dichiarare una variabile array chiamata, per esempio, "@array", dovremo utilizzare una sintassi simile alla seguente:
@array = ("valore_1", "valore_2", "valore_n");
Un array chiamato "@famiglia" potrebbe per esempio essere strutturato in questo modo:
@array = ("padre", "madre", "figlio", "figlia");
Dato che un array non rappresenta un unico valore, ma รจ comunque rappresentato da un unico nome, si pone il problema di estrarre i singoli valori da esso. Per far questo Perl assegna ai valori che compongono un array un indice numerico che vร da "0" a "n", dove "0" rappresenta il numero indice del primo valore ed "n" quello dellโennesimo valore contenuto. Per cui nel nostro array "@famiglia" avremo che "padre" รจ rapresentato dal numero indice "0", mentre "figlia" รจ rappresentato dallโultimo numero indice, cioรจ "3". Se volessimo estrarre il valore "madre" dallโarray "@famiglia", dovremmo indicare tra parentesi quadre il numero indice corrispondente al valore prescelto (in questo caso "1" in un indice numerico che vร da "0" a "3"). Quindi, in pratica avremo:
$famiglia[1]
Che รจ pari a "madre", da notare che in questo caso utilizzeremo "$" e non "@" in quanto "$famiglia[1]" rappresenta un unico valore ed รจ quindi una normale variabile non composita. Una volta dichiarato un array, in un secondo tempo รจ possibile allocare allโinterno di esso ulteriori valori tramite lโistruzione "push" (letteralmente "spingi"). Quindi, se per esempio volessimo accodare il valore "nonno" a quelli giร presenti nel nostro array "@famiglia" potremmo utilizzare la seguente istruzione:
push(@famiglia, "nonno");
In questo caso "nonno" assumerร un numero indice pari a "4" (quinto per un indice che vร da "0" a "4"). Se desiderassimo aggiungere piรน di un ulteriore valore allโarray dovremmo "annidare" le parentesi tonde:
push(@famiglia, ("nonno", "nonna"));
Sarร inoltre possibile che un array presenti un array (o piรน di uno) tra i suoi valori:
@array = ("padre", "madre", "figlio", "@nonni");
Un array puรฒ essere assegnato ad una comune variabile, ma in questo caso dovremo porre particolare attenzione allโuso degli apici, infatti:
$var = @famiglia;
consite nellโassegnazione alla variabile "$var" della lunghezza dellโarray denominato "@famiglia", mentre:
$var = '@famiglia';
opera una sotituzione tramite una stringa del nome di un array, la stringa rappresenterร i valori separati da spazi.
I comuni array consentono lโaccesso al loro contenuto tramite lโindice numerico, ma รจ inoltre possibile creare array con elementi accessibili tramite stringhe; in questo caso parliamo di array associativi:
%dati = (
"giuseppe garibaldi", 50,
"john lennon", 99,
"linus torvald", 44
);
Per cui, per esempio:
$dati{"linus torvald"};
restituirร "44".
Operare con le variabili
Una volta valorizzate le nostre variabili, potremo utilizzare le informazioni in esse contenute per svolgere numerosi tipi di operazioni con e su di esse, ciรฒ sarร reso possibile dallโimpiego di particolari costrutti nativi messi a disposizione dal Perl, chiamati appunto "operatori".
I primi operatori che analizzeremo saranno quelli di tipo matematico che ci consentono di effettuare semplici operazioni aritmetiche come le addizioni, le sottrazioni, le divisioni, le moltiplicazioni, il calcolo delle potenze, incrementi e decrementi etc.. Si tratta di operatori comuni ad altri linguaggi utilizzabili per lo scripting server side e non solo.
Lโoperatore di addizione รจ rappresentato dal segno "+", esso ci consente di sommare i valori contenuti in due o piรน variabili di tipo numerico oppure, come nellโesempio che segue, di allocare allโinterno di una variabile il risultato della sommatoria tra due valori numerici:
$var = 4 + 5;
Lโoperatore di sottrazione รจ rappresentato dal segno "โ", esso ci permette di calcolare la differenza tra i valori contenuti in due variabili o piรน di tipo numerico oppure, come nellโesempio seguente, di salvare allโinterno di una variabile il risultato della differenza fra valori numerici:
$var = 5 - 4;
Lโoperatore di moltiplicazione viene rappresentato tramite il segno "*", esso ha la funzione di calcolare il prodotto ottenuto dalla moltiplicazione di valori contenuti in due o piรน variabili di tipo numerico oppure, di salvare allโinterno di una variabile il risultato della moltiplicazione fra valori numerici:
$var = 4 * 5;
Lโoperatore di divisione simboleggiato dallo slash, "/", ha il compito di calcolare il risultato ottenuto dalla divisione di valori contenuti in variabili numeriche oppure, di salvare allโinterno di una variabile il risultato della divisione fra valori numerici:
$var = 4 * 5;
Per calcolare la potenza di un numero, utilizzaremo il simbolo "**", preceduto dalla cifra che vogliamo elevare e succeduto dallโesponente, ad esempio, per elevare "4" alla quinta scriveremo:
$var = 4 ** 5;
Per calcolare il resto di una divisione utilizzaremo il simbolo percentuale, "% "(modulo), ad esempio, per ottenere il resto della divisione "5/4" scriveremo:
$var= 5 % 4;
Per il calcolo dโincremento e decremento utilizzaremo rispettivamente gli operatori "++" (incrementa di "1") e "โ" (decrementa di "1"), quindi, data "$var=n" avremo che:
# Incremento unitario della variabile
++$var;
# Incremento unitario di $var + 1
$var++;
# Decremento unitario della variabile
--$var;
# Decremento unitario di $var - 1
$var--;
Nel corso di questa guida abbiamo giร analizzato lโoperatore di assegnazione "=", esso puรฒ essere utilizzato anche per attribuire ad una variabile il valore di unโaltra variabile:
$var = $var_1;
Puรฒ inoltre essere utilizzato per incrementare il valore di una variabile in associazione allโoperatore "+".
#associazione di un incremento unitario ad una nuova variabile
$var += $var_1;
Oppure puรฒ essere impiegato per decrementare il valore di una variabile in associazione allโoperatore "โ".
#associazione di un decremento unitario ad una nuova variabile
$var -= $var_1;
Per quanto riguarda le stringhe, oltre ad "=" valido anche per esse, introduciamo lโoperatore di concatenazione "." che potrร essere utilizzato come segue:
$var = $var_1.$var_2
oppure
$var. = $var_1
Nel primo caso creiamo una nuova variabile il cui valore รจ uguale alla concatenazione di due altre variabili (ad esempio, date "$var_1=โciaoโ" e "$var_2=โMaxโ", avremo che "$var" รจ uguale a "โCiao Maxโ"). Nel secondo caso, una variabile giร nota assume un nuovo valore concatenando il proprio a quello di unโulteriore variabile.
Un esempio di concatenazione tra stringhe allโinterno di unโistruzione รจ il seguente:
print $var.' e '.$var_1;
Per passare due parametri come una sola stringa utilizzeremo invece:
print "$var and $var_1";
i doppi apici ci consentiranno in fatti di rimpiazzare i nomi delle variabili con i loro rispettivi valori.
Operatori per il controllo del flusso
Perl vede le istruzioni come se fossero delle funzioni per cui restituisce un valore in output, questโultimo puรฒ essere interpretato in senso booleano come TRUE o come FALSE. Il valore "1" oppure una stringa non vuota e diversa da "0" sono TRUE, al contrario, il valore "0" o una stringa vuota sono FALSE.
Gli operatori booleani o logici ragionano in senso binario, cioรจ una dichiarazione puรฒ essere vera o falsa e sono impiegati in genere per le istruzioni condizionali come if, else ed elsif (omologa dellโelseif in altri linguaggi), oppure, per i cicli come for e while.
Tra gli operatori booleani citiamo:
- AND: ad esempio: $var && $var_1; lโespressione logica sarร vera se "$var" e "$var_1" sono entrambe TRUE altrimenti sarร falsa.
- OR: ad esempio: $var || $var_1; lโespressione logica sarร vera se almeno una delle due variabili lo รจ altrimenti sarร falsa.
- NOT: ad esempio: !$var; lโespressione sarร vera se "$var" non lo รจ altrimenti sarร falsa.
Gli operatori di confronto, invece, generano un output sulla base di un confronto tra variabili; in questo caso รจ molto importante poter confrontare tipologie di dato omogenee, quindi Perl dedica nativamente operatori specifici con i quali potremo operare confronti tra variabili numeriche, tra stringhe e tra file.
Tra gli operatori per i confronti numerici citiamo:
- Lโoperatore di uguaglianza. Ad esempio: $var == $var_1; restituisce TRUE se le variabili sono identiche tra loro per valore.
- Lโoperatore di minoranza. Ad esempio: $var < $var_1; restituisce TRUE se la prima variabile ha un valore inferiore rispetto a quello della seconda.
- Lโoperatore di minoranza o uguaglianza. Ad esempio: $var <= $var_1; restituisce TRUE se la prima variabile ha un valore inferiore o uguale a quello della seconda.
- Lโoperatore di maggioranza. Ad esempio: $var > $var_1; restituisce TRUE se la prima variabile ha un valore maggiore rispetto a quello della seconda.
- Lโoperatore di maggioranza o uguaglianza. Ad esempio: $var >= $var_1; restituisce TRUE se la prima variabile ha un valore maggiore o uguale a quello della seconda.
- Lโoperatore di diversitร o di negazione. Ad esempio: $var != $var_1; restituisce TRUE se le variabili sono diverse tra loro per valore.
Tra gli operatori per i confronti tra le stringhe citiamo:
- Lโoperatore di uguaglianza. Ad esempio: $var eq $var_1; restituisce TRUE se le variabili sono identiche tra loro.
- Lโoperatore di minoranza. Ad esempio: $var lt $var_1; restituisce TRUE se la prima variabile ha un valore inferiore per ordine alfabetico rispetto a quello della seconda.
- Lโoperatore di minoranza o uguaglianza. Ad esempio: $var le $var_1; restituisce TRUE se la prima variabile ha un valore inferiore o uguale per ordine alfabetico a quello della seconda.
- Lโoperatore di maggioranza. Ad esempio: $var gt $var_1; restituisce TRUE se la prima variabile ha un valore maggiore per ordine alfabetico rispetto a quello della seconda.
- Lโoperatore di maggioranza o uguaglianza. Ad esempio: $var ge $var_1; restituisce TRUE se la prima variabile ha un valore maggiore o uguale per ordine alfabetico a quello della seconda.
- Lโoperatore di diversitร o di negazione. Ad esempio: $var ne $var_1; restituisce TRUE se le variabili sono diverse tra loro.
Infine, citiamo alcuni tra gli operatori per il confronto tra file:
- -r, ad esempio: -r $var; restituisce TRUE se il file associato alla variabile รจ leggibile.
- -w, ad esempio: -w $var; restituisce TRUE se il file associato alla variabile รจ scrivibile.
- -d, ad esempio: -d $var; restituisce TRUE se alla variabile รจ associata una directory.
- -f, ad esempio: -f $var; restituisce TRUE se alla variabile รจ associato un file regolare.
- -T, ad esempio: -T $var; restituisce TRUE se alla variabile รจ associato un file di testo .
- -e, ad esempio: -e $var; restituisce TRUE se alla variabile รจ associato un file esistente.
Istruzioni condizionali
Quando si parla di istruzioni condizionali o di costrutti per il controllo del flusso, chi conosce un minimo di sintassi dello scripting in qualsiasi linguaggio pensa immediatamente ad if ed else. Essi consentono di intervenire sul flusso delle istruzioni di un applicativo a seconda che una determinata condizione sia verificata o meno.
La sintassi da utilizzare per effettuare controlli su condizione tramite if ed else รจ la seguente:
if (condizione) {
istruzioni da eseguire se si verifica la condizione
} else {
istruzioni da eseguire se non si verifica la condizione
}
Se (if) la condizione delimitata dalle parentesi tonde viene verificata (รจ TRUE), allora verrร eseguito il blocco dโistruzioni successivo allโif e racchiuso fra le parentesi graffe; altrimenti (else) verrร eseguito il blocco di istruzioni successivo ad else. Una volta passati i controlli stabiliti nei due blocchi, il flusso dei dati riprenderร con le istruzioni successive alla chiusura dellโultima parentesi graffa.
else รจ un costrutto opzionale, possiamo inserirlo o meno a seconda che si voglia o no stabilire unโistruzione alternativa a quella indicata per la condizione. In mancanza di unโalternativa, se viene soddisfatta la clausola stabilita nella condizione verrร eseguito il blocco di istruzioni delimitato dalle parentesi graffe successive alla condizione, quindi, lโesecuzione dellโapplicativo proseguirร seguendo le istruzioni succesive alla parentesi graffa chiusa. In caso contrario, se la condizione รจ FALSE, allora le istruzioni racchiuse tra le parentesi graffe non verranno eseguite ed il flusso continuerร ignorando quanto stabilito per la condizione.
Lโistruzione condizionale if puรฒ essere espressa anche in modi differenti con grandi vantaggi in termini di quantitร di codice da digitare; un caso particolare รจ quello riferito alla sintassi con notazione post-fissa, per cui gli elementi del costrutto potranno presentarsi nel modo seguente:
istruzione if condizione;
In questo caso non verranno utilizzate parentesi, nรจ tonde nรจ graffe, quindi, la singola istruzione verrร eseguita soltanto nel caso in cui si verifichi la condizione stabilita.
Volendo proporre un esempip di applicazione pratica delle istruzioni di controllo, รจ importante dire che esse possono essere utilizzate anche in associazione ad operatori per affinare la condizione stabilita:
if (!$var)
# ! richiede l'inesistenza di $var
{ print "Prima condizione verificata\n"; }
# invece se
elsif ($var == $var_1)
{ print "Seconda condizione verificata\n"; }
# invece se
elsif ($var == $var_2)
{ print "Terza condizione verificata\n"; }
# se non si verificano le condizioni:
else { print "Nessuna condizione verificata\n"; }
Nello script appena proposto abbiamo alcune importanti novitร da segnalare: la condizione รจ stabilitร dallโoperatore di negazione "!"; lโistruzione subalterna alla prima condizione comprente una newline ("\n") che consente di stabilire una nuova linea una volta stampato a video il risultato. Abbiamo poi due condizioni introdotte dal costrutto elsif che saranno vere soltanto se la prima condizione sarร verificata. Infine, else propone unโistruzione alternativa che produrrร il suo output soltanto dopo che (e se) i precedenti controlli avranno restituito FALSE.
I Cicli
I cicli, detti anche istruzioni di iterazione, sono dei costrutti nativi che ci consentono di eseguire ciclicamente e quindi di ripetere determinati comportamenti; per ciclo, intendiamo quindi la ripetizione di certi comandi per un determinato numero di volte.
Il ciclo for รจ sicuramente una delle istruzioni di iterazione maggiormente impiegata, anche perchรฉ non si tratta di un costrutto proprio soltanto del linguaggio Perl. Presentiamo di seguito un breve esempio della funzione svolta da for:
#!/usr/local/bin/perl
@famiglia = ("padre", "madre", "figlio", "figlia");
for ($i=0; $i<=$#famiglia; $i++)
{
print "$famiglia[$i]\n";
}
Nellโesempio proposto, abbiamo utilizzato un ciclo for con lo scopo di stampare a video tutti gli elementi di un array.
Un ciclo for si ottiene utilizzando una sintassi che comprende il costrutto for seguito da tre istruzioni che hanno il compito di definire il ciclo; abbiamo poi le istruzioni che dovranno essere eseguite ripetutamente. Analizziamo le tre istruzioni per la definizione del ciclo:
- la prima, nel nostro caso "$i=0", stabilisce un valore iniziale; essa deve essere eseguita una sola volta ad inizio ciclo.
- La seconda, nel nostro caso "$i<=$#famiglia" ("$#famiglia" indica l'ultimo valore dell'array), รจ chiamata condizione di terminazione; essa deve essere valutata prima di ogni iterazione e restituisce FALSE quando il ciclo si interrompe.
- La terza, nel nostro caso "$i++", svolge la funzione di incrementare il valore dato alla prima; essa viene rieseguita ad ogni iterazione fino a quando la condizione di terminazione non restituisce FALSE e il cilclo si ferma.
Nel nostro esempio, la variabile "$i" (contatore), assume allโinizio un valore pari a "0"; ad ogni ciclo il contatore subisce un incremento unitario ("$i++"); quando il contatore raggiunge un valore pari al numero degli elementi dellโarray ("$i<=$#famiglia") il ciclo termina.
Unโaltro costrutto dโiterazione da analizzare รจ foreach, per molti versi simile a for; attraverso foreach รจ possibile inserire di seguito allโinterno di una variabile tutti gli elementi di un array. Proponiamo quindi un esempio sullโutilizzo di questo nuovo costrutto:
#!/usr/local/bin/perl
@famiglia = ("padre", "madre", "figlio", "figlia");
foreach $famigliare (@famiglia)
{
print "$famigliare\n";
}
Come si avrร avuto modo di notare, le differenze anche sintattiche tra foreach e for sono veramente minime. Nellโesempio proposto, ad ogni ripetizione del ciclo la variabile "$famigliare" assume un valore pari a quello dellโelemento estratto in quel momento dallโarray "@famiglia".
Il costrutto di iterazione while, considerato come un particolare tipo di if ripetuta, consente di ciclare un determinato blocco di istruzioni fino a quando una condizione risulta vera, nel momento in cui essa dovesse restituire FALSE il ciclo si bloccherebbe; se la condizione dovesse risultare falsa prima di iniziare il ciclo questo non potrร essere eseguito. Vediamo un esempio:
#!/usr/local/bin/perl
@famiglia = ("padre", "madre", "figlio", "figlia");
while (@famiglia)
{
$famigliare = shift @famiglia;
print "$famigliare\n";
}
Grazie a while verrร visualizzato tutto il contenuto in valori dellโarray famiglia.
Creare funzioni personalizzate
Le funzioni sono dei costrutti sintattici utili per produrre specifici comportamenti. Esistono principalmente due tipologie di funzioni: quelle native messe a disposizione dal linguaggio stesso, quelle personalizzate che vengono definite dallo sviluppatore in sede di scrittura del codice.
Le funzioni native messe a disposizione da Perl sono numerosissime e producono i comportamenti piรน disparati: vi sono funzioni per effettuare operazioni aritmetiche, per convertire tipi di dato, per manipolare stringhe, file, directory ed array etc. Non sarebbe possibile proporle tutte in questa sede, quindi consigliamo di consultare il manuale ufficiale di Perl e di sfruttare questa documentazione gratuitร ogni volta che avremo bisogno di ricercare una determinata funzione per produrre un certo comportamento.
In questo capitolo, affronteremo invece il discorso riguardante le funzioni personalizzate, la cui sintassi per il Perl dovrร essere improntata sul modello della seguente:
sub funzione_personalizzata
{
print "Istruzione 1\n";
print "Istruzione 2\n";
}
Una funzione agisce sulla base di parametri (argomenti passati alla funzione), quando viene "richiamata". Per effettuare una chiamata dovremo porre una "&" davanti al nome effettivo della funzione:
# Chiamata semplice
&funzione_personalizzata;
# Chiamata con un solo parametro
&funzione_personalizzata ($_);
# Chiamata con piรน parametri
&funzione_personalizzata ($_1, $_2, ...);
Nel momento in cui una funzione viene richiamata, ciascun parametro viene passato come fosse una array allโinterno della variabile speciale @_ che non ha alcuna relazione con la variabile $_ che รจ una variabile di default utilizzata per le operazioni di input e di pattern matching (ricerche allโinterno di stringhe). Potremmo per esempio visualizzare i parametri passati ad una funzione attraverso una sintassi simile alla seguente:
sub view_array
{
print "@_\n";
}
&view_array("valore_1", "valore_2", "valore_n");
&view_array("valore_3", "valore_4", "valore_n2");
Il discorso sulle funzioni ci porta ad affrontare quello strettamente correlato dei valori di ritorno che in una funzione sono sempre lโultimo elemento sottoposto a valutazione. Vediamo un esempio:
sub min
{
if ($_[0] < $_[n])
{
$_[0];
}
else
{
$_[n];
}
}
$min = &min(7, 3);
Nello specifico, la funzione appena proposta restituisce il minore dei due parametri valutati.
Gestione dei file
Uno dei motivi per cui Perl รจ un liguaggio molto apprezzato dagli sviluppatori, risiede nella sua innata capacitร di gestire le varie operazioni di manipolazione che รจ possibile operare su un documento, come per esempio: apertura, lettura, scrittura e chiusura.
Nelle prossime righe proporremo il codice da digitare per la creazione di un piccolo aplicativo capace di aprire, leggere e chiudere un file chiamato "documento.txt":
# Passiamo il file come valore di una variabile
$var = 'documento.txt';
# Apertura
open(INFO, $var);
# Lettura
@testo = <INFO><INFO>;
# Chiusura
close(INFO);
# stampa a video
print @testo;
La logica seguita dal nostro piccolo applicativo รจ abbastanza semplice: innanzitutto il file su cui operare viene passato come valore ad una variabile ("$var"); in secondo luogo utilizziamo la funzione nativa open per aprire il file; quindi, il file viene letto passando il cuo contenuto come valore di un array ("@testo"); infine il fine viene chiuso utilizzando la funzione nativa close e il suo contenuto viene stampato a video.
Sempre riguardo alla gestione dei documenti, รจ importante sottolineare come la funzione nativa open possa essere utilizzata anche al fine di specificare un determinato file da impiegare per il salvataggio dei dati in output:
# Lettura
open(INFO, $var);
# Scrittura
open(INFO, ">$var");
# Salvataggio
open(INFO, ">>$var");
Sarร inoltre possibile scrivere del testo su di un documento aperto in scrittura, in questo caso dovremo utilizzare lโistruzione print a cui passeremo come parametro il contenuto attuale del file (che puรฒ essere anche vuoto) e la stringa da aggiungere:
print INFO "testo testo testo testo.\n";
Pattern matching e Pattern substitution
Lโambito di utilizzo principale del linguaggio Perl, da molti ritenuto il suo campo dโapplicazione "naturale", รจ quello relativo alla manipolazione delle stringhe attraverso operazioni di Pattern matching e di Pattern substitution.
Il Pattern matching consiste nella ricerca effettuata secondo determinati criteri di una deteminata sotto-stringa allโinterno di una sequenza di caratteri; il Pattern substitution consiste invece nella sostituzione tramite un sotto-stringa di una sotto-stringa individuata allโinterno di una sequenza di caratteri principale. Semplificando allโestremo, se ricerchiamo allโinterno della frase "Perl รจ Open Source" la parola "Perl", stiamo operando unโazione di Pattern matching; se sostituiamo la parola "Perl" con la stringa "PHP", stiamo operando unโazione di Pattern substitution (mi perdonino i puristi..).
I criteri tramite i quali operare ricerche e sostituzioni vengono stabiliti tramite dei costrutti detti espressioni regolari, queste ultime "codificano" caratteri e classi di caratteri in modo da mettere a disposizione dello sviluppatore uno strumento "universalmente valido" per operare su qualsiasi tipo di stringa.
Il matching in Perl segue questa sintassi:
m/pattern/opzioni;
Proponiamo di seguito alcune possibili opzioni:
- g: opera il matching su tutti i possibili pattern;
- i: ignora determinati casi;
- m: testa una stringa come multi-linea;
- o: esprime unโunica valutazione;
- s: vede una stringa come singola linea;
- x: ignora gli spazi vuoti.
Le sostituzioni avvengo invece secondo la seguente sintassi:
s/pattern/sostituzione/opzioni;
Ad esempio:
s/hjhjhj/jkjkjk/;
Sostituisce la stringa "hjhjhj" con "jkjkjk".
Opzioni per le sostituzioni:
- g: sostituzione d tutte le occorrenze;
- i: ignora determinati casi;
- e: valuta la stinga di sostituzione come unโespressione;
- m: testa una stringa come multi-linea;
- o: esprime unโunica valutazione;
- s: vede una stringa come singola linea;
- x: ignora gli spazi vuoti.