English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Ruby Exceptions

Le eccezioni e l'esecuzione sono sempre collegate. Se apri un file non esistente e non gestisci correttamente questa situazione, il tuo programma viene considerato di bassa qualità.

Se si verifica un'eccezione, il programma si ferma. Le eccezioni vengono utilizzate per gestire vari tipi di errori che possono verificarsi durante l'esecuzione del programma, quindi è necessario adottare misure appropriate per evitare che il programma si fermi completamente.

Ruby fornisce un meccanismo perfetto per la gestione delle eccezioni. Possiamo begin/end nel blocco aggiungi il codice che potrebbe sollevare un'eccezione, utilizzando rescue la clausola informa Ruby del tipo di eccezione che deve essere gestita correttamente.

Sintassi

begin # inizia
 
 raise.. # solleva un'eccezione
 
rescue [ExceptionType = StandardException] # cattura l'eccezione di tipo specificato con valore predefinito StandardException
 $! # indica l'informazione dell'eccezione
 $@ # indica la posizione del codice in cui è avvenuta l'eccezione
else # altre eccezioni
 ..
ensure # indipendentemente da eventuali eccezioni, entra nel blocco di codice
 
end # Fine

da begin a rescue tutto è protetto. Se si verifica un'eccezione durante l'esecuzione del blocco di codice, il controllo viene trasmesso a rescue in end e

tra begin ogni rescue clausole, Ruby confronta l'eccezione lanciata con ogni parametro. Se l'eccezione nominata nella clausola rescue è la stessa dell'eccezione lanciata o un suo superclasse, avviene una corrispondenza di successo.

Se l'eccezione non corrisponde a tutti i tipi di errori specificati, possiamo avere tutte le rescue Dopo la clausola else clausola.

Online Examples

#!/usr/bin/ruby
 
begin
   file = open("/unexistant_file")
   if file
      puts "File aperto con successo"
   end
rescue
      file = STDIN
end
print file, "==", STDIN, "\n"

Il risultato di esecuzione dell'esempio sopra riportato e'. Puoi vedere che,STDIN sostituisce file perchéL'aperturaFallisce.

#<IO:0xb7d16f84>==#<IO:0xb7d16f84>

Usare retry Esercizio

Puoi usare rescue Il blocco cattura l'eccezione e poi utilizza retry La frase inizia dall'inizio del blocco. begin blocco.

Sintassi

begin
    # L'eccezione lanciata da questo blocco viene catturata dalla clausola rescue
rescue
    # Questo blocco cattura tutti i tipi di eccezioni
    retry # Questo riportera' il controllo all'inizio di begin
end

Online Examples

#!/usr/bin/ruby
 
begin
   file = open("/unexistant_file")
   if file
      puts "File aperto con successo"
   end
rescue
   fname = "existant_file"
   retry
end

Ecco il flusso di gestione:

  • Si verifica un'eccezione durante l'apertura.

  • Si salta a rescue. fname viene riassegnato.

  • Con retry si torna all'inizio di begin.

  • Questa volta il file è stato aperto con successo.

  • Continua con il processo di base.

Attenzione:Se il file rinominato non esiste, il codice di esempio tenta all'infinito. Quindi, durante la gestione delle eccezioni, usa con cautela retry.

Usare raise Esercizio

Puoi usare raise La frase lancia un'eccezione. Il metodo seguente lancia un'eccezione durante la chiamata. Il secondo messaggio viene outputto.

Sintassi

raise 
 
o
 
raise "Error Message" 
 
o
 
raise ExceptionType, "Error Message"
 
o
 
raise ExceptionType, "Error Message" condition

La prima forma ri-lancia semplicemente l'eccezione corrente (se non c'è un'eccezione corrente, viene lanciato un RuntimeError). Questo viene utilizzato nel gestore di eccezioni che deve spiegare l'eccezione prima di passarla.

La seconda forma crea una nuova RuntimeError Eccezione, imposta il messaggio fornito. Dopo di che l'eccezione viene lanciata nella pila delle chiamate.

La terza forma utilizza il primo parametro per creare un'eccezione e poi impostare il messaggio relativo come secondo parametro.

La quarta forma è simile alla terza, puoi aggiungere qualsiasi altra condizione aggiuntiva (come unless)per sollevare un'eccezione.

Online Examples

#!/usr/bin/ruby
 
begin  
    puts 'Sono prima del raise.'  
    raise 'Si è verificato un errore.'  
    puts 'Sono dopo il raise.'  
rescue  
    puts 'Sono stato salvato.'  
end  
puts 'Sono dopo il blocco begin.'

L'esito dell'esecuzione dell'esempio sopra è:

Sono prima del raise.  
Sono stato salvato.  
Sono dopo il blocco begin.

Un altro esempio raise Esempio di utilizzo:

Online Examples

#!/usr/bin/ruby
 
begin  
  raise 'Una eccezione di test.'  
rescue Exception => e  
  puts e.message  
  puts e.backtrace.inspect  
end

L'esito dell'esecuzione dell'esempio sopra è:

Una eccezione di test.
["main.rb:4"]

Usare ensure Esercizio

A volte, indipendentemente dal fatto che venga sollevata un'eccezione o no, è necessario garantire che alcune operazioni siano completate alla fine del blocco di codice. Ad esempio, potrebbe aprire un file all'inizio e assicurarsi di chiuderlo quando esce dal blocco.

ensure Cosa fa la clausola. ensure viene messo dopo l'ultimo rescue e contiene un blocco di codice che viene sempre eseguito alla fine del blocco. Non importa se il blocco esce normalmente, se solleva e gestisce un'eccezione, o se termina per un'eccezione non catturata,ensure Il blocco viene sempre eseguito.

Sintassi

begin 
   #.. Processo
   #.. Lanciare un'eccezione
rescue 
   #.. Gestire gli errori 
ensure 
   #.. Assicurare che venga eseguito per ultimo
   #.. Questo viene sempre eseguito
end

Online Examples

begin
  raise 'Una eccezione di test.'
rescue Exception => e
  puts e.message
  puts e.backtrace.inspect
ensure
  puts "Assicurazione dell'esecuzione"
end

L'esito dell'esecuzione dell'esempio sopra è:

Una eccezione di test.
["main.rb:4"]
Assicurazione dell'esecuzione

Usare else Esercizio

Se viene fornito else Clausola, che di solito viene posizionata rescue Dopo la clausola, qualsiasi ensure Prima di.

else Il corpo della clausola viene eseguito solo se il corpo del codice non solleva un'eccezione.

Sintassi

begin 
   #.. Processo 
   #.. Lanciare un'eccezione
rescue 
   #.. Gestire gli errori
else
   #.. Eseguire se non ci sono eccezioni
ensure 
   #.. Assicurare che venga eseguito per ultimo
   #.. Questo viene sempre eseguito
end

Online Examples

begin
 # Lanciare 'Una eccezione di test.'
 puts "Non sto sollevando un'eccezione"
rescue Exception => e
  puts e.message
  puts e.backtrace.inspect
else
   puts "Congratulazioni--nessun errore!"
ensure
  puts "Assicurazione dell'esecuzione"
end

L'esito dell'esecuzione dell'esempio sopra è:

Non sto sollevando un'eccezione
Congratulazioni--nessun errore!
Assicurazione dell'esecuzione

L'uso della variabile $! può catturare i messaggi di errore lanciati.

Catch e Throw

Il meccanismo di raise e rescue può abbandonare l'esecuzione in caso di errore, a volte è necessario uscire da alcune strutture annidate in esecuzione normale. In questi casi, catch e throw sono molto utili.

catch Definisce un blocco che utilizza un nome dato (può essere un Symbol o una String) come etichetta. Il blocco viene eseguito normalmente fino a quando non incontra un throw.

Sintassi

throw :lablename
#.. Questo non viene eseguito
catch :lablename do
#.. Dopo aver incontrato un throw, viene eseguita la catch corrispondente
end
 
o
 
throw :lablename condition
#.. Questo non viene eseguito
catch :lablename do
#.. Dopo aver incontrato un throw, viene eseguita la catch corrispondente
end

Online Examples

Nel seguente esempio, se l'utente inserisce '!' come risposta a qualsiasi prompt, viene utilizzato un throw per terminare l'interazione con l'utente.

Online Examples

def promptAndGet(prompt)
   print prompt
   res = readline.chomp
   throw :quitRequested if res == "!"
   return res
end
 
catch :quitRequested do
   name = promptAndGet("Nome: ")
   age = promptAndGet("Età: ")
   sex = promptAndGet("Sesso: ")
   # ..
   # Gestione delle informazioni
end
promptAndGet("Nome:")

Il programma sopra richiede interazione manuale, puoi provarlo sul tuo computer. Ecco l'esempio di output del programma:

Nome: Ruby on Rails
Età: 3
Sesso: !
Nome: Just Ruby

Classe Exception

Le classi e i moduli standard di Ruby lanciano eccezioni. Tutte le classi di eccezione formano una gerarchia, inclusa la classe Exception in alto. Il livello successivo è composto da sette diversi tipi:

  • Interrupt

  • NoMemoryError

  • SignalException

  • ScriptError

  • StandardError

  • SystemExit

Fatal è un'altra eccezione a questo livello, ma l'interprete Ruby lo utilizza solo internamente.

ScriptError e StandardError hanno alcuni sottoclasse, ma non è necessario conoscere questi dettagli. La cosa più importante è creare la nostra classe di eccezione, che deve essere una sottoclasse di Exception o di una sua sottoclasse.

Let's see an example:

Online Examples

class FileSaveError < StandardError
   attr_reader :reason
   def initialize(reason)
      @reason = reason
   end
end

Now, let's see the following example, which will use the above exception:

Online Examples

File.open(path, "w") do |file|
begin
    # Write data ...
rescue
    # Error occurred
    raise FileSaveError.new($!)
end
end

Here, the most important line is raise FileSaveError.new($!)We use raise to indicate that an exception has occurred, passing it to a new instance of FileSaveError due to a specific exception causing data write failure.