English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
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.
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.
#!/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>
Puoi usare rescue Il blocco cattura l'eccezione e poi utilizza retry La frase inizia dall'inizio del blocco. begin blocco.
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
#!/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.
Puoi usare raise La frase lancia un'eccezione. Il metodo seguente lancia un'eccezione durante la chiamata. Il secondo messaggio viene outputto.
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.
#!/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:
#!/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"]
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.
begin #.. Processo #.. Lanciare un'eccezione rescue #.. Gestire gli errori ensure #.. Assicurare che venga eseguito per ultimo #.. Questo viene sempre eseguito end
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
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.
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
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.
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.
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
Nel seguente esempio, se l'utente inserisce '!' come risposta a qualsiasi prompt, viene utilizzato un throw per terminare l'interazione con l'utente.
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
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:
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:
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.