Perl/Istruzioni: differenze tra le versioni

Wikibooks, manuali e libri di testo liberi.
Contenuto cancellato Contenuto aggiunto
Riga 22: Riga 22:
'''NOTA''':la differenza fra un blocco e la definizione di un hash è evidente:l'hash deve avere un $,un"nome" ed una chiave fra {}, mentre il blocco non ha $,non ha nome e al suo interno sono presenti istruzioni.
'''NOTA''':la differenza fra un blocco e la definizione di un hash è evidente:l'hash deve avere un $,un"nome" ed una chiave fra {}, mentre il blocco non ha $,non ha nome e al suo interno sono presenti istruzioni.


=== Etichette ===
Le etichette individuano una istruzione o un blocco.
Le etichette da sole non servono molto, ma con dei costrutti particolari come goto , redo , next , last è possibile sfruttare meglio le loro potenzialità:

<ETICHETTA>:<istruzione>

<ETICHETTA>:{
... istruzioni ...
}
per esempio è possibile:

ETICHETTA_UNO: print "etichetta uno\n";

ETICHETTA_DUE:
{
print "etichetta due\n";
}

my $b = 15;
ETICHETTA_TRE : while ( $b < 20 )
{
print " etichetta tre ($b)\n";
$b++;
}
In questo modo un blocco o una istruzione "assume" un nome.Questo non è da confondere con il nome di una funzione.

==== Goto (da non usare) ====
Come dice il manuale del Perl l'uso del goto non è per nulla consigliato ed è limitato.Il suo uso "mal accettato" è quello di indicare una ETICHETTA.In questo modo il programma "torna" o "va" al punto indicato.Dato che questa istruzione si "sconsiglia" non verrà descritto oltre.

=== Istruzioni particolari su BLOCCO o ETICHETTA ===
Come anticipato precedentamente le etichette risultano particolarmente utili con le istruzioni particolari last,redo,next.Queste modificano l'esecuzione del programma "saltando" opportunamente all'interno di un blocco/etichetta.

==== Last ====
Questa istruzione consente di terminare "prematuramente" un blocco o una etichetta.

last ; # usato un blocco
last <ETICHETTA>; # indica su quale etichetta

Vediamo questo esempio:

my $b = 15;
my $stop = 17;
ETICHETTA_TRE : while ( $b < 20 )
{
print " etichetta tre (b=$b)\n";
$b++;
if ( $stop == $b ) { last ETICHETTA_TRE; }
}

==== Redo ====
Questa istruzione consente di ritornare allo stesso punto di quando è iniziata l'ultima iterazione.

redo ; # usato un blocco
redo <ETICHETTA>; # indica su quale etichetta


Vediamo questo esempio:

my $b = 15;
my $stop = 17;
my $ripetizioni=2;
ETICHETTA_TRE : while ( $b < 20 )
{
print "etichetta tre (b=$b , r=$ripetizioni)\n";
if ( $stop == $b and $ripetizioni > 0) { $ripetizioni--; redo ETICHETTA_TRE; }
$b++;
}
che produce :
etichetta tre (b=15 , r=3)
etichetta tre (b=16 , r=3)
etichetta tre (b=17 , r=2) # primo redo
etichetta tre (b=17 , r=1) # secondo redo
etichetta tre (b=17 , r=0)
etichetta tre (b=18 , r=0)
etichetta tre (b=19 , r=0)

==== Next ====
Questa istruzione consente di "saltare" all'elemento successivo.

next ; # usato un blocco
next <ETICHETTA>; # indica su quale etichetta


Vediamo questo esempio:

my $b = 15;
my $stop = 17;
my $ripetizioni=2;
ETICHETTA_TRE : while ( $b < 20 )
{
$b++;
if ( $stop < $b and $ripetizioni > 0) { $ripetizioni--; next ETICHETTA_TRE; }
print " etichetta tre (b=$b , r=$ripetizioni)\n";
}
che produce :

etichetta tre (b=16 , r=2)
etichetta tre (b=17 , r=2)
etichetta tre (b=20 , r=0)


===DECISIONALI===
===DECISIONALI===

Versione delle 16:25, 13 dic 2006

Template:Linguaggio Perl

Le istruzioni sono quei costrutti sintattici che consentono ad un linguaggio di controllare, gestire, manipolare. Quando un programma svolge un compito , esegue innumerevoli operazioni che il programmatore deve essere in grado di controllare e gestire. Ecco in breve le istruzioni "fondamentali" che consentono di realizzare un programma.

MINIME

con questo termine intendo indicare le istruzioni più semplici, come quelle che abbiamo usato fin'ora. Per esempio :

$a = 3;
@a = ( 1, 2, 3);
%a = ( 1 => 2 , 3 => 4 );

RACCHIUSE o BLOCCO

per blocco si intendono tutte quelle istruzioni comprese fra { e }.Ai fini pratici i blocchi individuano un gruppo di istruzioni.

{
  $a = 3;
  @a = ( 1, 2, 3);
  %a = ( 1 => 2 , 3 => 4 );
}

NOTA:la differenza fra un blocco e la definizione di un hash è evidente:l'hash deve avere un $,un"nome" ed una chiave fra {}, mentre il blocco non ha $,non ha nome e al suo interno sono presenti istruzioni.

Etichette

Le etichette individuano una istruzione o un blocco. Le etichette da sole non servono molto, ma con dei costrutti particolari come goto , redo , next , last è possibile sfruttare meglio le loro potenzialità:

<ETICHETTA>:<istruzione>
<ETICHETTA>:{
            ... istruzioni ...
            }

per esempio è possibile:

ETICHETTA_UNO: print "etichetta uno\n";
ETICHETTA_DUE: 
{
   print "etichetta due\n";
}
my $b = 15;
ETICHETTA_TRE : while ( $b < 20 )
                {
                    print " etichetta tre ($b)\n"; 
                    $b++;
                } 

In questo modo un blocco o una istruzione "assume" un nome.Questo non è da confondere con il nome di una funzione.

Goto (da non usare)

Come dice il manuale del Perl l'uso del goto non è per nulla consigliato ed è limitato.Il suo uso "mal accettato" è quello di indicare una ETICHETTA.In questo modo il programma "torna" o "va" al punto indicato.Dato che questa istruzione si "sconsiglia" non verrà descritto oltre.

Istruzioni particolari su BLOCCO o ETICHETTA

Come anticipato precedentamente le etichette risultano particolarmente utili con le istruzioni particolari last,redo,next.Queste modificano l'esecuzione del programma "saltando" opportunamente all'interno di un blocco/etichetta.

Last

Questa istruzione consente di terminare "prematuramente" un blocco o una etichetta.

last ;             # usato un blocco
last <ETICHETTA>;  # indica su quale etichetta  

Vediamo questo esempio:

my $b = 15;
my $stop = 17;
 
ETICHETTA_TRE : while ( $b < 20 )
                {
                    print " etichetta tre (b=$b)\n"; 
                    $b++;
                    if ( $stop == $b ) { last ETICHETTA_TRE; }
                } 

Redo

Questa istruzione consente di ritornare allo stesso punto di quando è iniziata l'ultima iterazione.

redo ;             # usato un blocco
redo <ETICHETTA>;  # indica su quale etichetta  


Vediamo questo esempio:

my $b = 15;
my $stop = 17;
my $ripetizioni=2;
 
ETICHETTA_TRE : while ( $b < 20 )
                {
                    print "etichetta tre (b=$b , r=$ripetizioni)\n"; 
                    if ( $stop == $b and $ripetizioni > 0) { $ripetizioni--; redo ETICHETTA_TRE; }
                    $b++;
                } 

che produce :

etichetta tre (b=15 , r=3)
etichetta tre (b=16 , r=3)
etichetta tre (b=17 , r=2) # primo   redo
etichetta tre (b=17 , r=1) # secondo redo
etichetta tre (b=17 , r=0)
etichetta tre (b=18 , r=0)
etichetta tre (b=19 , r=0)

Next

Questa istruzione consente di "saltare" all'elemento successivo.

next ;             # usato un blocco
next <ETICHETTA>;  # indica su quale etichetta  


Vediamo questo esempio:

my $b = 15;                                                                    
my $stop = 17;                                                                 
my $ripetizioni=2;                                                             
                                                                               
ETICHETTA_TRE : while ( $b < 20 )                                              
                {                                                              
                    $b++;                                                      
                    if ( $stop < $b and $ripetizioni > 0) { $ripetizioni--; next ETICHETTA_TRE; }                                                              
                    print " etichetta tre (b=$b , r=$ripetizioni)\n";          
                }                                                              

che produce :

etichetta tre (b=16 , r=2)
etichetta tre (b=17 , r=2)
etichetta tre (b=20 , r=0)

DECISIONALI

Per decisionali si intende quelle istruzioni che a seguito di una condizione consentono di far fare o meno una parte di istruzioni. Facciamo un esempio: un uomo nasce, cresce e muore.Durante la crescita passa da bambino, ragazzo , giovane, adulto, vecchio, anziano. Per puro esempio stabiliamo che l'età sia l'unico parametro che faccia passare da una definizione all'altra. Pertanto di potrebbe definire queste soglie: bambino fino a 14, ragazzo da 14 a 17 , giovane da 17 a 23, adulto da 23 a 60, vecchio da 60 a 75, anziano oltre 75

%stadio = (  bambino => 14
           , ragazzo => 17
           , giovane => 23
           , adulto  => 60
           , vecchio => 75 );


if, elsif, else

l'istruzione if () è una decisionale "spartiacque" cioè divide l'esecuzione del programma in "quella parte che verifica la condizione" e "quella parte che non la verifica". Nel mezzo delle parentesi ( e ) va posta la condizione:

%stadio = (  bambino => 14
          , ragazzo => 17
          , giovane => 23
          , adulto  => 60
          , vecchio => 75 );

$eta_ora = 27;

print "all'eta' di $eta_ora sei un bambino \n" if ( $eta_ora < 14 ) ;
# ma meglio:
print "all'eta' di $eta_ora sei un bambino \n" if ( $eta_ora < $stadio{bambino} ) ;

L'istruzione di print verrà eseguita SOLO se $eta_ora sarà minore di 14 . NOTA: il punto e virgola a indicare la fine dell'istruzione.Inoltre all'if (se usato in fondo) si può associare SOLO una istruzione.

E' possibile associare un blocco all'istruzione di if:

$eta_ora = 27;

if ( $eta_ora < $stadio{bambino} ) { print "all'eta' di $eta_ora sei un bambino \n"; }

NOTA: Ora il punto e virgola non c'è perchè le istruzioni sono dentro ad un blocco. Occorre poter distinguere una istruzione (anche se condizionale) ed un blocco associato ad una condizione. E' possibile inoltre associare più verifiche utilizzando il costrutto elsif:

%stadio = (  bambino => 14
          , ragazzo => 17
          , giovane => 23
          , adulto  => 60
          , vecchio => 75 );

$eta_ora = 27;

if ( $eta_ora >= $stadio{vecchio} )
{ 
   print "all'eta' di $eta_ora sei un anziano \n"; 
}
elsif ( $eta_ora >= $stadio{adulto} )
{ 
   print "all'eta' di $eta_ora sei un vecchio \n"; 
}
elsif ( $eta_ora >= $stadio{giovane} )
{ 
   print "all'eta' di $eta_ora sei un adulto \n"; 
}
elsif ( $eta_ora >= $stadio{ragazzo} )
{ 
   print "all'eta' di $eta_ora sei un giovane \n"; 
}
elsif ( $eta_ora >= $stadio{bambino} )
{ 
   print "all'eta' di $eta_ora sei un ragazzo \n"; 
}
elsif ( $eta_ora >= 0 )
{ 
   print "all'eta' di $eta_ora sei un bambino \n"; 
}

Esiste anche un'altra forma più elegante :

%stadio = (  bambino => 14
          , ragazzo => 17
          , giovane => 23
          , adulto  => 60
          , vecchio => 75 );
          
$eta_ora = 27;
if ( $eta_ora >= $stadio{vecchio} )
{ 
   print "all'eta' di $eta_ora sei un anziano \n"; 
}
elsif ( $eta_ora >= $stadio{adulto} )
{ 
   print "all'eta' di $eta_ora sei un vecchio \n"; 
}
elsif ( $eta_ora >= $stadio{giovane} )
{ 
   print "all'eta' di $eta_ora sei un adulto \n"; 
}
elsif ( $eta_ora >= $stadio{ragazzo} )
{ 
   print "all'eta' di $eta_ora sei un giovane \n"; 
}
elsif ( $eta_ora >= $stadio{bambino} )
{ 
   print "all'eta' di $eta_ora sei un ragazzo \n"; 
}
else
{ 
   print "all'eta' di $eta_ora sei un bambino \n"; 
}

Il caso else viene eseguito se tutte le condizioni precedenti NON sono state verificate.Il caso else DEVE essere l'ultimo. NOTA: E' possibile includere il caso else senza alcuna clausula elsif.Per esempio si sarebbe potuto scrivere:

%stadio = (  bambino => 14
          , ragazzo => 17
          , giovane => 23
          , adulto  => 60
          , vecchio => 75 );
$eta_ora = 27;
if ( $eta_ora >= $stadio{vecchio} )
{ 
   print "all'eta' di $eta_ora sei un anziano \n"; 
}
else
{
  if ( $eta_ora >= $stadio{adulto} )
  { 
     print "all'eta' di $eta_ora sei un vecchio \n"; 
  }
  else
  {
    if ( $eta_ora >= $stadio{giovane} )
    { 
      print "all'eta' di $eta_ora sei un adulto \n"; 
    }
    else
    {
      if ( $eta_ora >= $stadio{ragazzo} )
      { 
        print "all'eta' di $eta_ora sei un giovane \n"; 
      }
      else
      { 
        if ( $eta_ora >= $stadio{bambino} )
        { 
          print "all'eta' di $eta_ora sei un ragazzo \n"; 
        }
        else
        { 
          print "all'eta' di $eta_ora sei un bambino \n"; 
        }
      }
    }
  }
}

unless , else

Unless è in if al "contrario" cioè se NON si verifica la condizione allora viene eseguito. Vediamo gli esempi precedenti con unless (dove è possibile applicarli).

%stadio = (  bambino => 14
          , ragazzo => 17
          , giovane => 23
          , adulto  => 60
          , vecchio => 75 );
$eta_ora = 27;

print "all'eta' di $eta_ora NON sei un bambino \n" unless ( $eta_ora < 14 ) ;
print "all'eta' di $eta_ora NON sei un bambino \n" unless ( $eta_ora < $stadio{bambino} ) ;
NOTA: il punto e virgola a indicare la fine dell'istruzione.Inoltre all'unless (se usato in fondo) si può associare SOLO una istruzione.

unless ( $eta_ora < $stadio{bambino} ) { print "all'eta' di $eta_ora NON sei un bambino \n"; }

NOTA: a differenza di if , unless non ha un "elsunless" ne tantomeno "elsif"

%stadio = (  bambino => 14
          , ragazzo => 17
          , giovane => 23
          , adulto  => 60
          , vecchio => 75 );
$eta_ora = 27;

unless ( $eta_ora > $stadio{bambino} )
{ 
  print "all'eta' di $eta_ora sei un bambino \n"; 
}
else
{
  unless ( $eta_ora > $stadio{ragazzo} )
  { 
     print "all'eta' di $eta_ora sei un ragazzo \n"; 
  }
  else
  {
    unless ( $eta_ora > $stadio{giovane} )
    {
      print "all'eta' di $eta_ora sei un giovane \n"; 
    }
    else
    {
      unless ( $eta_ora > $stadio{adulto} )
      {
        print "all'eta' di $eta_ora sei un adulto \n"; 
      }
      else
      {
        unless ( $eta_ora > $stadio{anziano} )
        { 
           print "all'eta' di $eta_ora sei un anziano \n"; 
        }
        else
        {
           print "all'eta' di $eta_ora sei un vecchio \n"; 
        }  
      }      
    }
  }
}

NOTA:unless è utile per le funzioni es:

unless ( open ( FILE , "<pippo.txt" ) ) { print "non posso aprire pippo.txt"; exit 10; }

I CICLI

I cicli sono una serie di "azioni" ripetute "fino a" o "un certo numero di volte". Le azioni sono contenute in un blocco.Ogni volta che si esegue un blocco viene detto "iterazione". Ognuno di questi costrutti ha un elemento decisionale che serve a determinare la fine del ciclo. NOTA: non è obbligatorio che in ciclo finisca.

for

Il ciclo for è quello più comune a molti linguaggi. Da questo è possibile ottenere delle altre tipologie ma nell'uso generale si preferisce utilizzarlo quando il numero di iterazioni è noto.La sua sintassi è la seguente:

for ( <inizio> ; <condizione> ; <incremento> )
{
   ... istruzioni ...
}

vediamo un esempio [ciclo finito]:

my $max_valore = 10;

my $b;
for ( $b = 0 ; $b < $max_valore ; $b++ )
{
   print "iterazione numero $b\n";
}
print "b=$b\n";

che produrrà :

iterazione numero 0
iterazione numero 1
iterazione numero 2
iterazione numero 3
iterazione numero 4
iterazione numero 5
iterazione numero 6
iterazione numero 7
iterazione numero 8
iterazione numero 9
b=10

vediamo ora che cosa succede se togliamo la condizione (CTRL+C per fermare) [ciclo infinito1 no condizione]:

my $b;
for ( $b = 0 ;  ; $b++ )
{
   print "iterazione numero $b\n";
}
print "Ultima iterazione numero $b\n";

Sorpresi ? se non c'è una condizione che ferma il ciclo (o se questa non si verifica mai!) il ciclo continua indefinitamente!

vediamo ora che cosa succede se togliamo l'incremento (CTRL+C per fermare) [ciclo infinito2 no incremento]:

my $max_valore = 10;

my $b;
for ( $b = 0 ; $b < $max_valore ; )
{
   print "iterazione numero $b\n";
}
print "b=$b\n";

Sorpresi ? se non c'è un incremento la condizione che ferma il ciclo sarà sempre vera quindi il ciclo continua indefinitamente! NOTA: Continua indefinitamente perchè nel blocco $b non viene alterata e quindi il suo valore rimane costante.Pertanto la condizione

$b < $max_valore 

è sempre vera.

vediamo ora che cosa succede se togliamo l'inizio [ciclo finito senza inizio]:

my $max_valore = 10;

my $b;
for ( ; $b < $max_valore ; $b++ )
{
   print "iterazione numero $b\n";
}
print "b=$b\n";

che produrrà:

iterazione numero   
iterazione numero 1 
iterazione numero 2 
iterazione numero 3 
iterazione numero 4 
iterazione numero 5 
iterazione numero 6 
iterazione numero 7 
iterazione numero 8 
iterazione numero 9 
b=10

Come si vede , mancando un valore iniziale a $b è stato messo il valore undef che nel caso della condizione viene posto a uguale al valore 0 mentre nel caso della stringa viene posto uguale al valore "".Dopo la prima iterazione dal valore undef diventa 1 per effetto della chiamata $b++ e poi si incrementa.

While e Until

Il ciclo while è come il ciclo for con la sola condizione. Le istruzioni nel blocco vengono eseguite fino a quando la condizione è vera. Il ciclo until è come il ciclo while ma vengono eseguite le istruzioni se la condizione NON è verificata.


while ( <condizione> )   
{
   ... istruzioni ...
}
until ( <condizione> )   
{
   ... istruzioni ...
}

Vediamo come ottenere i cicli precedenti con while e until: [ciclo finito]

my $max_valore = 10;

my $b=0;
while ( $b < $max_valore )
{
   print "iterazione numero $b\n";
   $b++ ;
}
print "b=$b\n";


my $max_valore = 10;

my $b=0;
until ( $b > $max_valore - 1 )
{
   print "iterazione numero $b\n";
   $b++ ;
}
print "b=$b\n";

[ciclo infinito1 no condizione]: la condizione è necessaria quindi questo caso non è possibile.

[ciclo infinito2 no incremento] (CTRL + C per terminare):

my $max_valore = 10;

my $b=0;
while ( $b < $max_valore )
{
   print "iterazione numero $b\n";
}
print "b=$b\n";


my $max_valore = 10;

my $b=0;
until ( $b > $max_valore - 1 )
{
   print "iterazione numero $b\n";
}
print "b=$b\n";

[ciclo finito senza inizio ] :

my $max_valore = 10;

my $b;
while ( $b < $max_valore )
{
   print "iterazione numero $b\n";
   $b++ ;
}
print "b=$b\n";


my $max_valore = 10;

my $b;
until ( $b > $max_valore - 1 )
{
   print "iterazione numero $b\n";
   $b++ ;
}
print "b=$b\n";

Do ... While e Do ... Until

Questo costrutto è nella realtà una chiamata a funzione. Apparentemente assomiglia al costrutto sintattico di altri linguaggi ma perde (come ogni chiamata a funzione) la possibilità di usare i modificatori di ciclo. E' un costrutto usato se occorre fare almeno una iterazione e poi un controllo. Si basa sul principio di while e until con l'unica differenza che la condizione viene verificata alla fine del blocco di istruzioni , pertanto almeno una volta le istruzioni vengono eseguite.

do
{
   ... istruzioni ...
}
while ( <condizione> );
do
{
   ... istruzioni ...
}
until ( <condizione> );

NOTA:avete notato il ; alla fine ?

Riportiamo gli esempi con questo costrutto: [ciclo finito]

my $max_valore = 10;

my $b=0;

do
{
   print "iterazione numero $b\n";
   $b++ ;
} while ( $b < $max_valore );

print "b=$b\n";


my $max_valore = 10;

my $b=0;

do
{
   print "iterazione numero $b\n";
   $b++ ;
} until ( $b > $max_valore - 1 );
 
print "b=$b\n";

[ciclo infinito1 no condizione]: la condizione è necessaria quindi questo caso non è possibile.

[ciclo infinito2 no incremento] (CTRL + C per terminare):

my $max_valore = 10;

my $b=0;

do
{
   print "iterazione numero $b\n";
} while ( $b < $max_valore );
 
print "b=$b\n";


my $max_valore = 10;

my $b=0;
do
{
   print "iterazione numero $b\n";
} until ( $b > $max_valore - 1 );

print "b=$b\n";

[ciclo finito senza inizio ] :

my $max_valore = 10;

my $b;
do
{
   print "iterazione numero $b\n";
   $b++ ;
} while ( $b < $max_valore );

print "b=$b\n";


my $max_valore = 10;

my $b;

do
{
   print "iterazione numero $b\n";
   $b++ ;
} until ( $b > $max_valore - 1 );
print "b=$b\n";

E' opportuno precisare che modificando opportunamente i valori iniziali , è possibile ottenere che venga eseguito almeno una volta il ciclo utilizzando while o until Vediamo questo esempio: [do ... while ]

my $anni = 15;
do
{
   print "hai avuto anche $anni\n";
   $anni-- ;
} while ( $anni > 0 );

che produce :

hai avuto anche 15
hai avuto anche 14
hai avuto anche 13
hai avuto anche 12
hai avuto anche 11
hai avuto anche 10
hai avuto anche 9
hai avuto anche 8
hai avuto anche 7
hai avuto anche 6
hai avuto anche 5
hai avuto anche 4
hai avuto anche 3
hai avuto anche 2
hai avuto anche 1
hai avuto anche 0

NOTA:se $anni = 0 viene almeno scritta una riga : "hai avuto anche 0" [do ... until ]

my $anni = 15;
do
{
   print "hai avuto anche $anni\n";
   $anni-- ;
} until ( $anni < 0 );

[while]

my $anni = 15;

while ( $anni >= 0 )
{
   print "hai avuto anche $anni \n";
   $anni-- ;
}

[until]

my $anni = 15;

until ( $anni <= 0 )
{
   print "hai avuto anche $anni \n";
   $anni-- ;
}

Foreach

Questa istruzione consente di "scandire" una lista (array).

foreach <variabile> ( <lista> )
{
    ... istruzioni ...
}

Vediamo ora come è possibile creare il [ciclo finito]:

my $max_valore = 10;

my $b;

foreach $b ( 0 .. ($max_valore - 1) )
{
   print "iterazione numero $b\n";
}
print "b=$b\n";

che produrrà :

iterazione numero 0
iterazione numero 1
iterazione numero 2
iterazione numero 3
iterazione numero 4
iterazione numero 5
iterazione numero 6
iterazione numero 7
iterazione numero 8
iterazione numero 9
b=9

NOTA: $b non è stato incrementato ma assume il valore di volta in volta contenuto in lista.Infatti non ha valore 10 ma 9 !