Dopo aver visto come si sollevano le eccezioni diamo uno sguardo alla loro gestione attraverso rescue
ed ensure
. Supponiamo di aver scritto una applicazione che si comporta in modo diverso a seconda che esista o meno una determinata libreria. Vogliamo dunque intercettare un'eventuale eccezione LoadError
e comportarci di conseguenza. Per catturare le eccezioni scriviamo il tutto in un blocco begin/end, ad esempio:
begin require 'gmailer' GMAIL_SUPPORTED = true rescue LoadError GMAIL_SUPPORTED = false end
in questo modo impostiamo la costante GMAIL_SUPPORTED
in base alla disponibilità della libreria gmailer. È possibile anche indicare più clausole rescue
all'interno dello stesso blocco, mentre se non si indica nessun argomento rescue intercetterà tutti gli errori che discendono da StandardError
. Per recuperare il valore dell'eccezione va utilizzata questa sintassi:
begin require 'gmailer' GMAIL_SUPPORTED = true rescue LoadError => error puts "L'errore è: #{error}" GMAIL_SUPPORTED = false end
e in caso di eccezione LoadError
vedremo sullo schermo la scritta "L'errore è: no such file to load -- gmailer". All'interno del corpo di rescue si può inserire un'istruzione retry
con la funzione di rieseguire il blocco dall'inizio, ovviamente prima di retry
vanno eseguite delle istruzioni atte a risolvere il problema riscontrato. Infine c'è la clausola ensure
utile quando si devono eseguire delle operazioni all'uscita da un blocco begin/end. Un classico esempio è quello della gestione dei file:
file = File.open("test.txt") begin # operazioni varie sul file rescue # gestione degli errori ensure file.close unless file.nil? end
Nel blocco principale vengono eseguite le normali operazioni sul file aperto, poi c'è il blocco rescue
per la gestione degli errori e infine nel blocco ensure
ci sono le istruzioni per chiudere il file. In questo modo siamo sicuri che all'uscita dal blocco il file verrà chiuso.
Oltre che all'interno dei blocchi begin/end, è possibile gestire le eccezioni anche all'interno dei normali metodi, il cui corpo è implicitamente un blocco begin/end:
def nome_metodo # istruzioni varie rescue # gestione degli errori end