Corso di Perl

Strutture di controllo: ancora cicli

 

While abbreviato

Così come l’istruzione if, anche per while è prevista una forma abbreviata di scrittura. Il nostro ciclo può essere espresso in una sola riga in questo modo:

$media=0;
$media = $media + $valore while(($chiave, $valore) = each( %altezza));


Ma non conviene, perché si ottiene un codice che è troppo complicato. Però potrebbe essere utile in casi più semplici:

$a = 10;
print $a = $a-1 while ($a>0);

Riuscite ad indovinare cosa farà questo codice? Sfrutta un paio di idee che ho già esposto, quindi ve lo lascio come compito a casa.

Un’altra cosa: avrete notato che, nello scrivere il ciclo while in forma abbreviata, ho tralasciato l’istruzione if. Questo perché sia while che if sono istruzioni che controllano l’esecuzione di altre istruzioni, e quando sono scritte in forma abbreviata non possono essere combinate. Questo perché la forma abbreviata è pensata per istruzioni semplici, da
scrivere e da leggere in pochi secondi. Combinare troppe istruzioni su una sola riga risulterebbe in un codice incomprensibile.

Modifiche in corsa

L’esecuzione dei cicli non è sempre lineare. Ci saranno casi in cui vorrete uscire da un ciclo senza completare le ripetizioni previste, ed altri dove volete far ripartire il ciclo senza stare ad eseguire tutte le istruzioni del blocco da ripetere, controllando oppure no la condizione iniziale. Per questi casi il Perl ci mette a disposizione le istruzioni last, next e redo.

Uscita di sicurezza

L’istruzione last causa l’uscita immediata da un ciclo, saltando le ripetizioni che devono ancora essere fatte. Ad esempio, riprendiamo il codice delle lezioni precedenti e aggiungiamo una riga:

$media=0;
while(($chiave, $valore) = each( %altezza))
      {
      last if $valore<0;
      $media = $media + $valore;
      }


Qui l’istruzione last comanda l’uscita dal ciclo while se, per qualche motivo, uno dei valori da sommare è minore di zero: trattandosi di altezze espresse in centimetri, non deve mai accadere. Anche se, nel nostro caso, i valori erano inseriti a mano all’inizio del programma e quindi non dovremmo aspettarci errori, è sempre buona norma fare qualche controllo sulla validità dei dati su cui operiamo.

Notate che l’istruzione last si riferisce sempre ad un ciclo, anche se si trova inserita in un blocco più interno:

while ($a>0)
      {
      $a = $a-1;
      if ( $a <0)
            {
            print “$a è minore di 0\n”;
            last;
            }
      }


Non preoccupatevi di cosa fa questo codice, non serve assolutamente a niente. Voglio solo far vedere che l’istruzione last è stata nidificata, come si suol dire, ma quando viene eseguita terminerà il ciclo while.

Andare fino al Via

Se last significa “questa è l’ultima ripetizione”, potete immaginarvi che next significhi “inizia la prossima ripetizione”. E infatti è proprio così:

$media=0;
while(($chiave, $valore) = each( %altezza))
      {
      next if $valore<0;
      $media = $media + $valore;
      }

Questo codice è migliore del precedente, perché invece di terminare di botto il ciclo, ne prosegue l’esecuzione ignorando i valori sbagliati: infatti, la prima istruzione del ciclo è un controllo su ciò che è contenuto in $valore. Se è minore di zero, viene eseguita l’istruzione next, che salta a piè pari il resto del ciclo e ritorna allo while per valutare un’altra volta l’espressione.
Ovviamente, per next valgono tutte le considerazioni che abbiamo fatto per last riguardo alla nidificazione.

Qualcuno di voi svelto di mente potrebbe accorgersi che quel next era inutile. Bastava infatti scrivere:

$media=0;
while(($chiave, $valore) = each( %altezza))
      {
      $media = $media + $valore if $valore>=0;
      }


per far funzionare il tutto allo stesso modo. In effetti è così, ma come spesso vi ripeto, la versione precedente era più
leggibile. E in qualche modo dovevo pure spiegarvi next e last, no?

Ripetere

E per ultimo abbiamo redo, in Inglese re-do, cioè rifare. Redo è molto simile a next, con la differenza che il ciclo viene rieseguito senza controllare l’espressione dello while. Cioè:

$a = 100;
while ($a>0)
      {
      $a = $a -1;
      redo;
      }


Questo è un ciclo infinito: a forza di decrementare $a, prima o poi l’espressione “$a>0” diventerà falsa, ma col redo questa non viene mai valutata. Vedremo in futuro degli usi più costruttivi di questa istruzione.

 

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