jueves, 18 de agosto de 2016

Usabilizando GeneXus: Renombrar variables

Una de las cosas que ayuda mas a entender código escrito por otras personas, es que las variables, los objetos y las rutinas usadas en dicho código, tengan nombres coherentes y que permitan identificar rápidamente lo que se almacena en ellas.

A medida que pasa el tiempo, el significado de los diferentes objetos/variables del sistema  puede cambiar y por lo tanto conviene renombrarlo.

Si lo que renombro son tablas o atributos, le cambio el nombre, se genera un programa de reorganización para cambiar la base de datos y se regeneran todos los programas en forma que empiecen a usar dichos nombres.

Es renombrar objetos ejecutables (por ejemplo, procedures, transactiones, webpanels, etc) dentro de la KB, es una tarea que esta bien implementada, pues le cambio el nombre al objeto, hago un build all y se regeneran y compilan todos los objetos que se necesitan.

Las rutinas dentro de un objeto, se pueden renombrar y pero hay que cambiar en forma manual los lugares que hacen referencias a las mismas. No es un gran trabajo, pero hay que hacerlo en forma manual. El especificador indica cuando nos equivocamos en el cambio de nombre. Es una tarea que podría mejorarse, dando la opción al renombrar la subrutina que proponga un dialogo para cambiar todos los lugares que esta siendo invocada la misma.

Lo que si me parece que es muy mejorable, es la tarea de renombrar variables dentro de los objetos.
Hoy renombrar una variable, implica cambiar la definición de la misma (en el TAB de variables del objeto) y luego hay que ir por todos los demás TABs, cambiándola. Puede estar en las condiciones, en las rules, en el form, en el source.
Es una tarea en la cual se pueden introducir muchos errores, por lo que los programadores la evitan. Esto trae como  consecuencia, que una vez que una variable se nombro mal, como da mucho trabajo renombrarla, queda con el nombre mal por mucho tiempo.

Creo que si GeneXus ayudara en el renombre de variables, colaboraríamos mas para tener  código un poco mas facil de leer y entender.

Creo que son pequeñas cosas a mejorar que nos haría la vida un poco mas placentera y nos dejará pensar en problemas mas importantes.

PD1: Otra funcionalidad un poco mas avanzada, seria la de renombrar las variables basadas en un atributo y tiene el mismo nombre que dicho atributo, cuando lo renombro. Por ejemplo, si tengo el atributo/dominio CliId y en varios objetos de la KB tengo &CliId basada en dicho atributo, cuando renombre CliID a ClienteID, me pregunte si quiero renombrar tambien las variables basadas en dicho atributo y las renombre en forma acorde.

PD2: Hay dos  tipos de objetos que tienen problemas al renombrarse. Uno son los SDT cuando se tienen mas de un generador, porque muchas veces al renombrarlos las cosas dejan de compilar, porque quedan mal las referencias. Es un error que deberia solucionarse.

Otro caso en el cual se cambia el comportamiento al renombrar es con los External Objects del tipo SOAP, cuando manejan Location. En el codigo, pueden quedar referencias al nombre cuando se hace el GETLocation("NombreObjeto") y dicho nombre no se cambia cuando se renombra, por lo cual el programa deja de hacer lo que estaba haciendo. Hay que tener cuiado con este caso tambien.
Es un error que podria evitarse si GeneXus tuviera una sintaxis diferente.

Si en  vez de usar

&Location = GetLocation("NombreObjeto")

fuera

&Location = &NombreObjeto.GetLocation()

se podría adaptar automáticamente al cambio de nombre.

viernes, 12 de agosto de 2016

Quien paga las migraciones?

Un colega me pregutó como manejábamos los procesos de migración y fundamentalmente si le cobrábamos algo adicional a los clientes en los procesos de migraciones.

Cuando hablo de migración, me refiero cuando quiero cambiar la version de mi herramienta de desarrollo (en mi caso GeneXus), para una mas nueva y con mejores prestaciones, pero sin agregar funcionalidad ninguna.

Es muy dificil vender estos proyectos a los clientes, pues el valor de los mismos pasan bastante desapercibidos. Funcionalmente la aplicación luego de terminar el proyecto tiene que hacer exactamente los mismo que antes, pero al regenerar toda la aplicación se agrega el riesgo de que algo funcione diferente y peor que antes.

Si bien no hay una receta única para esto, en general es bueno tratar de absorber el costo de los proyectos de migración. En el futuro, se le puede cobrar a los clientes, por las nuevas funcionalidades que se van a desarrollar con las nuevas tecnologías o mejoras al sistema.
Por ejemplo al migrar a Evolution 3, puede cobrarse por hacer una aplicación responsive que se adapte a todos los dispositivos, o con navegación smooth, o que soporte HTML5 y los ultimas versiones de los navegadores.

Dentro de las diferencias de funcionamiento podemos tener :

  • Cambios en la performance (cambios en sentencias, optimizaciones, etc)
  • Cambios en la seguridad (aplicaciones mas seguras)
  • Cambios tecnológicos (soporte de nuevas tecnológicas, html, responsive, etc)

En los proyectos de migración, lo que hay que hacer es mitigar los riesgos que cosas que funcionaban bien, empiecen a funcionar mal. Para esto lo mejor es detectar las diferencias y analizarlas para ver si hay algun problema. Según mi experiencia, el porcentaje de objetos que funcionan diferente es bastante bajo de una versión a la siguiente, por lo que si hacemos el ejercicio de migrar cada 2 años, es un trabajo mas que razonable.

Bueno, resumiendo y para no hacer un post muy largo

Migrar es indispensable, por lo tanto hacelo rápido

Si queremos mantenernos en el mercado, es indispensable migrar, por lo que conviene hacerlo lo mas a menudo que se pueda. Por supuesto que hay que equilibrar las horas que dedicamos a las migraciones, con las horas de desarrollo de nuevas funcionalidades, que siempre deberian ser la prioridad numero uno.
El proceso de migracion es muy automatizable, por lo que una vez que nos convencemos que es una tarea que hay que voy a tener que realizar varias veces, conviene invertir en automatizar la mayoria de los procesos que involucran.

Hacer migraciones desechables. 

Una vez que se tiene automatizado o al menos estandarizado el proceso de migracion, se hace mucho mas fácil hacer migraciones de prueba a nuevas versiones. Por ejemplo, es muy bueno hacer una copia de mi KB y convertirla a la ultima versión de GeneXus y  ver si aparecen errores o warnings nuevos. También hacer pruebas para ver si todo se genera sin problemas. 

Migrar permite detectar errores

En las migraciones, es un buen momento de detección de errores. 
Durante el proceso de desarrollo muchas veces se realizan determinadas "pisadas" para que las cosas funcionen o se hacen pasos de forma no demasiado ortodoxa. Las migraciones son el momento donde quedan a la vista todas estas "no conformidades" del proceso de desarrollo. 

Esto es un valor agregado importante de las migraciones, aunque algunos la vean como algo malo, para mi es algo muy bueno, pues ayuda a mejorar el proceso de desarrollo. 
Algunos ejemplos :
  • Se borro un objeto en la KB, pero se dejo en producción. 
  • Se renombró un objeto, pero sigue estando el viejo y el nuevo. 
  • Se copio un programa externo y el mismo no esta en la KB. 
  • Se modifico un CSS, javascript en producción y no se documentó correctamente
  • Se uso un font no standard y no se documento correctamente
  • Se instaló en producción una versión mas nueva del  User Control y no se documento

Migrar trae riesgos y hay que minimizarlos 

Conviene detectar diferencias en :

  • Navegaciones / Performance
  • WSDL/REST
  • Lista de programas generados
  • Interfaz de la aplicación con el exterior (Planillas, file system, mail, etc)
  • Revisar logs de ejecución en busca de errores o lentitudes
  • Pruebas funcionales
Una vez detectadas las diferencias, hay que estudiarlas y ver cuanto nos pueden afectar. 
Si el salto de versión no es muy grande, son tareas muy manejables. 

Desarrollar y cobrar por nuevas funcionalidades.


Esta es la parte mas fácil si estamos capacitados en las nuevas funcionalidades que nos brindan la versión.

El resumen es:

  • Migrar rapido y a menudo (este paso debería ser casi automático)
  • Encontrar diferencias rapido  (este paso debería ser casi automático)
  • Iterar hasta estar convencido que todo funciona bien
Si se puede hacer esto, el costo de la migración es fácil de compensar con las nuevas funcionalidades y las mejoras en productividad. 

martes, 9 de agosto de 2016

SUGERENCIA PARA GXSERVER. Duplicar un version y su estado.

Esta es una funcionalidad que me gustaría tener en GXServer. 


Tengo una KB, con objetos, con  base de datos con datos y un build all terminado en mi version de trabajo y es la misma desde la que instalo y esta en producción. 

Quiero hacer un cambio grande con reorganización que puede llevar un tiempo largo (mas de una semana)  y me gustaría poder trabajar tranquilo sin afectar mi capacidad de instalar desde la version original. 

Me gustaría poder contar con una opción que haga estos pasos en uno solo

  • Cree una version congelada
  • Cree una version derivada de la congelada
  • Copie la estructura de archivos de la version original a la nueva (TargetPath, subdirectorios y archivos de especificación)
  • Deje todos los objetos como especificados (igual que la version original)
  • (Paso opcional) Cree la estructura de la base de datos nueva con la misma estructura de la version original
  • (Paso opcional) Copie los datos de la base de datos de la version original a la base de datos de la nueva version. 
  • Copie todos los archivos del usuario que corresponden a esa version
La idea básica es DUPLICAR una version y todo su estado a una nueva version independiente, evitando el tiempo del build all y automatizando la copia de datos que es una etapa muy engorrosos para hacerla a mano. 

Una vez hecho esto, puedo ponerme a trabajar en dicha version, sin interferir con mis compañeros de grupo. 
Cuando pruebo el cambio y el mismo cumple con los requerimientos, debo llevar todos los cambios hacia la version original y esto se puede hacer con la opción de Bring Changes y todo volvería al proceso normal

Por ultimo, cuando ya no necesite mas esta version me gustaría contar con una opción de borrado de la version que haga

  • Borre la version Congelada
  • Borre la version derivada de la congelada
  • Borre todos los archivos del targetpath, de especificación y del usuario correspondiente a dicha version y archivos ari 
  • (opcional) Borre la base de datos o tablas generadas

Creo que estas opciones harian mas facil el uso de versiones en grupos de trabajo. 

jueves, 21 de julio de 2016

StackOverflow Documentation

En StackOverflow pusieron en BETA Documentation. 


Es un lugar donde se pueden subir ejemplos de código de diferentes lenguajes.
La gente puede votarlos por utilidad y también clasificarlos por version para la que sirve, etc.

Me parece buen lugar donde empezar a generar ejemplos de GeneXus para darle mas visibilidad y mostrar como se pueden hacer cosas sofisticadas con poco código.
Tiene de malo, que no todo lo que modelamos con GeneXus se traduce a código, por ejemplo, las estructuras de transacciones y SDT, la definición de variables, el editor abstracto, los patrones, etc, pero para procedures y eventos y reglas, puede funcionar muy bien.

Al menos, pondría ahí un ejemplo de cada una de las palabras claves de Genexus, de sus tipos de datos y external objects standard.

Si logran hacer con la documentación, lo mismo que hicieron con las preguntas y respuestas de programacion el resultado puede ser bueno.

UPDATE
Marcos me comentó que el tag #GeneXus aun no tiene movimiento suficiente como para ingresar documentación. Ser pocos tiene estos problemas. Hay que hacer un poco mas de ruido para que nos escuchen.

martes, 19 de julio de 2016

Migrando de GeneXus Evolution 2 a GeneXus Evolution 3.

Estamos realizando una migración de version de GeneXus, a la última liberada.



Algunas de las tareas involucradas fueron las siguientes

Comparación de Navegaciones. 

Use el KBDoctor para comparar las navegaciones de la Evolution 2 con la Evolution 3.
Unos cuantos objetos cambiaron su navegación, pues ahora cambia el ORDER de algunas sentencias.
En general, el criterio que vi es que toma en cuenta las condiciones del WHERE para considerar el orden. Parece mejor en casi todos los casos, pero igual hay que chequear contra la base de datos para ver si alguna sentencia que estaba optimizada no tiene problemas de performance.


Comparación de WSDL de servicios publicados. 

Tuvimos diferencias en algunos pocos WSDL publicado, pero era por habíamos dejado el Namespace de la KB en su valor por default y como la KB toma el nombre de la KB como Namespace, al cambiar de KB cambiaba la definición del WSDL. Detectamos el problema y lo solucionamos rapido.

Objetos con  código nativo.

Tenemos algunos programas externos, que tuvieron que cambiar porque usabamos el metodo cleanup() que paso de ser private a public override.

Shell, SQL, Stored Procedure

Las llamadas al Shell, SQL y Stored Procedures, funcionaron sin problemas.

Excel, PDF, XMLWriter, XMLReader, Envio de Mail

No tuvimos diferencias en el funcionamiento.

GXFlow

Tuvimos inconvenientes en la creación de tablas de Workflow y en la ejecución de la actualización de la base de datos. Con el cliente Oracle de 32 bits, los programas daban error, diciendo que el cliente oracle no era compatible con el data provider.
Tuvimos que cambiar los exes que están bajo Packages/gxpm/platfom y ejecutarlo con el comando

corflags  /32BITREQ+

y marcarlos para forzar la ejecución de 32bits.

Cliente Oracle. 

En versiones anteriores  de aplicaciones GeneXus teníamos restricciones con cual version del dataprovider teniamos que usar, pues tenia que ser la misma con la que había sido compilado.
Ahora no tuvimos problemas en usar el dataprovider que estábamos usando.

Scripts de Build y Deploy. 

Hicimos varios cambios, porque estamos aprovechando la migración para dejar únicamente el generador WEB. Tenemos muchos procesos batch que se generan con el generador WIN en Evolucion 2 y ahora pasan a generarse todo con el generador WEB.
Hice un programa que cambia los generadores y eso facilito la tarea.


Cosas que nos falta probar

  • Data Type.WebSession, Data Type.WebWrapper, Data Type.Cookie, Data Type.Directory, Data Type.File
  • Data Type.HttpClient, Data Type.HttpRequest, Data Type.HttpResponse, Data Type.Location
  • Data Type.Queue, Data Type.QueueMessage, Data Type.RegExMatch, Data Type.Window
  • Todos los User Controls. (son 17!!)
Vamos bien, ya estamos haciendo pruebas manuales y vamos a seguir con las pruebas automatizadas.