¿Cuál es la diferencia entre generar excepciones y lanzar excepciones en Ruby?

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

  •  09-06-2019
  •  | 
  •  

Pregunta

Ruby tiene dos mecanismos de excepción diferentes:Lanzar/Atrapar y Levantar/Rescatar.

¿Por qué tenemos dos?

¿Cuándo deberías usar uno y no el otro?

¿Fue útil?

Solución

Creo http://hasno.info/ruby-gotchas-and-caveats tiene una explicación decente de la diferencia:

atrapar/lanzar no es lo mismo que subir/rescatar.catch/throw le permite salir rápidamente de los bloques hasta un punto donde se define una captura para un símbolo específico, elevar el rescate es el verdadero manejo de excepciones que involucra el objeto Exception.

Otros consejos

  • raise, fail, rescue, y ensure manejar errores, también conocido como excepciones
  • throw y catch son flujo de control

A diferencia de otros idiomas, el lanzamiento y la captura de Ruby no se usan para excepciones.En cambio, proporcionan una forma de terminar la ejecución temprano cuando no se necesita más trabajo.(Grimm, 2011)

Terminar un único nivel de flujo de control, como un while bucle, se puede hacer con un simple return.La terminación de muchos niveles de flujo de control, como un bucle anidado, se puede hacer con throw.

Si bien el mecanismo de excepción de aumento y rescate es excelente para abandonar la ejecución cuando las cosas van mal, a veces es bueno poder saltar de alguna construcción profundamente anidada durante el procesamiento normal.Aquí es donde resulta útil atrapar y lanzar.(Thomas y Hunt, 2001)

Referencias

  1. Grimm, Avdi."Lanza, atrapa, cría, rescate ... ¡Estoy tan confundido!" Blog de RubyLearning.Np, 11 de julio de 2011.Web.1 de enero.2012. http://rubylearning.com/blog/2011/07/12/throw-catch-raise-rescue--im-so-confused/.
  2. Thomas, Dave y Andrew Hunt."Programación de Ruby". :La guía pragmática del programador.Np, 2001.Web.29 de septiembre.2015. http://ruby-doc.com/docs/ProgrammingRuby/html/tut_exceptions.html.

https://coderwall.com/p/lhkkug/don-t-confuse-ruby-s-throw-statement-with-raise Ofrece una excelente explicación que dudo que pueda mejorar.Para resumir, tomando algunos ejemplos de código de la publicación del blog a medida que avanzo:

  1. raise/rescue son los análogos más cercanos a la throw/catch construcción con la que está familiarizado en otros lenguajes (o en Python) raise/except).Si ha encontrado una condición de error y desea throw sobre él en otro idioma, deberías raise en Rubí.

  2. rubí throw/catch te permite interrumpir la ejecución y subir por la pila en busca de un catch (como raise/rescue lo hace), pero en realidad no está destinado a condiciones de error.Debe usarse raramente y está ahí sólo para cuando "sube por la pila hasta encontrar el correspondiente". catch"El comportamiento tiene sentido para un algoritmo que estás escribiendo, pero no tendría sentido pensar en el throw como correspondiente a una condición de error.

    ¿Para qué se utiliza atrapar y lanzar en Ruby? ofrece algunas sugerencias sobre buenos usos del throw/catch construir.

Las diferencias concretas de comportamiento entre ellos incluyen:

  • rescue Foo rescatará casos de Foo incluyendo subclases de Foo. catch(foo) sólo atrapará el mismo objeto, Foo.No sólo no puedes pasar catch un nombre de clase para detectar instancias del mismo, pero ni siquiera hará comparaciones de igualdad.Por ejemplo

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

    te daré un UncaughtThrowError: uncaught throw "foo" (o un ArgumentError en versiones de Ruby anteriores a la 2.2)

  • Se pueden enumerar múltiples cláusulas de rescate...

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

    mientras que múltiples catches necesita estar anidado...

    catch :foo do
      catch :bar do
        do_something_that_can_throw_foo_or_bar
      end
    end
    
  • Un desnudo rescue es equivalente a rescue StandardError y es una construcción idiomática.Un desnudo catch", como catch() {throw :foo}, nunca atrapará nada y no debe usarse.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top