Tengo un código que necesita rescatar varios tipos de excepciones en ruby:
begin
a = rand
if a > 0.5
raise FooException
else
raise BarException
end
rescue FooException, BarException
puts "rescued!"
end
Lo que me gustaría hacer es almacenar de alguna manera la lista de tipos de excepción que quiero rescatar en algún lugar y pasar esos tipos a la cláusula de rescate:
EXCEPTIONS = [FooException, BarException]
y entonces:
rescue EXCEPTIONS
¿Es esto siquiera posible, y es posible sin algunas llamadas realmente hack-y a eval
? No tengo esperanzas dado que estoy viendo TypeError: class or module required for rescue clause
cuando intento lo anterior.
Respuestas:
Puede utilizar una matriz con el operador splat
*
.Si va a usar una constante para la matriz como arriba (con
EXCEPTIONS
), tenga en cuenta que no puede definirla dentro de una definición, y también si la define en alguna otra clase, debe referirse a ella con su espacio de nombres. En realidad, no tiene por qué ser una constante.Operador de Splat
El operador de splat
*
"desempaqueta" una matriz en su posición para quesignifica lo mismo que
También puede usarlo dentro de un literal de matriz como
que es lo mismo que
o en una posición de argumento
lo que significa
[]
se expande al vacío:Una diferencia entre ruby 1.8 y ruby 1.9 es con
nil
.Tenga cuidado con los objetos sobre los que
to_a
está definido, yato_a
que se aplicará en tales casos:Con otros tipos de objetos, vuelve a sí mismo.
fuente
EXCEPTIONS
en este caso? Me gustaría aprender un poco más.rescue InvalidRequestError, CardError => e
(consulte mikeferrier.com/2012/05/19/… )rescue *EXCEPTIONS => e
dondeEXCEPTIONS
es una matriz de nombres de clases de excepción.Si bien la respuesta dada por @sawa es técnicamente correcta, creo que hace un mal uso del mecanismo de manejo de excepciones de Ruby.
Como el comentario de Peter Ehrlich sugiere (señalando una publicación de blog antigua de Mike Ferrier ), Ruby ya está equipado con un mecanismo de manejo de excepciones DRY:
Al usar esta técnica, podemos acceder al objeto de excepción, que generalmente contiene información valiosa.
fuente
Me encontré con este problema y encontré una solución alternativa. En el caso de que su
FooException
yBarException
todas sean clases de excepción personalizadas y, en particular, si están todas relacionadas temáticamente, puede estructurar su jerarquía de herencia de modo que todas hereden de la misma clase principal y luego rescaten solo la clase principal.Por ejemplo, yo tenía tres excepciones:
FileNamesMissingError
,InputFileMissingError
yOutputDirectoryError
que quería rescate con una sola declaración. Hice otra clase de excepción llamadaFileLoadError
y luego configuré las tres excepciones anteriores para heredar de ella. Entonces solo rescatéFileLoadError
.Me gusta esto:
fuente