paper.gifioProgrammo N°4, Maggio 1997 ©Copyright DIEMME Editori

fire.gif

ISTRUZIONI DI CALCOLO
E' giunto il momento di scoprire come sia possibile ottenere flessibilità e potenza da uno script Perl. L'uso combinato di istruzioni di controllo ed espressioni regolari permette la scrittura di algoritmi complessi ma brevi, un risultato difficilmente ottenibile con altri linguaggi, C compreso
In Perl esistono tre categorie di istruzioni di controllo. Istruzioni di selezione, come if e unless; istruzioni di iterazione, di cui fanno parte i cicli for, foreach, while, do-while e until; istruzioni di salto, che comprendono last, next, e goto. La forma generale dell'istruzione if è la seguente:

if (espressione) {
  istruzione/i;
}
else {
  istruzione/i;
}

La clausola else è facoltativa, mentre le parentesi graffe sono obbligatorie, anche se si tratta di una singola istruzione. L'espressione condizionale è una qualsiasi espressione Perl che produce un risultato booleano (vero o falso, con falso=0 e vero qualsiasi valore diverso da zero). Se il risultato è quindi vero sarà eseguito l'argomento di if, altrimenti sarà eseguita l'istruzione dopo l'else. Gli if possono essere annidati e associati a clausole elseif dando origine a scale if-else-if. L'istruzione unless, invece, è l'esatto contrario di if.

unless (espressione) {
  istruzione/i;
}
else { ... }

In questo caso il blocco di istruzioni verrà eseguito solo se l'espressione risulta falsa

$i = 20;
unless ($i < 10) {
  print "i è maggiore di 10\n";
}

Passiamo ora alle istruzioni di iterazione. Il ciclo for ha una sintassi analoga al for del linguaggio C

for (inizializzazione; espressione; incremento) {
  istruzione/i;
}

e viene usato per ripetere un determinato numero di volte una o più istruzioni. L'iterazione continua finché l'espressione condizionale rimane vera. Ecco come si può usare il for per sommare uno dopo l'altro i numeri da 1 a 10

for ($i=1; $i<=10; $i++) {
  $somma += $i; 
}
print "Somma = $somma";

Simile al for è l'istruzione foreach, più indicata se si usano array

foreach variabile (array) {
  istruzione/i;
}

e che dopo aver assegnato a variabile un elemento di array esegue il blocco di istruzioni. L'iterazione continua finché non rimane alcun elemento dell'array. Vediamo l'esempio precedente adottando foreach

@numeri = (1..10);
foreach $i (@numeri) {
  $somma += $i;
}
print "Somma = $somma";

C'è anche l'istruzione while

while (espressione) {
  istruzione/i;
}

usata per ripetere una o più istruzioni finché la condizione è vera. Ecco un esempio per leggere dallo standard input e stampare le righe lette

while (<STDIN>) { print $_; }

La versatilità del ciclo while è notevole e si può usare praticamente qualsiasi espressione condizionale, anche un intero array. Sì, perché le istruzioni verranno iterate fino all'ultimo elemento dell'array. Esempio:

@array = ('a'..'z');
while (@array) {
  $a = shift @array;
  print $a;
}

C'è un misterioso shift. E' una delle tante funzioni predefinite per il trattamento degli array. La funzione shift elimina il primo elemento dall'array e lo restituisce, spostando tutti gli altri elementi rimanenti. Anche while come if ha il suo opposto: l'istruzione until. Le istruzioni di salto come last e next vengono usate per forzare rispettivamente la fine e l'iterazione di un ciclo. Questo script stampa i numeri pari tra 0 e 100 ma quando si arriva a 50 finisce.

for ($x=0; $x<=100; $x++) { 
  if ($x % 2)  { next; }
  if ($x > 50) { last; }
  print "$x\n";
}

goto invece sposta il flusso del programma ad una etichetta. Eseguite il seguente script e scrivete exit per fermarlo.

loop: #etichetta
  print "Comando: ";
  $stop = <STDIN>;
  chop $stop; #elimina il newline da $stop
  unless ($stop eq "exit") {
    print "scrivere exit per uscire\n";
    goto loop;
  }

linea.gif
LE ESPRESSIONI REGOLARI
Si tratta di particolari costrutti che servono per analizzare le stringhe. In sostanza una espressione regolare è una sequenza di caratteri racchiusa tra due barre oblique (slash) e viene di solito usata per cercare le occorrenze di una o più stringhe in un file. Le regole per creare espressioni regolari sono piuttosto semplici, anche se Perl permette la creazione di espressioni molto complesse. Per usare una regular expression è necessario l'operatore di corrispondenza (o di matching) =~ o il suo opposto !~. Di norma tali operatori restituiscono un risultato booleano. Se scriviamo $stringa =~ /[pP]erl/ significa che le stringhe perl e Perl vengono cercate nella variabile $stringa. In generale i caratteri alfanumerici usati per costruire l'espressione regolare indicano se stessi, tuttavia ce ne sono alcuni che hanno un significato speciale. Il punto . per esempio indica qualsiasi carattere tranne il newline; il carattere ^ indica l'inizio di una stringa mentre $ ne indica la fine. Per cercare quindi tutte le stringhe di un solo carattere nella stinga $a basta scrivere $a =~ /^.$/ Se vogliamo cercare i caratteri speciali come ^ $ . * + ? [ ] / dobbiamo togliere al carattere il suo significato speciale, anteponendo un backslash \. Infatti con l'istruzione $a =~ /\./ cerco nella variabile $a proprio il punto, mentre se avessi scritto $a =~ /./ avrei cercato in $a qualsiasi stringa composta da almeno un carattere diverso dal newline. Il backslash però oltre a disattivare alcuni caratteri ne rende speciali altri. \d corrisponde a un singolo numero, \w corrisponde a un carattere alfanumerico, \S ad uno spazio, \n al newline ecc. E se si vuole cercare solo uno tra alcuni caratteri? Si usano le parentesi quadre. Con $a =~ /[abc]/ cerco in $a il carattere a, b oppure c ma non la stringa abc, mentre con $a =~ /[0-9]/ cerco un singolo numero (/[0-9]/ è l'equivalente di /[0123456789]/). Oltre che caratteri singoli è possibile specificare anche sequenze di caratteri e per farlo si usano i modificatori + * ?. Il + indica che la stringa da cercare può apparire una, due o più volte. $a =~ /[ab]+/ ritorna vero se $a è per esempio costituita da a, b, ab, aa, ababab ecc. L'asterisco, che funziona come il +, permette il riscontro anche se la stringa non è del tutto presente in $a, mentre il punto interrogativo indica che l'espressione regolare può apparire una volta oppure no. Ecco un esempio di riepilogo per controllare l'input del nome di una persona.

do {
  print "nome: ";
  $nome = <STDIN>;
  chop $nome;
} while ($nome !~ /^[a-z']*$/i);

Il carattere i alla fine dell'espressione forza la ricerca senza distinguere minuscole e maiuscole. Oltre alle funzioni di ricerca si possono costruire delle funzioni di sostituzione. $var =~ s/perl/PERL/gi cerca la striga perl in $var e, se la trova, la sostituisce con PERL.
linea.gif
ABBIAMO CONCLUSO
Nei prossimi articoli vedremo come si usano i files, i "default" e come sia possibile interagire con il sistema operativo.

fire.gif

Data creazione HTML: Febbraio 1998
Autore: Francesco Munaretto
E-mail: NoSpam@thank.you
exclaim.gif