¿Cuál es la diferencia - técnico, filosófico, conceptual, o de otra manera - entre¿Cuál es la diferencia entre `raise" foo "` y `raise Exception.new (" foo ")`?
raise "foo"
y
raise Exception.new("foo")
?
¿Cuál es la diferencia - técnico, filosófico, conceptual, o de otra manera - entre¿Cuál es la diferencia entre `raise" foo "` y `raise Exception.new (" foo ")`?
raise "foo"
y
raise Exception.new("foo")
?
Técnicamente, la primera plantea una RuntimeError con el conjunto de mensajes a "foo"
, y el segundo genera una excepción con el conjunto de mensajes a "foo"
.
Prácticamente, hay una diferencia significativa entre cuándo quiere usar el primero y cuándo quiere usar el último.
En pocas palabras, usted probablemente querrá un RuntimeError
no un Exception
. Un bloque de rescate sin argumento atrapará RuntimeErrors
, pero NO atrapará Exception
s. Así que si usted levanta una Exception
en su código, este código no cogerlo:
begin
rescue
end
Con el fin de coger el Exception
que tendrá que hacer esto:
begin
rescue Exception
end
Esto significa que en un sentido , un Exception
es un error "peor" que RuntimeError
, porque tiene que hacer más trabajo para recuperarse de él.
Así que lo que desea depende de cómo su proyecto hace su manejo de errores. Por ejemplo, en nuestros daemons, el bucle principal tiene un rescate en blanco que capturará RuntimeErrors
, informe de ellos y luego continúe. Pero en una o dos circunstancias, queremos que el daemon realmente muera por error, y en ese caso levantamos un Exception
, que pasa directamente a nuestro "código normal de manejo de errores" y sale.
Y de nuevo, si usted está escribiendo código de la biblioteca, es probable que quieren un RuntimeError
, no un Exception
, ya que los usuarios de la biblioteca se sorprenderá si eleva errores que un espacio en blanco rescue
bloque no puede atrapar, y se necesitará ellos un momento para darse cuenta por qué.
Por último, debo decir que el RuntimeError
es una subclase de la clase StandardError
, y el estado real es que aunque se puede raise
cualquier tipo de objeto, el espacio en blanco rescue
voluntad por defecto sólo coger cualquier cosa que se hereda de StandardError
.Todo lo demás tiene que ser específico.
From the offical documentation:
raise
raise(string)
raise(exception [, string [, array ] ])
Sin argumentos, plantea la excepción en $!
o plantea una RuntimeError
si $!
es nula. Con un solo argumento String
, levanta un RuntimeError
con la cadena como un mensaje. De lo contrario, el primer parámetro debe ser el nombre de una clase Exception
(o un objeto que devuelve Exception
cuando se envía una excepción). El segundo parámetro opcional establece el mensaje asociado a la excepción, y el tercer parámetro es una matriz de información de devolución de llamada. Las excepciones son capturadas por la cláusula de rescate de los bloques begin...end
.
raise "Failed to create socket"
raise ArgumentError, "No parameters", caller
muy informativo, gracias. algunas cosas: [1] El último párrafo fue el más esclarecedor, y déjame descubrir en IRB algo que no has mencionado: 'RuntimeError
[1, 2] Sí. [3] no estoy seguro ... [4] Cuando estoy codificando como el más profesional, tiendo a crear tipos de error personalizados que heredan de 'StandardError'. No tiene que ser más complicado que algunas líneas como 'clase MissingArgumentsError
Muy informativo, pero ¿bajo qué tipo de situaciones querrá lanzar un error de Excepción en lugar de error de tiempo de ejecución si se prefiere el error de tiempo de ejecución para escribir libraray? –