Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Procedure o funzioni?

Capire la differenza tra due costrutti che si rivelano molto simili
Capire la differenza tra due costrutti che si rivelano molto simili
Link copiato negli appunti

Due articoli già pubblicati descrivono la struttura e l'utilizzo Impariamo ad usare le procedure, chiamate anche comunemente sub, e Impariamo ad usare le funzioni, chiamate invece function. Siccome il modello Object Oriented di ASP è decisamente limitato rispetto ad altri linguaggi potrebbe non essere così immediata la differenza tra questi due costrutti che si rivelano molto simili.

Per semplificare la differenza possiamo pensare alle funzioni come singole istruzioni formate da un numero limitato di comandi, che possono comparire in modo ripetuto nel nostro codice. Racchiudere questo numero di comandi in una funzione ci permette con una sola chiamata di eseguirli in un colpo solo e di non dover ripetere righe di codice uguali in diverse parti del programma.

Una sub è invece una vera e propria procedura, ovvero un insieme complesso di comandi ed esecuzioni che può anche contenere, al suo interno, delle funzioni precedentemente dichiarate.

Esempio teorico

Immaginiamo di aver creato un programma per la gestione di alcuni conti finanziari. Il nostro programma potrebbe avere delle procedure complesse di trasferimento, deposito e prelievo. All'interno di queste istruzioni potremmo poi individuare una serie di minioperazioni di utilità, come ad esempio una conversione di una somma in valute, un calcolo semplice su un interesse ed un calcolo sul costo percentuale di una operazione.

Ecco che potremmo quindi individuare:

Funzioni di utilità

  • converti_valuta()
    Accetta un valore in una valuta espressa e lo restituisce nella valuta richiesta
  • calcola_interesse()
    Calcola un interesse semplice percentuale in base al valore percentuale fornito
  • calcola_spesa_operazione()
    Calcola la spesa di una operazione in base al valore percentuale fornito
  • calcola_risultato_operazione()
    Calcola il risultato della operazione sottraendone la spesa calcolata da
    calcola_spesa_operazione()

Come è facile comprendere, tutte queste operazioni sono semplici insiemi di comandi che, presi una serie di parametri, restituiscono il risultato dei calcoli. L'ultimo esempio mostra poi come sia possibile richiamare una funzione dentro ad un'altra funzione o eventualmente, adottare il meccanismo della ricorsione che consente ad una funzione di richiamare sé stessa.

Procedure

  • deposita()
    Esegue il deposito di una somma di denaro, aggiornando tutte le operazioni correlate, compresi estratti conti, situazioni bancarie. È in grado di riconoscere la valuta in ingresso e di convertirla se necessario nel rispettivo controvalore in € necessario per la transazione.
  • preleva()
    Esegue il prelievo di una somma di denaro, eseguendo tutti gli aggiornamenti correlati e le conversioni necessarie come la procedura di deposito.
  • trasferimento()
    Esegue il trasferimento di una somma di denaro da un conto iniziale ad uno destinatario, utilizzando le procedure di deposito e quelle di prelievo sui rispettivi conti bancari.

Le procedure sono invece operazioni decisamente più complesse, che non si accontentano di eseguire qualche singola operazione ma un elenco di comandi. Al loro interno possono poi richiamare le funzioni con lo scopo di ottimizzare la scrittura del codice.

Esiste poi un'ulteriore importante differenza che è determinante per la scelta tra una procedura o una funzione. Le funzioni sono studiate per restituire un valore, generalmente il risultato del calcolo, le procedure invece per eseguire delle istruzioni.

Questo è facilmente riscontrabile anche nella logica adottata dalle componenti di codice riportate nell'esempio della struttura bancaria prima abbozzata.

Esempio pratico: dichiarare e costruire il costrutto

Procedure

  • eseguono dei comandi e non restituiscono valori
  • contengono un elenco di istruzioni racchiuse tra delle voci Sub e End Sub
  • accettano parametri, indicati tra () dopo al nome della sub
  • sono richiamate genericamente mediante il comando call nomesub()

Esempio senza parametri:

' Scompone la data corrente
' nei singoli valori temporali
' e li stampa a video.
Sub scomponi_data_corrente()

Dim dtmDate
dtmDate = Now()
Response.Write("<br />Giorno : " & Day(dtmDate))
Response.Write("<br />Mese : " & Month(dtmDate))
Response.Write("<br />Anno : " & Year(dtmDate))
Response.Write("<br />Ora : " & Hour(dtmDate))
Response.Write("<br />Minuti : " & Minute(dtmDate))
Response.Write("<br />Secondi : " & Second(dtmDate))

End Sub

Esempio con parametri:

' Scompone la data passata come parametro
' nei singoli valori temporali
' e li stampa a video.
Sub scomponi_data (ByVal dtmDate)

Response.Write("<br />Giorno : " & Day(dtmDate))
Response.Write("<br />Mese : " & Month(dtmDate))
Response.Write("<br />Anno : " & Year(dtmDate))
Response.Write("<br />Ora : " & Hour(dtmDate))
Response.Write("<br />Minuti : " & Minute(dtmDate))
Response.Write("<br />Secondi : " & Second(dtmDate))

End Sub

Funzioni

  • eseguono dei comandi e restituiscono valori
  • contengono un elenco di istruzioni racchiuse tra delle voci Sub e End Sub
  • accettano parametri, indicati tra () dopo al nome della funzione
  • sono richiamate genericamente assegnando il risultato ad una variabile o un comando, tramite la sintassi variabile = nomefunzione()

Esempio senza parametri:

' Individua il giorno corrente
' e ne restituisce il valore
' formattato a 2 cifre
' anteponendo uno 0 se necessario.
Function formatta_giorno_corrente_dd()

Dim dtmDate, dtmDay
dtmDate = Now()
dtmDay = Day(dtmDate)

' Controlla il formato
if Cint(dtmDay) < 10 then dtmDay = "0" & dtmDay

' Ritorna il valore
formatta_giorno_corrente_dd = dtmDay

End function

Esempio con parametri:

' Individua il giorno della data come parametro
' e ne restituisce il valore
' formattato a 2 cifre
' anteponendo uno 0 se necessario.
Function formatta_giorno_dd(dtmDate)

Dim dtmDay
dtmDay = Day(dtmDate)

' Controlla il formato
if Cint(dtmDay) < 10 then dtmDay = "0" & dtmDay

' Ritorna il valore
formatta_giorno_dd = dtmDay

End function

Richiamare il costrutto

È in questa fase che si ha la differenza fondamentale. Ricordiamoci infatti che una funzione è nata per restituire un valore, al contrario di una sub.

Per richiamare una procedura è generalmente sufficiente usare il comando call:

Call scomponi_data_corrente()
Call scomponi_data(Now())

E le istruzioni all'interno saranno elaborate.

Richiamare una funzione è invece differente. È necessario specificare cosa fare del valore restituito ed è quindi possibile assegnarlo ad una variabile o ad una ulteriore funzione, ad esempio una stampa:

Response.Write(formatta_giorno_corrente_dd())
variabile = formatta_giorno_corrente_dd()
Response.Write(formatta_giorno_dd())
variabile = formatta_giorno_dd()

Cattive abitudini

Spesso si incontrano funzioni gestite come procedure , ovvero funzioni dichiarate come tali nella definizione ma che non restituiscono valori e, a maggior ragione, sono richiamate con il comando call nel codice.

Questa forma non rappresenta tuttavia un corretto utilizzo degli strumenti di ASP ed è una pratica sconsigliata per evitare di creare confusioni a eventuali lettori del codice.

Ti consigliamo anche