jueves, junio 12, 2014

La importancia de un buen nombre para los procedimientos y las funciones


Por: Fernando D. Bozzo

Cuando se desarrollan nuevas funcionalidades, si queremos hacer las cosas bien lo haremos de forma encapsulada, usando control de errores, evitando en lo posible dependencias externas y parametrizando lo más posible, para intentar que haya claramente una entrada y una salida.

En este proceso, lo primero que elegimos y creamos es el nombre del procedimiento o función que contendrá el código con la implementación de la funcionalidad.

Lamentablemente a este paso muchas veces no se le da la importancia necesaria, siendo que de la claridad con la se defina esto, dependerá buena parte de la autodocumentación de la aplicación, y de que dentro de un tiempo nosotros u otros desarrolladores entendamos qué hacía o por qué.

En este artículo se verán algunos nombres que por su longitud a quienes estén acostumbrados a la vieja usanza les podrá resultar exagerado o demasiado verborrágico, pero es que los tiempos han cambiado y con los años se han aprendido nuevas lecciones por el camino.



Lo que importa es el nombre


Nombres como "procedimiento_1" o "proc_A" no indican absolutamente nada sobre su funcionamiento o intención, incluso algo más elaborado como "EvaluarHabilitaciones" puede ser ambiguo si no se usa correctamente.

Las buenas prácticas indican hacer métodos que hagan en lo posible una sola cosa y usar un nombre que sea lo más representativo posible de esa funcionalidad.

¿Pero qué regla se puede usar para evitar equivocaciones o nombres poco útiles y conseguir el mejor nombre?

Hay una regla muy fácil: Convertir el nombre del método que hemos elegido en una pregunta, y si las respuestas (los valores de salida) no son ambiguas y unívocamente responden a la pregunta, entonces ese es un buen nombre.



Veamos algunos ejemplos


1) Tenemos un método que debe devolver el estado de habilitación (enabled) de un grupo de controles de acuerdo a ciertas condiciones.


Rápidamente podríamos pensar algo como "EvaluarEstadosDeDeshabilitacion", ya que aparentemente este nombre está hablando sobre lo que hace internamente, lo cuál es cierto, y que se usará en una condición de este tipo:

IF EvaluarEstadosDeDeshabilitacion()
   * Asignar ENABLED=.T. a unos controles
ELSE
   * Asignar ENABLED=.F. a unos controles
ENDIF


Pero sometámoslo a la prueba de la pregunta a ver si es un nombre adecuado, y comparemos las respuestas:

Pregunta:
"¿Se van a Evaluar Estados de Deshabilitación?"

Respuestas posibles del método:
Verdadero
Falso

En este caso las respuestas confunden, porque ¿se van a evaluar o no esos estados?

Para complicarlo más, el nombre incluye una negación, "Deshabilitación", por lo que al responder afirmativamene, realmente estamos diciendo lo que no se debe hacer en vez de lo que sí se debe hacer. Como se ve, algo que debería ser sumamente sencillo comienza a complicarse sin sentido.

Pero dado que las respuestas del método realmente deben ser esas (Verdadero/Falso), debemos asumir entonces que las pregunta está mal hecha, y por consiguiente el nombre del método está mal.

Volvamos a pensarlo: La respuestas indican si se deben habilitar o no controles, ¿no sería mejor un nombre como "ControlesEvaluadosHabilitados" o "ControlesEvaluadosEnabled"?

Sometámoslo a la misma prueba:

Pregunta:
"¿Están los Controles Evaluados Habilitados?"

Respuestas posibles del método:
Verdadero
Falso

En este caso ambas respuestas definen precisamente los valores posibles a la pregunta, con lo que ese nombre es el adecuado. Luego, el ejemplo anterior quedaría así:

IF ControlesEvaluadosHabilitados()
   * Asignar ENABLED=.T. a unos controles
ELSE
   * Asignar ENABLED=.F. a unos controles
ENDIF



2) Tenemos un método que no debe devolver ninguna respuesta, sino solamente evaluar y actualizar los estados de habilitación antes comentados.


En este caso se trata de un método que invoca a otros métodos para realizar su tarea, por lo que aquí sí que "EvaluarEstadosDeHabilitacion" o "EavaluarYActualizarEstadosDeHabilitacion" sería un nombre correcto, ya que se usaría así:

PROCEDURE EvaluarYActualizarEstadosDeHabilitacion
   * Hacer las evaluaciones necesarias y configurar los ENABLED
ENDPROC

Pero sometámoslo a la prueba de la pregunta a ver si es un nombre adecuado, y comparemos las respuestas:

Pregunta:
"¿Se van a Evaluar Y Actualizar Estados de Habilitacion?"

Respuestas posibles del método:
Como no devuelve respuesta, se debe comparar con la veracidad de la intención, que en este caso es SI, se van a Evaluar Y Actualizar Estados de Habilitación.




3) Un nombre de método tomado de un sistema: "Formularios()". No devuelve nada, solo realiza una acción: Cierra los formularios abiertos.


¿Qué nos dice este nombre? Pues que tiene que ver con formularios, pero nada más.
¿Indica su función? No
¿Podemos deducir lo que hace? No

Entonces es un nombre inútil. Para la acción que realiza, un mejor nombre podía ser CerrarFormularios(), y no requería mucha imaginación ni trabajo extra.




4) Algunos ejemplos de nombres usados en casos de prueba automatizados con FoxUnit:


Deberia_Ejecutar_FOXBIN2PRG_ParaLaLibreria_FB2P_TEST_VCX_YValidarLosCamposDelRegistro

Deberia_Ejecutar_FOXBIN2PRG_ParaElForm__F_OptionGroup__YValidarLaVisualizacionDePantalla

Deberia_DevolverLaFechaHora_2013_12_01_08_02_00_ParaElValor_1132544064

Deberia_ObtenerLaUbicacionDelBloque_IF_ENDIF_CuandoCodigoCon_IF_ENDIF_predominante_esEvaluado


Creo que no necesitan ver el código ni los comentarios de estos métodos para saber lo que hacen, y eso es suficiente para demostrar el sentido de estos nombres extra-largos y cuán útiles son.




Resumen


Estas sugerencias de nomenclatura se basan en la forma de pensar natural sobre las cosas: cuando queremos un manzana de la frutería, vamos a ver si "HayManzanasEnLaFruteria", jamás iremos a ver si "NoHayManzanasEnLaFrutería", ya que la negación no es la forma natural de razonar, y por eso es que no es recomendable usar negaciones en los nombres de los métodos.

Respecto de los nombres largos, hay que hacerlos lo más descriptivos posibles, a tal punto que no requiera tener que inspeccionar el código para saber lo que hacen.

Finalmente, recuerden hacerse la pregunta con el nombre del método: Si las respuestas admitidas son ambiguas o no son del todo exactas, entonces el nombre no está bien elegido y conviene cambiarlo.

Todo esto ayudará enormemente a la autodocumentación de las aplicaciones y a que tanto ustedes como cualquier otro desarrollador puedan saber qué hacen los procedimientos o funciones solo leyendo sus nombres, lo que también facilitará el mantenimiento de la misma, aunque pase mucho tiempo.

Incluso si alguien nuevo debe familiarizarse con el código, estas buenas prácticas lo ayudarán a no perderse y ser productivo en menos tiempo.



Hasta la próxima!


sábado, junio 07, 2014

Nueva versión v2.4.17 de las herramientas Visual FoxPro 9 para PlasticSCM (Incluye FoxBin2Prg.exe v1.19.23)

Por: Fernando D. Bozzo

Está liberada la versión v2.4.17 de las herramientas Visual FoxPro 9 para PlasticSCM, con los siguientes cambios:

  • Agregado switch "nFlags" en los scripts vbs para Plastic, para poder mostrar un mensaje de finalización de proceso, muy útil cuando se procesan muchos archivos o cuando se procesan archivos pesados que tardan (activo por defecto)
  • Activado por defecto el mensaje de finalización de proceso en los scripts vbs para usar con el administrador de archivos de Windows
  • Actualizada la versión de FoxBin2Prg (solo el EXE) a la versión v1.19.23



Estas herramientas son un grupo de scripts vbs y programas Visual FoxPro 9 que se configuran dentro de PlasticSCM para poder invocar a FoxBin2Prg (incluye solo el EXE) desde dentro de la interfaz de Plastic.

El README.txt explica como se configura en Inglés y Español.

Nota: Los fuentes de FoxBin2Prg están en CodePlex, en el link indicado arriba en la versión.


Como actualizar las existentes:
Con descargarlas y reemplazar los archivos en el sitio que los hayan puesto antes es suficiente.


Link de descarga:
https://github.com/fdbozzo/foxpro_plastic_diff_merge


Saludos!

Nueva versión v1.19.23 de FoxBin2Prg (Arreglos y mejoras)

Por: Fernando D. Bozzo

Está liberada la versión v1.19.23 de FoxBin2Prg con los siguientes cambios:

  • Mejora: Los valores de los campos timestamp y uniqueid vuelven a los binarios. En los tx2 es configurable con los flags NoTimestamps y ClearUniqueID. En la v1.19.7 se introdujo la posibilidad de vaciar los timestamps de los binarios y tx2 con el switch NoTimespamt, y en la v1.19.10 se introdujo el flag ClearUniqueID para hacer lo mismo con los UniqueID. Desde esta versión esos campos se dejan con valor en los binarios siempre y los switch solo afectarán a los textos tx2 generados desde los mismos. El motivo es evitar diferencias innecesarias en los binarios, ya que si, por ejemplo, un proyecto PJX tiene estos campos vacíos y se abre el proyecto (con MODIFY PROJECT), aunque no se toque nada y se cierre, FoxPro completa varios de estos campos automáticamente, lo que produce diferencias que luego salen en el control de código como binario modificado.
  • Mejora: Agregado valor de sccdata por defecto. Este es otro campo que se dejaba vacío, pero que al abrir ciertos componentes con MODIFY, aunque no se modifiquen, FoxPro les rellena este campo con el valor por defecto. Desde esta versión los binarios regenerados tendrán este campo relleno con el valor por defecto, así FoxPro no lo rellena por su cuenta y se evitan diferencias en los binarios por este motivo.
  • Bug Fix: Arreglo de evaluación de la fecha para incluir los archivos ??T (vct, frt, mnt, sct, lbt). En la v1.19.21 se introdujo una mejora en la regeneración de archivos, controlada por el switch OptimizeByFilestamp (activa por defecto en foxbin2prg.cfg), en la que se optimizaba su creación dependiendo del timestamp de los archivos TX2 y de los archivos ??X. El problema es que si se modifica, por ejemplo, el backcolor de un form y se guarda, el archivo actualizado es el memo (SCT) y no el SCX, por lo que el archivo SC2 no se regeneraba, pudiendo perderse el cambio si se regeneraba el binario desde el mismo. Ahora se compara también el timestamp de los archivos .??T (memo), para evitar este problema. Esto solo afecta las instalaciones que tengan OptimizeByFilestamp = 1 en foxbin2prg.cfg
  • Bug Fix: Agregada propiedad faltante "BorderColor" en props_optiongroup.txt. No hubo ningún reporte de error por esto, pero faltaba en la lista y fue agregada.
  • Bug Fix: Agregada props Stretch en props_image.txt (Kenny Vermassen). La ausencia de esta propiedad en la lista de propiedades provocaba en ciertas situaciones que algunas imágenes se redimensionen mal, dependiendo del valor de la propiedad Stretch y del tamaño de la imagen. Esto solo afecta a los forms o clases que usen imágenes más grandes que el tamaño asignado al height/width del control image que las contiene.
  • Bug Fix: Agregada props Enabled en props_image.txt. No hubo ningún reporte de error por esto, pero faltaba en la lista y fue agregada.


Como actualizar el FoxBin2Prg existente:
Con descargar el zip y reemplazar los archivos en el sitio que los hayan puesto antes es suficiente.


Link  de descarga:
https://vfpx.codeplex.com/releases/view/116407


 Saludos!

domingo, mayo 18, 2014

Nueva versión v2.4.16 de las herramientas Visual FoxPro 9 para PlasticSCM (Incluye FoxBin2Prg.exe v1.19.22)

Por: Fernando D. Bozzo

Está liberada la versión v2.4.16 de las herramientas Visual FoxPro 9 para PlasticSCM, con los siguientes cambios:

- Actualizada la versión de FoxBin2Prg (solo el EXE) a la versión v1.19.22



Estas herramientas son un grupo de scripts vbs y programas Visual FoxPro 9 que se configuran dentro de PlasticSCM para poder invocar a FoxBin2Prg (incluye solo el EXE) desde dentro de la interfaz de Plastic.

El README.txt explica como se configura en Inglés y Español.

Nota: Los fuentes de FoxBin2Prg están en CodePlex, en el link indicado arriba en la versión.


Como actualizar las existentes:
Con descargarlas y reemplazar los archivos en el sitio que los hayan puesto antes es suficiente.


Link de descarga:
https://github.com/fdbozzo/foxpro_plastic_diff_merge


Saludos!

Nueva versión v1.19.22 de FoxBin2Prg (Arreglo de bugs, mejoras y optimizaciones)

Por: Fernando D. Bozzo

Está liberada la versión v1.19.22 de FoxBin2Prg con los siguientes cambios:

  • Bug Fix scx/vcx: La propiedad Picture de una clase form se pierde y no muestra la imagen. No ocurre con la propiedad Picture de los controles (Fidel Charny). Este problema ocurre cuando se ordenen las propiedades internas del form de cierta forma. FoxPro las necesita en cierto orden --que no está documentado-- para que funcionen correctamente. Regenerando el binario desde el tx2 existente se soluciona el problema.
  • Bug Fix scx/vcx: Algunas opciones del optiongroup pierden el width cuando se subclasan de una clase con autosize=.T. (Miguel Duran). Este problema está relacionado con el anterior, ya que también depende del orden de las propiedades internas, por lo que he realizado un estudio más a fondo de todas las propiedades de todas las clases de VFP 9 (ver Excel en directorio TESTS del proyecto) y las he agrupado para poder obtener un orden de propiedades con las ubicaciones más habituales. Para disminuir la posibilidad de conflictos, hay un segundo order que va por clase, donde se usa el orden exacto que usa VFP 9. El mejor caso es aquel donde cada clase se programan sus propiedades de una sola vez (aquí se usa el ordenamiento exacto por clase), y el peor caso es cuando se subclasa un contenedor de controles y en la subclase se redefinen las propiedades de los mismos (aquí se usa la lista genérica porque no se sabe qué propiedad corresponde a qué clase, ya que FoxPro guarda todo como una gran lista).
  • Agregado soporte de evaluación de propiedades desde archivo externo (props_*.txt). Todo lo anterior, y también por motivos de performance y mantenimiento, ha motivado la creación de listas de propiedades en archivos de texto independientes, uno por cada clase y uno genérico que las contiene a todas.
  • Bug Fix scx/vcx: La detección incorrecta de PROCEDURE/ENDPROC/TEXT/ENDTEXT puede causar pérdida de algunos métodos en determinadas circunstancias (Andres Mendoza). Si por alguna casualidad, en el código hay alguna variable que comience por "TEXTxxx", esto ocasiona que el parser la confunda con la estructura TEXT/ENDTEXT y considere todo lo posterior como si fuera parte del mismo método. El efecto visual en el tx2 es la pérdida de la indentación y la duplicación de los métodos antes agrupados como métodos vacíos. Si se conserva este tx2 se puede recuperar el binario original regenerándolo con esta versión, pero si se usó la versión defectuosa (v1.19.21 y anteriores) para regenerar el binario, en el peor caso podrían perderse métodos y ser necesario restaurar desde un backup previo.
  • Mejoras en Tests Unitarios de comparación de bitmap de pantallas antes/después (se compara contra regenerado de regenerado por si hubiera algún cambio). Estos han sido unos tests costosos de montar, ya que el objetivo era probar todos los controles visuales de FoxPro en distintas configuraciones (control y subclase de control), como así también la comprobación de que se siguen ejecutando correctamente algunos eventos como Access, Assign y programmaticChange, para tener más seguridad de los cambios realizados en el ordenamiento de las propiedades.
  • Agregado Unit Testing de la configuración por defecto, por archivo y por parámetros. Se han agregado tests automatizados para los tres tipos de configuración, donde el orden de prioridad es: 1-Parámetros, 2-foxbin2prg.cfg, 3-Valores por defecto
  • Agregado Unit Testing para comprobar generación de clases, forms, reportes y menús. De varios componentes se han guardado las versiones texto para poder compararlas con las que se regeneren desde los binarios, y así poder saber si algún cambio futuro provoca algún cambio en la generación de los tx2.
  • Agregado nuevo switch OptimizeByFilestamp (activo por defecto) que permite desactivar la optimización de regeneración de archivos según el timestamp, en el caso de querer regenarar siempre. Desde la versión v1.19.21 hay una optimización sugerida por Matt Slay, en la que si el archivo a regenerar (ej: un binario) tiene una fecha/hora más nueva que el archivo base (ej: un tx2), significa que no es necesario volver a regenerar porque el archivo a generar (destino) es más nuevo que el archivo origen. Igualmente, como siempre pueden haber casos especiales donde este no sea el comportamiento deseado y se requiera regenerar siempre el destino, hay un nuevo switch, tanto en el archivo de confguración foxbin2prg.cfg como por parámetro, llamado OptimizeByFilestamp, donde se puede inhabilitar asignándole "0".
  • Optimización en garbage collect en todo el código. Se han hecho muchos cambios para mejorar la recolección de basura (liberación de objetos y referencias de objetos principalmente), lo que ha mejorado perceptiblemente la estabilidad durante la ejecución de los tests automatizados.


Como actualizar el FoxBin2Prg existente:
Con descargar el zip y reemplazar los archivos en el sitio que los hayan puesto antes es suficiente.


Link  de descarga:
https://vfpx.codeplex.com/releases/view/116407


 Saludos!

jueves, mayo 01, 2014

Nueva versión v2.4.15 de las herramientas Visual FoxPro 9 para PlasticSCM (Incluye FoxBin2Prg.exe v1.19.21)

Por: Fernando D. Bozzo

Está liberada la versión v2.4.15 de las herramientas Visual FoxPro 9 para PlasticSCM, con los siguientes cambios:

- Actualizada la versión de FoxBin2Prg (solo el EXE) a la versión v1.19.21



Estas herramientas son un grupo de scripts vbs y programas Visual FoxPro 9 que se configuran dentro de PlasticSCM para poder invocar a FoxBin2Prg (incluye solo el EXE) desde dentro de la interfaz de Plastic.

El README.txt explica como se configura en Inglés y Español.

Nota: Los fuentes de FoxBin2Prg están en CodePlex, en el link indicado arriba en la versión.


Como actualizar las existentes:
Con descargarlas y reemplazar los archivos en el sitio que los hayan puesto antes es suficiente.


Link de descarga:
https://github.com/fdbozzo/foxpro_plastic_diff_merge


Saludos!

Nueva versión v1.19.21 de FoxBin2Prg (Mejoras y Optimizaciones)

Por: Fernando D. Bozzo

Está liberada la versión v1.19.21 de FoxBin2Prg con los siguientes cambios:

    • Agregado soporte para convertir a texto o binario todos los archivos de un proyecto desde pjx o pj2 (Matt Slay). Gracias al feedback en el foro Google de Thor (Proyecto VFPx), me comentaron que sería útil poder pasar todos los archivos de un proyecto PJX a texto (y viceversa), por lo que se agregó esa posibilidad. Para hacerlo, se debe ejecutar desde la ventana de comandos: DO foxbin2prg WITH "<path>\proyecto.pjx", "*" . El último asterisco hace la diferencia entre el proyecto solo o todos los archivos del proyecto.
    • Optimización de búsqueda del programa de capitalización al procesar proyectos. Junto al nuevo soporte anterior, hay una optimización para no buscar una y otra vez por cada archivo escaneado si existe el programa de capitalizaciones, lo que implica un acceso extra al disco, por lo que ahora se cachea en memoria al inicio del escaneo.
    • Agregado AGAIN a la apertura SHARED de las tablas, para permitir concurrencia (Jim Nelson).
    • Agregada optimización basada en la la fecha/hora de modificación de los archivos para regerenar solo los archivos binarios y tx2 modificados (Matt Slay). Esta optimización puede mejorar mucho los tiempos de generación de los archivos binarios o tx2 de un proyecto o directorio, ya que solo se generarán los que hayan cambiado desde la última generación. Esto se hace comparando los timestamps de cada binario y su tx2, y fue sugerido por Matt Slay en el foro de Thor.
    • Agregada traducción al inglés en foxbin2prg_en.h del mensaje de LOG para la nueva optimización
    • Simplificación de la sección <DefinedPropArrayMethod>: Los métodos y arrays ya no requieren los símbolos * y ^ delante. Hasta ahora, en esta sección los métodos llevaban "*" por delante, y los arrays llevaban "^", ya que así es como está guardado en la tabla. Desde esta versión ya no requieren llevar esos símbolos por delante, y tampoco se generarán en los tx2, solo se generarán al actualizar los binarios. Esto mejora y simplifica el mantenimiento de este bloque. Igualmente se mantiene la compatibilidad con los archivos tx2 existentes que tengan esos símbolos.


    Como actualizar el FoxBin2Prg existente:
    Con descargar el zip y reemplazar los archivos en el sitio que los hayan puesto antes es suficiente.


    Link  de descarga:
    https://vfpx.codeplex.com/releases/view/116407


     Saludos!