![]() |
![]() |
![]() |
![]() |
![]() |
FTP | ![]() |
![]() |
CCD | ![]() |
![]() |
Buscar | ![]() |
![]() |
Trucos | ![]() |
![]() |
Trabajo | ![]() |
![]() |
Foros | ![]() |
|
Registrarse | FAQ | Miembros | Calendario | Guía de estilo | Temas de Hoy |
![]() |
|
Herramientas | Buscar en Tema | Desplegado |
|
#1
|
||||
|
||||
Otra posibilidad es crear un "modo depuración". Si este está activo, entonces muestra toda la información de la excepción capturada (por ejemplo, llamando a TApplication.ShowException), y si está desactivado sólo muestra un mensaje más corto pero guardando el resto de información. Sería algo así como:
Nota importante: Acabo de fijarme en que la clase Exception definida por Free Pascal difiere ligeramente de la descrita por Delphi, y lo mismo pasa con otras clases y funciones relacionadas, así que puede variar un poquito la cosa. Aun así creo que queda clara la idea, ¿no? |
#2
|
||||
|
||||
Gracias amigos por sus comentarios, voy hacer algunas pruebas y luego les cuento
... |
#3
|
||||
|
||||
El problema con esto es meter todo en la misma "bolsa". Las excepciones son problemáticas porque interrumpen el flujo de forma abrupta, y porque se supone que *no deberían usarse/suceder de forma frecuente* y por eso se desaconsejan (la unica excepcion que conozco es python, donde se considera idiomatico).
Ademas, son evidencias de deficiencias en los lenguajes, en especial si 1)No permiten devolver mas de un valor en RETURN 2) Son OO y no hay forma de hacer encadenado de funciones de forma natural, usando un discrimininador de tipo. El asunto es que los lenguajes normalmente asumen que esta bien retornar en la ruta OK mas de un tipo de valor, de cualquier clase, pero no en la ruta ERROR (ie: No se espera que sea idiomatico retornar errores!), lo que hace la vuelta a veces un poco molesta. En fin... ----- En obj-c/Coccoa tienen un concepto util: Hay EXCEPTIONS y hay ERRORS. ERRORS son destinados siempre al usuario (y si hay un EXCEPTION la idea es que se transforma en ERROR de ser el caso...). Asi que el primer paso es: 1- Separar lo que es de usuario y lo que no Y si ocurre una excepcion: 2- Transformar de esta a ERROR si es el caso Esta es la solucion mas sana en un lenguaje con las 2 limitantes anteriores. P.D: El poner o no LOG es *tangencial* al problema. El que algo se haga den DEBUG/RELEASE tambien es tangencial y no resuelve en nada el asunto. El usar dialogos o escribir en la consola/archivo es tambien tangencial. ---- Si hay soporte a retornar multiples valores, o se usa una estructura como TUPLAS o un RECORD, se puede hacer algo muy elegante (en este pseudocodigo delphi, que estoy oxidado):
En tal caso, se retorna no el valor como tal, sino el RECORD. Lo malo es que en Delphi no hay como forzar el uso del camino "correcto" como en F#: http://fsharpforfunandprofit.com/posts/exceptions/ Ir hasta el subtitulo: "Should functions throw exceptions or return error structures?". En los lenguajes como F#, es mas comun retornar estructuras, porque permite hacer encadenamientos y automatizar un monton todo el tema. ---- Releyendo esto me di cuenta que no deje nada muy en claro, asi que: Hay 2 escuelas de como manejar los errores: 1- Uso excepciones, que son GOTOS super-cargados y especiales (Delphi, Java, C#, etc) 2- Uso valores de retorno (C, GO) La escuela 2 permite hacer codigo mas robusto, pero es muy engorroso de manejar. La primera es mas facil, pero se pierde de vista muy rapido el error y su origen (aparte de que causo una interrupcion abrupta). La 2 es mas facil de entender, porque retornar un error es quasi-como retornar un valor normal. Lo malo, es que al estilo de C (usando un 0 para OK y otro valor para quien-sabe, a veces NO-OK otras hay que consultar la tabla de errores, que esta en otro lado) es un fiasco. Ahora bien, en lenguajes funcionales, como F#, tienen una variacion del 2, pero mas util: 2-pero-util: Retorno un valor error tal como un valor OK. Quien recibe el valor decide que hace con el. (F#, ML, Haskell, Elixir) Lo cual es mil-veces-mejor que C, pero mata la gracia de las excepciones: Que el cliente no tiene que decidir siempre que hacer. --- Al punto al que voy: Hacer 2) es mas practico para manejar "errores" donde debo tener control, mas 1) es mas practico en todos los demas casos porque no quiere tener el control todo el tiempo!
__________________
El malabarista. Última edición por mamcx fecha: 03-11-2015 a las 23:51:53. |
#4
|
||||
|
||||
Yo caigo dentro del primer grupo
![]()
La pregunta del millon es, si en CalcSomething se eleva una excepcion, realmente importa el valor de retorno de Foo? ![]() A mi modo de ver las cosas no, ya que si ocurrio una excepcion (algo que no deberia haber pasado y que esta fuera del control de mi programa) Otra alternativa es usar Nullables. En delphi no vienen de serie pero se implementan facilmente. Tambien hay frameworks que los implementan, por ej Spring4d El codigo anterior quedaria similar a esto:
Los TNullable en spring, son implementados usando record, asi que si falla la creacion no tendriamos nunca un AV si mas adelante quiero consultar su valor Obviamente, un verdadero nullable no permite acceder al valor en cuestion si nunca se seteo nada; en este caso spring4d, eleva una excepcion EInvalidOperation. Lo interesante del asunto es que se dispone del metodo Value para recuperar el valor; y el metodo HasValue para ver si tengo un valor valido |
#5
|
||||
|
||||
Coincido con mamcx. Es más, yo sólo uso excepciones para manejar estados de error; por ejemplo, el usuario indicó el nombre de un archivo que no existe. En el resto de casos, devuelvo valores.
Por cierto mamcs, Delphi sí es capaz de devolver varios valores en sus funciones. Recuerda los parámetros VAR y OUT. |
#6
|
||||
|
||||
Ah! se me olvido eso... De hecho, asi es como se hace en obj-c (osea, el manejo de los ERRORS).
__________________
El malabarista. |
#7
|
||||
|
||||
Yo no comparto la visión que tienen de las excepciones. El manejo de la excepción no es quien corta abruptamente la ejecución sino la excepción misma, si es que se ve la diferencia.
Es cierto que hay un abuso de las excepciones al grado de usarlas a modo de condicional y en muchas ocasiones bastaría examinar el valor de retorno de una función. Sin embargo, las excepciones son un objeto mucho más complejo que eso, siendo su gran virtud el efecto burbuja, esto es, que la excepción se va elevando hasta encontrar un punto en donde se puede manejar por quien pueda y sepa hacerlo. Lejos de ser una interrupción brusca del código, en realidad el manejo de excepciones es quien permite manejar un problema de la forma más decorosa posible. Como dije antes, no hay que abusar de las excepciones. El caso que se planteó aquí originalmente (me refiero al de este año no al del inicio del hilo) es un típico caso de abuso de la técnica: se usa la excepción como un condicional para tomar una decisión que, en realidad, tiene que ver más con la lógica de negocios que con el flujo de la aplicación. // Saludos |
![]() |
|
|
![]() |
|