Programmazione.it v6.4
Ciao, per farti riconoscere devi fare il login. Non ti sei ancora iscritto? Che aspetti, registrati adesso!
Info Pubblicità Collabora Autori Sottoscrizioni Preferiti Bozze Scheda personale Privacy Archivio Libri Corsi per principianti Forum
Corso su Ruby: le eccezioni
Scritto da Satish Talim il 23-07-2007 ore 09:28
Intel Parallel Studio XE
Le eccezioni sono un tipo speciale di oggetti, un’istanza della classe Exception o un discendente di essa. Sollevare un’eccezione significa interrompere la normale esecuzione del programma, trattare il problema che si è verificato o arrestare il programma. Tutto dipende dalla creazione della clausola rescue, poiché se questa operazione non è stata eseguita, il programma verrà terminato. Ruby ha delle classi predefinite — Exception e le sue sottoclassi — che permettono di gestire gli errori che possono verificarsi nei programmi. La figura che segue, tratta dal libro Programming Ruby, mostra la gerarchia delle eccezioni di Ruby:

<center>875109108_e407eb0493_o.jpg</center>

Il metodo che segue solleva una eccezione ogni volta che viene chiamato; il suo secondo messaggio non verrà mai stampato. Segue un programma di esempio, p043raise.rb:
  1. <span style="font-size:1.0em">
  2. def raise_exception
  3.   puts 'Prima dell'eccezione.'
  4.   raise 'Verifica dell'errore'
  5.   puts 'Dopo l'eccezione'
  6. end
  7. raise_exception</span>

L'output è:
  1. <span style="font-size:1.0em">
  2. >ruby p043raise.rb
  3. Prima dell'eccezione.
  4. raise.rb:3:in `raise_exception': An error has occured (RuntimeError)
  5.       from raise.rb:6
  6. >Exit code: 1</span>

Il metodo raise fa parte del modulo Kernel. Per default, raise crea un’eccezione della classe RuntimeError. Per sollevare un’eccezione di una specifica classe, è possibile passare il nome della classe come argomento di raise. Ecco il programma p044inverse.rb:
  1. <span style="font-size:1.0em">
  2. def inverse(x)
  3.   raise ArgumentError, 'Argument is not numeric' unless x.is_a? Numeric
  4.   1.0 / x
  5. end
  6. puts inverse(2)
  7. puts inverse('not a number')</span>

L'output è:
  1. <span style="font-size:1.0em">
  2. >ruby p044inverse.rb
  3. 0.5
  4. inverse.rb:2:in `inverse': Argument is not numeric (ArgumentError)
  5.       from inverse.rb:6
  6. >Exit code: 1</span>

Da tenere presente, i metodi che agiscono come interrogazioni prendono nomi con un ? che segue s_a?; è un metodo nella classe Object e restituisce vero o falso. Il modificatore unless, quando agganciato alla fine di un normale comando, significa “esegui l'espressione precedente a meno che la condizione sia vera”. Per essere più specifici circa il prodursi di un errore, è possibile definire le proprie sottoclassi di Exception:
  1. <span style="font-size:1.0em">
  2. class NotInvertibleError < StandardError
  3. end</span>

Per gestire le eccezioni, racchiudiamo il codice che potrebbe sollevare un’eccezione in un blocco begin/end e usiamo una o più clausole rescue per dire a Ruby il tipo di eccezione che vogliamo trattare. Il programma 0045handexcp.rb mostra questa procedura:
  1. <span style="font-size:1.0em">
  2. def raise_and_rescue
  3.   begin    
  4.     puts 'Prima dell'eccezione'
  5.     raise 'Verifica dell'errore'
  6.     puts 'Dopo l'eccezione'
  7.   rescue
  8.     puts 'Problema risolto.'
  9.   end
  10.   puts 'Dopo l'inizio del blocco.'
  11. end
  12. raise_and_rescue</span>

L'output è:
  1. <span style="font-size:1.0em">
  2. >ruby p045handexcp.rb
  3. Prima dell'eccezione.
  4. Problema risolto.
  5. Dopo l'inizio del blocco.
  6. >Exit code: 0</span>

Da osservare che il codice interrotto dall'eccezione non viene mai eseguito. Una volta che l'eccezione è gestita, l'esecuzione continua immediatamente dopo il blocco begin che l'ha generata.

Se si scrive una clausola rescue senza lista di parametri, i parametri vengono per default da StandardError. Ciascuna clausola rescue può specificare più eccezioni da intercettare. Alla fine di ciascuna clausola rescue si può dare a Ruby il nome di una variabile locale nella quale viene ricevuta l'espressione corrispondente. I parametri della clausola rescue possono essere espressioni arbitrarie (comprese chiamate ai metodi), che restituiscono una classe Exception. Se utilizziamo raise senza parametri, esso risolleverà l'eccezione. Si possono impilare clausole rescue in un blocco begin/rescue. Le eccezioni non gestite da una clausola rescue vengono passate alla successiva.
  1. <span style="font-size:1.0em">
  2. begin
  3.   # -
  4. rescue OneTypeOfException
  5.   # -
  6. rescue AnotherTypeOfException
  7.   # -
  8. end</span>

Per ogni clausola rescue nel blocco begin, Ruby confronta le Exception sollevate con ciascuno dei parametri a rotazione. Il confronto ha successo se l'eccezione nominata nella clausola rescue ha lo stesso tipo di quella sollevata, o è una superclasse di quella eccezione. Se si vuole interrogare un’eccezione recuperata, è possibile mappare l'oggetto Exception in una variabile all'interno della clausola rescue, come mostrato nel programma p046excpvar.rb:
  1. <span style="font-size:1.0em">
  2. begin
  3.   raise 'A test exception.'
  4. rescue Exception => e
  5.   puts e.message
  6.   puts e.backtrace.inspect
  7. end</span>

L'output è:
  1. <span style="font-size:1.0em">
  2. >ruby p046excpvar.rb
  3. A test exception.
  4. ["excpvar.rb:2"]
  5. >Exit code: 0</span>

Se si ha bisogno della garanzia che qualche elaborazione sia eseguita alla fine di un blocco di codice che si siano o meno verificate eccezioni, allora è necessaria una clausola ensure,che deve essere messa alla fine dell'ultima clausola rescue e contiene il pezzo di codice che deve essere sempre eseguito alla fine del blocco. Ensure garantisce che il blocco verrà sempre eseguito. Alcune comuni eccezioni sono mostrate nella seguente tabella, tratta da Ruby For Rails:

<center>874309041_6428279a01_o.jpg</center>

"Traduzione e adattamento a cura di Francesca Beatrice Cice. La versione originale del tutorial di Satish Talim può essere trovata su rubylearning.com"
Precedente: Risolto il gioco della dama
Successiva: Web Tools Platform per Eclipse
Copyright Programmazione.it™ 1999-2013. Alcuni diritti riservati. Testata giornalistica iscritta col n. 569 presso il Tribunale di Milano in data 14/10/2002. Pagina generata in 0.323 secondi.