Qual è la differenza tra la generazione di eccezioni e la generazione di eccezioni in Ruby?

StackOverflow https://stackoverflow.com/questions/51021

  •  09-06-2019
  •  | 
  •  

Domanda

Ruby ha due diversi meccanismi di eccezione:Lancia/Prendi e Rilancia/Salva.

Perché ne abbiamo due?

Quando dovresti usare l'uno e non l'altro?

È stato utile?

Soluzione

Penso http://hasno.info/ruby-gotchas-and-caveats ha una spiegazione decente della differenza:

prendere/lanciare non sono la stessa cosa di rilanciare/salvare.catch/throw ti consente di uscire rapidamente dai blocchi fino al punto in cui è definito un catch per un simbolo specifico, raise Rescue è la vera gestione delle eccezioni che coinvolge l'oggetto Exception.

Altri suggerimenti

  • raise, fail, rescue, E ensure maniglia errori, conosciuto anche come eccezioni
  • throw E catch Sono flusso di controllo

A differenza di altre lingue, il lancio e la cattura di Ruby non sono usati per eccezioni.Invece, forniscono un modo per interrompere l'esecuzione in anticipo quando non sono necessari ulteriori lavori.(Grimm, 2011)

Terminare un singolo livello di flusso di controllo, come a while loop, può essere fatto con un semplice return.È possibile terminare molti livelli di flusso di controllo, come un ciclo annidato throw.

Sebbene il meccanismo di eccezione di raise e salvataggio sia ottimo per abbandonare l'esecuzione quando le cose vanno male, a volte è bello poter saltare fuori da qualche costrutto profondamente annidato durante la normale elaborazione.È qui che la cattura e il lancio tornano utili.(Thomas e Hunt, 2001)

Riferimenti

  1. Grimm, Avdi."Lancia, cattura, alza, salva ... Sono così confuso!" Blog di Ruilearning.Np, 11 luglio 2011.Ragnatela.1 gennaio2012. http://rubylearning.com/blog/2011/07/12/throw-catch-raise-rescue--im-so-confused/.
  2. Thomas, Dave e Andrew Hunt."Programmazione Ruby." :La guida pragmatica del programmatore.Np, 2001.Ragnatela.29 settembre2015. http://ruby-doc.com/docs/ProgrammingRuby/html/tut_exceptions.html.

https://coderwall.com/p/lhkkug/don-t-confuse-ruby-s-throw-statement-with-raise offre un'eccellente spiegazione che dubito di poter migliorare.Per riassumere, prendo alcuni esempi di codice dal post del blog mentre procedo:

  1. raise/rescue sono gli analoghi più vicini al throw/catch costrutto con cui hai familiarità da altri linguaggi (o da Python raise/except).Se hai riscontrato una condizione di errore e lo faresti throw sopra in un'altra lingua, dovresti raise in Rubino.

  2. Quello di Ruby throw/catch ti consente di interrompere l'esecuzione e risalire lo stack cercando a catch (Piace raise/rescue lo fa), ma non è realmente pensato per condizioni di errore.Dovrebbe essere usato raramente, ed è lì solo per quando "salisci lo stack finché non trovi un corrispondente". catch" il comportamento ha senso per un algoritmo che stai scrivendo, ma non avrebbe senso pensare al throw come corrispondente ad una condizione di errore.

    A cosa serve il "prendi e lancia" in Ruby? offre alcuni suggerimenti sugli usi piacevoli di throw/catch costruire.

Le differenze comportamentali concrete tra loro includono:

  • rescue Foo salverà le istanze di Foo comprese le sottoclassi di Foo. catch(foo) catturerà solo lo stesso oggetto, Foo.Non solo non puoi passare catch un nome di classe per catturarne le istanze, ma non eseguirà nemmeno confronti di uguaglianza.Ad esempio

    catch("foo") do
      throw "foo"
    end
    

    ti darà un UncaughtThrowError: uncaught throw "foo" (o un ArgumentError nelle versioni di Ruby precedenti alla 2.2)

  • È possibile elencare più clausole di salvataggio...

    begin
      do_something_error_prone
    rescue AParticularKindOfError
      # Insert heroism here.
    rescue
      write_to_error_log
      raise
    end
    

    mentre multiplo catchdevono essere nidificati...

    catch :foo do
      catch :bar do
        do_something_that_can_throw_foo_or_bar
      end
    end
    
  • Uno nudo rescue è equivalente a rescue StandardError ed è un costrutto idiomatico.Un "nudo". catch", Piace catch() {throw :foo}, non catturerà mai nulla e non dovrebbe essere utilizzato.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top