FTP | CCD | Buscar | Trucos | Trabajo | Foros |
|
Registrarse | FAQ | Miembros | Calendario | Guía de estilo | Temas de Hoy |
|
Herramientas | Buscar en Tema | Desplegado |
#21
|
||||
|
||||
Sigo avanzando.
Esta nueva propuesta está dentro de todo funcionando, según las pruebas que he estado llevando a cabo. El diseño si captura las excepciones generadas por TFileStream y genera las propias. Un típico modo de uso, sería algo:
LogOperation() y LogException() son dos métodos que he implementado en un sistema básico para prueba de caja blanca (y algo de "caja gris") que van registrando en un Memo a modo Log cada test que se realiza. En el caso de LogException() se busca capturar las excepciones y mostrar el nombre de la clase y el mensaje. He advertido que el algoritmo tiene dos bugs que ya he procedido a eliminar: 1. Al momento de hacer una lectura del Identificador inicial debiera de invocar, por seguridad es apropiado hacer previamente un Seek(0, soFromBeginning) 2. Al momento de proceder a leer los datos de igual forma se debe posicionarse en el primer elemento y para ello es necesario un Seek(INI_DATA_M, soFromBeginning) siendo INI_DATA_M una constante apropiada para el caso de un archivo diseñado para matrices. Estos mismos problemas detectados fueron eliminados en el método LoadVector. Esta versión optimiza el indexado del posicionamiento al leer la data. Inicialmente procedía con dos ciclos anidados. Gracias a la tan bella matemática se puede prescindir de un ciclo y directamente hacer la correspondencia entre el índice Idx del dato y su posición [i, j] en la matriz tanto en un lectura columna por columna como fila a fila. Estoy abierto a las sugerencias. Saludos, |
#22
|
||||
|
||||
Hola Marcelo.
Este fin de semana tuve algo de tiempo libre para leer con detenimiento todo lo planteado por ti y Mario. ¡Cuántas cosas me gustaría decir! Como procurar la redacción en un sólo idioma y de manera más comprensible. O evitar en lo posible escribir métodos de más de 20 líneas de código. Pero intentaré enfocarme en lo principal de tu planteamiento técnico. El uso canónico de un bloque Try-Finally es: El uso canónico de un bloque Try-Except es: El punto 6 consiste, generalmente, en tomar alguna diligencia de control, liberar algún recurso que previamente se cargó en memoria, registrar o reportar una bitácora de incidencias, o anexar/convertir la excepción en otra excepción. Pero casi siempre este tratamiento termina elevando una excepción (propagando la misma o instanciando otra) al llamador. En algunas ocasiones el punto 4 podría ser opcional. Por otra parte, además de la muy mala práctica de sofocar excepciones (atraparlas solo "para que no estorben"), existe cierta práctica no muy buena (y afortunadamente poco difundida) de atrapar una excepción para convertirla en un código de resultado. Nunca hagas eso a menos que no tengas alternativa. Es más válido que un método de aplicación envuelva a un método de API, atrapando una excepción de esa API para transformarla en una excepción más propia de la aplicación (algo que ya veo haces). Aunque también es válido dejar que la excepción original aparezca en la pantalla del usuario. Lo más malo es que aparezca cualquier mensaje de error, no que el mensaje de error sea algo "geek". Claro, podría ser deseable que las excepciones digan algo entendible, pero no olvidemos que son eso: excepciones que no debieran presentarse. Dada la introducción anterior, me permito poner en seudocódigo cómo podría ser tu método LoadMatrix: Espero que esta participación sea de alguna ayuda. |
#23
|
||||
|
||||
Ah, pero resulta que el punto 1, es para ti punto 5 también. Entonces apliquemos la misma lógica:
¿Mucha anidación?...¿Recuerdas lo de tener un límite de líneas? Divide un método largo en varios cortos y vencerás toda complejidad. Última edición por Al González fecha: 01-06-2015 a las 19:09:56. |
#24
|
||||
|
||||
Alberto,
Cita:
Nelson. |
#25
|
||||
|
||||
Hola Al.
Te agradezco tu aporte. De lo que veo en tu propuesta, aplicas un triple try anidado y separas la excepción de la creación del FileStream de las excepciones que puede arrojar un Read o Write, y dejas a un try-finally intermedio cuando se dan situaciones "segura" y por tanto proceder a finalizar el Free. No se diferencia mucho de la 2da propuesta que logré diseñar. Basicamente la diferencia radica en donde capturar y lanzar las excepciones propias. Ayer estuve haciendo más pruebas y pude apreciar que no necesito relanzar la excepción como me estaba preguntando ¡Lo hace! Mi miedo era que el raise de EInvalidFileArrayFormat y/o el de EInconsistArray fuera capturado por el except y no se mostrara dicha excepción y tuviera que añadirla en la lista y volver a aplicar un rise. La excepción "pasa de largo" y efectivamente se termina recibiendo desde el "lado cliente". Aparentemente todo funciona bien. La aplicación de prueba me ha permitido evaluar las alternativas, y en ciertos casos forzando algunas situaciones como un fallo de lectura/escritura. Se detectan las excepciones y se lanzan las adecuadas. Tendría que probar tu alternativa, pero tengo que continuar con el trabajo. Por el momento tengo en suspenso tu propuesta. Y será el camino hacia una nueva versión si lo amerita, o bien en cuanto pueda disponer de tiempo y se justifique algo más seguro. CheckMatrix no ha sido diseñada para lanzar excepciones. Pertenece a una unidad (que junto a otras forman un gran módulo) que contiene cientos de procedimientos y funciones dedicadas a álgebra lineal y otras cosas más. Su diseño, a la vieja escuela (paradigma estructurado), no ameritaba algo OO por lo que CheckMatrix, por ejemplo, se limita a ofrecer variables de control como ser el código de error generado y adicionalmente la dimensión de la matriz. Es una unidad que ya ha alcanzado un grado de madurez bastante elevado y tiene casi 3000 líneas de código. No se malgasta en clases, excepciones, va a lo directo. Su diseño a sido dual: ofrece procedimientos bajo situaciones ideales, y además ofrece funciones y otros métodos de evaluación y control para aquellos casos en los que se necesita ciertas evaluaciones previas. Las clases/módulos clientes de esta gran biblioteca si quieren pueden seguir el diseño estructurado o bien, aprovechar el poder OO para situaciones más complejas. Los mensajes de algunas excepciones, si te fijas en mi 2da propuesta, aplican a un Format() a un string. Entre los parámetros paso el mensaje de la excepción original. De este modo el texto de la excepción que arrojo lleva consigo no sólo el texto para el contexto esperado (el Converter) sino además información adicional que provee sobre el TFileStream (aunque el texto de éstas más bien es básico según lo que vi en su código). Lo de escribir en un único idioma, si es que te lo preguntas el porque uso comentarios en español y código en inglés, es porque ya me acostumbré asi. La idea es que los comentarios me ayuden a entender lo que tengo y para ello recurro al español. Después de todo es trabajo personal. Lo que evitar algoritmos de más de 20 líneas lo tengo presente. Pero en ocasiones debemos extendernos más. Tengo por ejemplo en otra unidad un procedimiento que tiene 130 líneas de código. Se podría particionarlo, pero ya de por sí las operaciones se hacen de manera óptima y goza de buena velocidad. De particionarlo, algunas partes se estarían llamando cientos de veces. Preferí centrar todo y se ejecute en un único procedimiento antes que estar lidiando con las vueltas de código repartido en varios. Te agradezco tu ayuda porque siempre se aprende algo nuevo. Seguro que esta lección del triple-try la pongo en práctica para otro caso, que tiene cierta semejanza con el TArrayConverter. Es otra especie de conversor pero para otras clases (quizá más manejables que el TFileStream... espero) y finalidades. Seguramente nos mantendremos en contacto. Saludos, |
#26
|
||||
|
||||
¡Mucha suerte, Marcelo!
Por cierto, fu forma de escribir y tus comentarios de código me parecen bien. Lo del idioma fue un llamado a la comunidad en general para ser un poco más formales con las explicaciones técnicas, evitando el spanglish en algo tan valioso como la divulgación técnica. Al González. P.D. Nelson, gracias por ese mensaje. |
#27
|
||||
|
||||
Cita:
Ojalá la suerte fuera contagiosa y se transmitiera por cables de red. Necesito ¡ y mucha! Me alagas demasiado por mi escritura de código. Aún tengo mucho por pulir, sobre todo habiendo perdido mucha práctica por haber tenido que dejar por tanto tiempo la programación. Y si de pulir se trata ahora que veo de nuevo mi código creo que puedo reducir 2 cálculos en uno sólo. Cuando calculo los índices i y j aplico DIV y MOD según sea el caso. Esto se puede hacer de manera efectiva y rápida con DivMod. En lo de ser lo más técnico posible te apoyo. Hay que hacer lo posible por emplear las palabras formales, pero entiendo que en ocasiones por las prisas, cansancio, el no poder encontrar las expresiones en el momento (que pasa... y seguido) y hasta algo de desconocimiento, nos juegan en contra y nos mandamos cada una. Saludos, |
|
|
Temas Similares | ||||
Tema | Autor | Foro | Respuestas | Último mensaje |
Capturando excepciones en un archivo de texto | noob | Varios | 5 | 20-02-2009 09:47:46 |
Duda sobre posibles excepciones en una desconexión de un socket | noob | Varios | 0 | 13-02-2009 19:33:14 |
TMaskedit, con posibles excepciones en el formato | grotero76 | OOP | 6 | 31-01-2008 13:49:23 |
Cómo utilizar consultas con DISTINCT de forma correcta | dec | MySQL | 9 | 19-09-2006 17:50:47 |
lista de todas las posibles excepciones | maruenda | Varios | 1 | 06-12-2004 22:31:02 |
|