giovedì 16 febbraio 2012

Eccoci alle funzioni!

 Salve!

Con questo post iniziamo a parlare delle funzioni. Lo so, è passato un pò di tempo dall'ultimo post, ma purtroppo non sto vivendo proprio dei bei momenti... Lasciamo stare, va. Che è meglio.

Come ormai saprete, il progetto bash non è un corso su bash, ma un invito a cimentarsi con il linguaggio bash.
Niente di più. Il nostro sforzo è tutto diretto ad esprimerci nel modo più semplice possibile. Ma la cosa bella è che sono stati in molti ad aver espresso il loro gradimento. Non può che farci tanto piacere. Veramente. :))

Presto tutti questi articoli saranno rivisitati, rielaborati e trasformati in pdf.
Forse faremo dei fascicoli che pubblicheremo di volta in volta e che voi potrete scaricare. :)

Passiamo alle funzioni. Prima di dire a cosa servono, cerchiamo di capire come si scrivono.

Il costrutto di una funzione può essere scritto in due modi diversi.

primo metodo:

function nome_funzione() {
comandi
 }

secondo metodo:

nome_funzione() {
comandi
 }

o addirittura su una sola riga.

Come potete vedere cambia ben poco! Si scrive prima il nome della funzione seguito dalle parentesi tonde. All'interno delle parentesi graffe, invece, si scrive il comando (o comandi) che si vuole eseguire. Estremamente semplice, vero?

In altri termini, una funzione consta:

1. del nome seguito da "()"
2. di uno o più comandi racchiusi tra parentesi graffe.

Tutto qui!

Le funzioni entrano (o dovrebbero entrare) in gioco quando c'è da iterare, ripetere blocchi di codice. E non solo, ma di questo
ne parleremo in altri post. Procediamo per gradi.

Una funzione si dichiara in maniera molto semplice:

#!/bin/bash
function ciao() {
  echo " ciao nonno"
}
ciao

Come potete notare, all'interno delle parentesi graffe abbiamo aggiunto un comando, nella fattispecie "echo"
Lanciato lo script, subito dopo la prima riga (#!/bin/bash), bash legge la funzione ma non la esegue.
Essa verrà presa in cosiderazione solo quando verrà richiamata.

Come si richiama una funzione?

Una funzione si richiama col suo nome. Nell'esempio di cui sopra, la funzione viene richiamata col nome "ciao"

Se omettessi di scrivere, alla fine, il nome della funzione, lo script non farebbe proprio nulla. Chiaro?

Ma non è tutto!

Alle funzioni possiamo passargli anche una o più variabili.

#!/bin/bash

a=10
b=10

function somma() {

totale=$((a+b))

echo $totale
}

somma $a $b


In questo caso dichiaro due variabili e le passo alla funzione somma. Si, in questo caso la funzione ha per nome "somma." All'interno della parentesi graffe abbiamo messo due comandi: il costrutto $((...)) che serve a svolgere operazioni aritmetiche e il comando echo.
Subito dopo la parentesi graffa chiusa, abbiamo richiamato la funzione con suo nome (somma appunto) insieme alle due variabili dichiarate.

Facciamo un altro esempio semplice semplice :))

#!/bin/bash

function confronto() {

if [ $primo -gt $secondo ]; then
   echo "Il primo numero immesso è maggiore rispetto al secondo"
else
   echo "il primo numero immesso è pari o inferiore al secondo"

fi

exit
}

echo "dammi un numero: "
read primo

echo "dammi un secondo numero: "
read secondo

confronto $primo $secondo

exit 0


Faccio una piccola premessa. Questi esempi servono esclusivamente a capire come "ragiona e come si comporta" una funzione.
Ciò detto, in questo piccolo script dichiaro una funzione che chiamo "confronto"
All'interno delle parentesi graffe metto un costrutto if col compito di controllare se il primo numero è maggiore del secondo.
Usciti dalla funzione, "riempio" di contenuto, tramite il comando read, sia la variabile di nome "primo" che la variabile di nome "secondo". Ricordate? Le variabili altro non sono che dei contenitori!

Come si comporta lo script?

Cerchiamo di descriverne, in modo ordinato (si fa per dire), tutti i passaggi logici.

  • Anzitutto legge la prima riga e capisce che l'interprete è bash
  • legge la funzione ma non la esegue. Ricordate? la funzione viene eseguita solo se richiamata. Per ora prende atto della sua esistenza.
  • Legge il primo echo, esegue il primo read, inserisce il valore che noi gli passiamo nella prima variabile (che abbiamo chiamato "primo")
  • Legge il secondo echo, esegue il secondo read, inserisce il valore che noi gli passiamo nella seconda variabile (che abbiamo chiamato "secondo")
  • Richiama la funzione "confronto" e gli passa la variabile $primo e la variabile $secondo. Come potete notare, bash risalirà lo script, entrerà nella funzione "confronto" e, solo ora, la eseguirà.
Penso che ora sia chiara una cosa: La funzione viene eseguita solo se richiamata!

Facciamo un altro esempio.

#!/bin/bash

function confronto() {

if [ $primo -gt $secondo ]; then
   echo "Il primo numero immesso è maggiore rispetto al secondo"
else
   echo "il primo numero immesso è uguale o inferiore al secondo"
fi

}

echo "dammi un numero: "
read primo

echo "dammi un secondo numero: "
read secondo

#la funzione viene eseguita per la prima volta
echo "primo risultato:"
confronto $primo $secondo

secondo=$((secondo / 2))

#la funzione viene eseguita per la seconda volta
echo "secondo risultato:"
confronto $primo $secondo

exit 0


Cosa fa lo script?
  • Legge l'interprete bash
  • Si accorge che esiste una funziona ma non la esegue
  • Esegue ECHO e READ del primo valore
  • Esegue ECHO e READ del secondo valore
  • CHIAMA la funzione "confronto"
  • BASH entra dentro la funzione "confronto" e la esegue (per la prima volta)"
  • BASH esce dalla funzione ed esegue l'istruzione "secondo=$((secondo / 2))"
  • Una volta eseguita l'istruzione "secondo=$((secondo / 2))",va avanti e richiama, per la seconda volta, la funzione "confronto", e la esegue (per la seconda volta).
Badate, anche se la stessa funzione viene richiamata due volte, le circostanze sono diverse: la variabile $secondo è stata dimezzata, è stata divisa per 2. Perciò il risultato del controllo potrebbe essere differente rispetto al primo.

Per comprenderne la portata, conviene lanciare lo script.
Salvate lo script sulla scrivania, nominate il file col nome funzione.sh, dal terminale spostatevi nella directory Scrivania

cd Scrivania

e lanciate lo script

bash funzione.sh

Capite ora l'importanza delle funzioni? Se non ci fosse stata la possibilità di utilizzare una funzione avremmo dovuto riscrivere l'IF per ben due volte allungando di molto il codice.

Per concludere, le funzioni non sono obbligatorie, ma se si tratta di script complessi, corposi e con tanti controlli, le funzioni sono come la manna piovuta dal cielo. :))

PS1. Penso proprio che ci dilungheremo un pò sulle funzioni; perciò aspettatevi altri post sia nella sezione teorica che pratica del progetto bash.
PS2. Il caro Lightuono, nella sua parte pratica sulle funzioni, ci delizierà, oltre che con i suoi effetti speciali, anche con schemi grafici.
PS3. Per non perdere il filo, vi consiglio sempre di consultare l'indice del progetto. qui e qui.

Alla prossima. :))

Io e Lightuono

2 commenti:

  1. Dal il Progetto Bash è interessante. È incredibile come si possano fare cose molto più sinteticamente che con un linguaggio di programmazione normale. E poi è molto più da geek / nerd!

    RispondiElimina
  2. E io lo aggiungo ai miei preferiti!

    RispondiElimina