rails - ruby guide style
Fallo y aumento en Ruby: ¿Deberíamos realmente creer en la guía de estilo? (2)
Ruby ofrece dos posibilidades para provocar una excepción programáticamente: raise
y fail
, ambos métodos son Kernel
. Según los documentos, son absolutamente equivalentes.
Fuera de un hábito, solo utilicé el raise
hasta ahora. Ahora encontré varias recomendaciones (por ejemplo here ), usar el raise
para las excepciones que se deben detectar y fail
en los errores graves que no deben ser manejados.
¿Pero realmente tiene sentido? Cuando escribe una clase o un módulo, y causa un problema en lo profundo, que señala por fail
, sus colegas de programación que están revisando el código, pueden comprender sus intenciones, pero la persona que está usando mi código probablemente no verá en mi código y no tiene forma de saber si la excepción fue causada por un raise
o por un fail
. Por lo tanto, mi uso cuidadoso de raise
o fail
no puede tener ninguna influencia en su decisión, ya sea que ella deba o no manejarla.
¿Podría alguien ver fallas en mis argumentos? ¿O hay otros criterios, que me gustaría usar fail
lugar de raise
?
use ''raise'' para capturar excepciones y ''fail'' para errores graves que no deben ser manejados
Esto no es lo que dice la guía de estilo oficial o el enlace que proporcionó al respecto.
Lo que se quiere decir aquí es el raise
uso solo en bloques de rescue
. El uso de Aka fail
cuando se quiere decir que algo está fallando y se usa raise
cuando se vuelve a lanzar una excepción.
En cuanto a la parte "¿importa?" , No es una de las reglas más estrictas que se han seguido estrictamente, pero se podría argumentar lo mismo para cualquier convención. Debes seguir en ese orden:
- Tu guía de estilo de proyecto.
- Guía de estilo de su empresa.
- La guía de estilo de la comunidad.
Idealmente, los tres deberían ser los mismos.
Actualización : A partir de este RP (diciembre de 2015), la convención es usar siempre el raise
.
Una vez tuve una conversación con Jim Weirich acerca de esto, desde entonces siempre he usado fail
cuando mi método está fallando explícitamente por algún motivo y ha aumentado las excepciones para volver a lanzarlas.
Aquí hay una publicación con un mensaje de Jim (casi en forma literal a lo que me dijo en persona): http://www.virtuouscode.com/2014/05/21/jim-weirich-on-exceptions/
Aquí está el texto relevante de la publicación, una cita atribuida a Jim:
Aquí está mi filosofía básica (y otros pensamientos aleatorios) sobre las excepciones.
Cuando llama a un método, tiene ciertas expectativas sobre lo que logrará el método. Formalmente, estas expectativas se llaman post-condiciones. Un método debe lanzar una excepción siempre que no cumpla con sus postcondiciones.
Para utilizar esta estrategia de manera efectiva, esto implica que debe tener una pequeña comprensión del Diseño por Contrato y el significado de las condiciones previas y posteriores. Creo que es una buena cosa saber de todos modos.
Aquí hay algunos ejemplos concretos. El método de
save
modelo Rails:
model.save! -- post-condition: The model object is saved.
Si el modelo no se guarda por algún motivo, se debe generar una excepción porque no se cumple la condición posterior.
model.save -- post-condition: (the model is saved && result == true) || (the model is not saved && result == false)
Si
save
no guarda realmente, entonces el resultado devuelto seráfalse
, pero la condición posterior aún se cumple, por lo tanto no es una excepción.Me parece interesante que la
save!
El método tiene una post-condición mucho más simple.Sobre el tema del rescate de excepciones, creo que una aplicación debe tener puntos estratégicos donde se rescatan las excepciones. Hay poca necesidad de rescate / rebrotes en su mayor parte. El único momento en que querría rescatar y volver a realizar es cuando tiene un trabajo a mitad de camino y desea deshacer algo para evitar un estado parcialmente completo. Los puntos estratégicos de rescate deben elegirse con cuidado para que el programa pueda continuar con otros trabajos, incluso si la operación actual falla. Los programas de procesamiento de transacciones deben pasar a la siguiente transacción. Una aplicación de Rails debería recuperarse y estar lista para manejar la próxima solicitud http.
La mayoría de los manejadores de excepciones deben ser genéricos. Dado que las excepciones indican una falla de algún tipo, entonces el manejador solo necesita tomar una decisión sobre qué hacer en caso de falla. Las operaciones de recuperación detalladas para excepciones muy específicas generalmente se desaconsejan a menos que el manejador esté muy cerca (llame al gráfico) al punto de la excepción.
Las excepciones no se deben usar para el control de flujo, use
throw/catch
para eso. Esto reserva excepciones para condiciones de falla verdaderas.(Aparte, porque uso excepciones para indicar fallas, casi siempre uso la palabra clave
fail
lugar de la palabra claveraise
en Ruby.Fail
yraise
son sinónimos, por lo que no hay diferencia, excepto quefail
más claramente que el método ha fallado. la única vez que uso elraise
es cuando detecto una excepción y la vuelvo a elevar, porque aquí no estoy fallando, sino que estoy generando una excepción explícita y deliberadamente. Este es un tema estilístico que sigo, pero dudo que muchas otras personas lo hagan. .Ahí lo tienen, un volcado de memoria bastante confuso en mis pensamientos sobre excepciones.
Sé que hay muchas guías de estilo que no están de acuerdo (la guía de estilo utilizada por RoboCop , por ejemplo). No me importa Jim me convenció.