Hola,
Hace tiempo que no posteo, pero este tema parece interesante y creo que el
thread daba para más. Sobre todo porque creo que la discusión no es
específica de Ruby.

De todas formas no todas las excepciones están para ser manejadas.
> Muchas tienen que poder pasar para informar que hay algo que no está
> andando bien (si la conexión a la DB falla, está bien que la excepción
> salga del backtrace para informarnos que tenemos que chequear el motor
> de base de datos).


Si mal no te entiendo, vos decís que dependiendo del tipo de excepción, tu
módulo puede optar por comportarse en forma transparente, y dejar pasar la
exception.
Yo lo veo un poco al revés, no depende tanto de qué tipo de excepción se
produzca, sino del contexto en el que se produce, dado que la exepción va a
interrumpir el flujo secuencial de tu módulo, es probable, que sin importar
el tipo de excepción, vos tengás que tomar alguna medida para garantizar
cosas, cerrar conexiónes, liberar algún recurso, etc.
Está bueno que el Ruby tenga el "ensure", así como otros lenguajes tienen el
"finally".
En ese sentido, un caso medio jorobado es el del C++, y perdonen por el
O.T., pero sirve para mostrar diferencias. No tiene finally, ni nada por el
estilo, por lo que algunos programadores usan destructores para asegurarse
de realizar las acciones finales. Ejemplo:

void doSomething(void)
{
        Lock();
        //Do other things
        Unlock();
}

Claramente, si dentro de "do other things" sucede algo excepcional, el
Unlock nunca llega a ejecutarse. Por lo que los de C++ se valen de los
"destructores" de las clases para tal fin, ejemplo:

class LockManager
{
        // Esto que sigue es el constructor de la clase: LockManager
        LockManager(void)
        {
                Lock(); //realiza el lock en el contructor
        }
        // Esto que sigue el destructor de la clase LockManager
        ~LockManager()
        {
                Unlock(); //realiza el unlock en el destructor
        }
}

Entonces doSomething() queda:

void doSomething(void)
{
        // acá se está declarando e instanciando la variable lockMgr,
        // por lo que se está invocando el constructor, y este a su vez
        // está haciendo el "Lock()"

        LockManager lockMgr;

        //Do other things

        //al finalizar doSomething(), el destructor es invocado en forma
        //automática por C++, por lo el destructor se encarga de invocar el
unlock.
}


Sufridito ¿no?, Cabe aclarar, que en C++, pase la excepción que pase (salvo
que Edenor corte justo antes del destructor), los destructores siempre van a
ser invocados, es por eso que usan esta técnica.

Queda todavía la pregunta original de Pedro:

Pregunta adicional, los errores funcionales (el usuario mete mal los dedos)
> deben ser tratados como excepciones?
> Todo debería ser una excepción? o se simplifica si los errores funcionales
> (las password no coinciden por ejemplo) son manejados por el código sin
> excepciones y los técnicos (duplicate key entry) son manejados por
> excepciones.
>

Acá creo que un factor que influye mucho es si se va a tener la oportunidad
o no de atrapar la exepción antes de que reviente en el OS o en el caso de
las WebApp en el WebServer, en definitiva si se va a poder atrapar la
excepción antes de que llegue al usuario.
Por ejemplo, en el caso de la password, probablemente sea una mala idea usar
exepciones, porque a lo mejor, si estamos cerca de la capa que interactúa
con el usuario, probablemente la exepción termine siendo mostrada en el
navegador o aplicación de escritorio, pero si por ejemplo, estamos haciendo
una librería para manejo de fechas, y ésta provee una función que recibe dia
mes y año y retorna un tipo-fecha, y el usuario (de la librería, no del
sistema final) pasa el 99/99/2008, entonces acá sí, yo tiraría una
excepción.
En definitiva, mi lógica sería: Al usuario del sistema se le validan y
restringen lo más posible todos sus inputs, y en todo caso se le informa
amablemente sobre su error, mientras que al usuario de librerías y
subsistemas internos, se los trata un poco peor, se les tiran excepciones,
aún cuando no sean por condiciones excepcionales (disk full, network errors,
etc.)

saludos,
_______________________________________________
Ruby mailing list
[email protected]
http://lista.rubyargentina.com.ar/listinfo.cgi/ruby-rubyargentina.com.ar

Responder a