Les comento que tengo un módulo que contiene varios métodos (casi un centenar). Por diseño, se necesita estar controlando y operando constantemente y hay varias variables en juego.
Por todo esto, es que algunos de esos métodos son funciones diseñadas para hacer las comprobaciones y devolver un boolean.
Si todo anda bien, el valor como es de esperar es true. Por el contrario si es false algo ha fallado.
Para saber ese algo se dispone de un parámetro por referencia que almacena una especie de código de error. Para facilitar un poco las cosas estos códigos los tengo declarados como constantes:
const TODO_BIEN = 0; ERROR_TIPO1 = 1; // ... ERROR_TIPO6 = 6;
Bueno. La cosa es que estas funciones reciben entre 1 a 3 parámetros a los que somete a prueba. Ahora es cuando se pone un poco pesada la cosa. Algunas de estas funciones invocan a otras y que son más específicas para evaluar a cada tipo de parámetro. Estas "subfunciones" además de ese parámetro por referencia para el código de error regresan información adicional de interés (que no son más de 2).
Entonces en una función "padre" puede que requiera llamar a 1 o hasta 3 subfunciones. Cada una hace lo suyo y regresa el código de error para el caso detectado, más la/s info/s adicional/es:
SePuede1 := VerificarParametroTipo1(Param1, info11, info12, Cod1); SePuede2 := VerificarParametroTipo2(Param2, info21, info22, Cod2); SePuede3 := VerificarParametroTipo3(Param3, info31, info32, Cod3);
Siendo Cod1 a Cod3 las variables destinadas para detectar el código de error para cada parámetro e infoXY la variable de información Y-ésima para el parámetro X.
Estas subfunciones evalúan de forma "interna" cada parámetro. Más no lo "externo", que es lo que terminará realizando la función padre. Para eso son las InfoXY.
Entonces, al evaluar las variables SePuede se sabe que con los parámetros dados puedo trabajar... Pero hace falta hacer unas pocas pruebas más para ver si es "legal" operar con ellos.
Tengo al final esto:
result := SePuede1 AND SePuede2 AND SePuede3; if result then begin // Aqui se evalúan las InfoXY y se generan Cod. de error específicos en caso de no pasar algunas pruebas. // Si todo OK: se trabaja. end else CodErr = Cod1 + Cod2 + Cod3;
Como pueden ver, si inicialmente ya se detecta que no se puede, regreso en la variable de referencia del código de error general (como para ponerle un nombre y diferenciarlo de los específicos para cada parámetro) una simple suma de los errores.
A mi en su lugar me gustaría poder devolver en el código de error un valor "acumulativo" de errores que tenga todos los errores detectados. Es decir, O bien todos los errores específicos/internos acumulados, o bien los errores generales externos acumudos.
Entre los errores internos (4) y externos (los 2 últimos) contabilicé 6. De allí que he diseñado 6 constantes.
Es decir que:
CodError = "suma" errores internos. cuando la evaluación SePuede da negativo. O bien...
CodError = "suma" errores externos. cuando la evaluación SePuede da positivo.
Naturalmente las constantes no debieran de tener valores consecutivos. Porque de esa forma por ejemplo al sumar TIPO1 y TIPO2 daría el TIPO3 y no necesariamente eso quiere decir que se ha detectado esto.
La intención de hacerlo "acumulativo" es que se pueda distinguir los errores y desde el módulo cliente regresar un mensaje alusivo a modo de advertencia señalando puntualmente la seguidilla de errores. No sólo en cuanto interno vs externo sino también para que cuando sea interno se pueda diferenciar el error de cada parámetro.
Es decir que CodError exprese numéricamente algo como "Che, mirá, las evaluaciones indican que se han detectado:
1. En el parámetro 1 te falló X.
2. Para el parámetro 2 tenés Y.
3. Y por último en 3, el Z no vá.
Así no se puede trabajar viejo. Empezá todo de nuevo"
Cuando todo sea por causa interna. Y cuando es externa, que diga por ejemplo:
"Che... todo bien, pero para operar con param 1 y param 2 deben coincidir el índice. Pasame otro y opero perfecto"
¿Me explico?
¿Que alternativa consideran viable?
He pensado en un diseño con número de error basado en potencias:
ERROR_TIPO1 = 1;
ERROR_TIPO2 = 2;
ERROR_TIPO3 = 4;
ERROR_TIPO4 = 8;
ERROR_TIPO5 = 16;
ERROR_TIPO6 = 32;
Esto es para que la "suma" no se "pisen" los valores. Pero claro, ¿Y cómo podría a su vez hacer que detecte si es para param1, param2, param3?
Pensé que podría ser útil entonces hacer que sea por rangos: Para Param1 que el valor sea 100 + Nro, para Param2 le corresponda 200 + Nro y para Param3 el 400 + Nro. Pero presiento que así tampoco puede funcionar.
Si logro hacer esto desde el módulo "cliente" bastarían cosas como:
if EvaluarPadreCon3ParamsParaLaOperacion1(Param1, Param2, Param3, Err) then Operar1(Param1, Param2, Param3) else DarAviso(Err); ... if EvaluarPadreCon2ParamsParaLaOPeracion2(Param1, Param2, Err) then Operar2(Param1, Param2) else DarAviso(Err);
Y así DarAviso() centraliza todo y el se encarga de armar y dar las malas noticias.
Lo máximo que estuve pensando, y a lo que quisiera evitar, es tener que definir constantes específicas para cada caso.
Quizá les parezca medio a los palos el diseño, pero bueno... es lo más aceptable y lógico que mi mente ha logrado hacer para poder lograr manerar la cantidad de variables que juegan. Si mis Operar() tuvieran que manerar parte de la decisiones y evaluaciones que se hacen en los Evaluar() padres e hijos la complejidad se disparaba mucho.
A pesar de eso, me gusta la buena biblioteca que he generado.
El manejo de error es dentro de todo un detalle algo menor. La biblioteca está funcionando. Pero quisiera escuchar otras alternativas y opciones y ver que posibilidades hay de llegar a algo como lo que quiere inducirme este Delphius inconsciente :lol:
Saludos,