No comentes: ¡Asegura!
Hoy he descubierto mucho de ese gran desconocido que es assert.
Resulta que tenía a mi alcance una herramienta de depuración bastante fuerte y aún no he hecho uso de ella.
Con el fin de solucionar este problema, escribo este artículo, aunque no escribiré nada que no se encuentre en la Documentación de Java sobre Assert o la documentación Python.
Lo más básico
Lo primero es saber cómo vamos a usarlo. Suele haber dos maneras de utilizarlo: con un parámetro o con dos. El segundo parámetro indicará el texto a acompañar la excepción cuando el primero de los parámetros no se cumpla.
En python:
|
|
y en java:
|
|
Es importante destacar que, si la expresion1
no se cumple, la expression2
no se evaluará. A menudo, esta segunda expresión debe generar una cadena.
¡¡No utilices Assert!!
De la misma manera que no utilizarías un martillo neumático para apretar un tornillo, no podemos utilizar assert en todos los casos.
Donde no debemos usarlo es en los siguientes supuestos:
- Métodos públicos: Cuestión estética, ya que queda horrible recibir un “Assertion Error”. Será mejor recibir un “Se ha producido un error”, por lo que en métodos públicos es mejor utilizar una comparación y una excepción. Además, existe la posibilidad de desactivar las aseveraciones, por lo que corremos el riesgo de dejar de comprobar la entrada de un método público.
- Para hacer trabajo útil en un método, ya que las aseveraciones se pueden desactivar y, por tanto, dejaría de realizarse ese trabajo.
¡¡Utiliza Assert!!
A menudo nos sentimos tentados de escribir comentarios del tipo “Todo bien”, “no debería llegar aquí”, etc. Este tipo de comentario es un problema ya que, por un lado, pueden dejar de ser ciertos y por otro, nadie los está comprobando.
Además, se requieren demasiadas letras para dar la misma semántica (comparo el
comentario con su equivalente con assert
).
En Python:
|
|
En Java:
|
|
Cuando tenemos un switch, en ocasiones dejamos el caso por defecto sin gestionar, ya que nunca se llegará allí. ¿O tal vez sí? ¿Qué ocurrirá el día que añadamos una nueva opción? Podemos asegurarnos de contemplarlas:
|
|
Precondiciones y postcondiciones
Uno de mis usos favoritos es el de comprobar entradas y salidas. Por ejemplo: tenemos la función que devuelve el factorial de un número, y que debe exigir que la entrada sea mayor que 1 (y que no sea negativa, claro). Asumiendo que no sea un método público:
|
|
También podemos asegurarnos de no haber dejado algo con un valor inválido:
|
|
En Java, es muy común tener en una clase funciones synchronized y no synchronized que se llaman entre ellas. Eso es un foco de deathlocks dificilísimos de detectar, ya que estamos esperando a que nosotros mismos soltemos el bloqueo. Es como buscar las gafas con las gafas puestas.
Este caso es realmente sencillo de detectar con un assert:
|
|
Desactivación
Por último, indicar que estas aseveraciones (por favor, no uséis “aserciones”) se pueden desactivar en un entorno de producción, por lo que no importa si hacéis cosas “caras”. Cuando las desactivéis será como si nunca las hubierais escrito.
En python están ACTIVADAS por defecto. Se debe usar la opción -O
para desactivarlas:
|
|
En Java estarán DESACTIVADAS por defecto, aunque se pueden activar por módulo,
por método, etc. Aunque lo más útil es utilizar -ea
para activarlas todas.
¡¡Empleadlo con cariño!!