Cicli con controllo in coda
Sia while che for sono cicli con controllo in testa:
la condizione viene valutata prima di eseguire il blocco.
Come molti altri linguaggi, il Perl mette a disposizione ciclo col
controllo in coda, usando la parola chiave do:
do
{
blocco;
}
while (espressione);
In questi cicli, lespressione viene valutata dopo che
il blocco è stato eseguito la prima volta. Usando while,
il ciclo viene ripetuto se lespressione è vera. Con do
abbiamo a disposizione anche la parola chiave until:
do
{
blocco;
}
until (espressione);
in questo caso, il blocco viene ripetuto se lespressione
è falsa. Infatti until ha il significato opposto
di while. In questo momento sono troppo pigro per trovare
un esempio che usi until col nostro programma delle altezze.
Beh, qualche compito per casa ve lo devo pur dare, no?
Attenzione
Nel Perl, i cicli realizzati con do non sono considerati
veri cicli, ma semplici blocchi di istruzioni che, in certe condizioni,
possono essere ripetute. Di conseguenza, non si possono usare next,
last o redo dentro di essi. Siamo spiacenti,
dice la documentazione ActivePerl, e poi passa a descrivere un paio
di elaborati trucchetti per utilizzarli lo stesso. Qui non ne farò
parola, anche perché vi invito caldamente a non usarli, ma se li
trovate in un altro script e non sapete che pesci pigliare, potete
andare a vedere il capitolo perlsyn della documentazione
in linea.
Labels
Per terminare la trattazione dei cicli, devo parlarvi delle labels
(etichette). Chi conosce il Basic o linguaggi simili
sa a cosa mi riferisco: una label è un nome che viene dato ad una
certa linea di programma, in modo da poter saltare direttamente
a quel punto, con le famose istruzioni goto. In tutti i linguaggi
strutturati, e anche in Perl che è un po un ibrido, i goto
sono fortemente deprecati per le complicazioni che introducono.
Vediamo invece un uso comunemente accettato (e incoraggiato) delle
label:
PROVA: while ($a > 0)
{
$b +=1;
last PROVA if $b>100;
}
Una label è una qualunque stringa alfanumerica. Normalmente è scritta
in caratteri maiuscoli, per distinguerla dal resto. Quando viene
dichiarata, è seguita da un carattere due punti :.
Nel nostro esempio, la label dà un vero e proprio nome al blocco
while.
Le istruzioni next, last e redo possono utilizzarla
per dire quale blocco ripetere o arrestare. E una cosa molto
utile se abbiamo più blocchi innestati uno dentro laltro,
come in questaltro esempio:
LOOP1: while ($a >0)
{
LOOP2: while ($b>0)
{
$c += 10;
last LOOP1 if $c>100;
}
}
notate che listruzioni last provoca luscita del
primo while (e quindi di tutto il ciclo), invece dello while
più vicino come avrebbe fatto se non avessimo messo la label.
Cicli impropri, con e senza label
Una label non è limitata ad un ciclo vero e proprio, ma può essere
assegnata ad un blocco qualunque:
BLOCK: {
$a = $b+$c;
redo BLOCK if $a>100;
}
notate come questo blocco sia diventato in pratica un ciclo! Anche
senza nessuna istruzione while o simili, il blocco può essere
ripetuto grazie allistruzione redo. Listruzione
next non avrebbe funzionato, perché non cè nessuna
espressione che controlli la ripetizione del blocco: ricordatevi
che next forza la rivalutazione dellespressione di
controllo. Se questa manca, è difficile che il Perl la consideri
valida.
Notate inoltre che, se togliamo le label, il ciclo funziona ancora:
{
$a = $b+$c;
redo if $a>100;
}
infatti un blocco tra parentesi graffe è funzionalmente equivalente
ad un ciclo eseguito una sola volta. E le istruzioni di controllo
funzionano benissimo.
Vi invito però a non scrivere un codice del genere, perché è difficilmente
comprensibile. Ve ne parlo per completezza, e perché potreste trovare
uno script scritto da qualcuno abbastanza matto :-)
In pratica, le label in Perl si utilizzano quasi solo in questo
modo. Esiste anche listruzione goto label, che esegue
un salto incondizionato alla label stessa. Ma visto che non dovete
usarla, per ora non ve ne parlo :-)
Torna all'indice Generale del corso di Corso di Perl di Software Planet