Corso di Perl

Strutture di controllo: do, labels

 

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, l’espressione viene valutata dopo che il blocco è stato eseguito la prima volta. Usando while, il ciclo viene ripetuto se l’espressione è vera. Con do abbiamo a disposizione anche la parola chiave until:

do
      {
      blocco;
      }
until (espressione);

in questo caso, il blocco viene ripetuto se l’espressione è 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 l’altro, come in quest’altro esempio:

LOOP1: while ($a >0)
      {
      LOOP2: while ($b>0)
            {
            $c += 10;
            last LOOP1 if $c>100;
            }
      }


notate che l’istruzioni last provoca l’uscita 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 all’istruzione redo. L’istruzione next non avrebbe funzionato, perché non c’è nessuna espressione che controlli la ripetizione del blocco: ricordatevi che next forza la rivalutazione dell’espressione 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 l’istruzione 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