miércoles, 22 de diciembre de 2010

GeneXus Knowledge Interchange Protocol

En el día de hoy se liberó el GeneXus Knowledge Interchange Protocol (KIP), como había prometido Breogán Gonda en el pasado XX Encuentro GeneXus.

Esta es una gran noticia. Todos los que alguna vez desarrollamos alguna aplicación que generaba o interactuaba con un XPZ, sabemos lo tedioso del proceso de hacer la ingeniería reversa para entender la estructura del mismo.

Sin duda tener la especificación va a facilitar el trabajo de los que tengan que trabajar con el formato.

Pero por otro lado, creo que el KIP se queda corto.

Citando la noticia en GXTechnical:
Con la publicación del GX KIP se pretende contribuir a la consolidación del paradigma de desarrollo de sistemas basados en conocimiento, y a su vez, atender las necesidades empresariales desatendidas por la programación manual.
[...]
GeneXus, y cualquier herramienta inteligente basada en conocimiento que pueda existir en el futuro, trabajan con una KB (Knowledge Base). La KB está formada por dos componentes: una base de datos, donde se almacena el conocimiento y una “máquina” capaz de procesar automáticamente dicho conocimiento.
El problema con el XPZ, es que es demasiado dependiente de la implementación actual de GeneXus. El conocimiento no solo es independiente de la tecnología utilizada, también debería ser independiente de la forma de representarlo.

Es decir, el hecho de que represente una entidad en un objeto Transaction de GeneXus, es independiente de la existencia de dicha entidad. La entidad con su estructura y sus reglas de negocio existen, independientemente de la forma de representarla en un WebForm. Lo que se tiene en el XPZ, es una mezcla de todo eso.

Sería interesante ver el XPZ separado en dos: una parte que describiera el conocimiento de la forma más pura posible, y otra que describiera la capa de presentación como la ve GeneXus. De esa forma sí sería una representación más fiel (y transportable a otras aplicaciones) del conocimiento almacenado en la base de conocimiento.

jueves, 16 de diciembre de 2010

Alkeo Blog App

BlogReader es una aplicación en la que estuve trabajando para Alkeo (ahora conocida oficialmente como Alkeo Blog App), que permite transformar un blog en una aplicación nativa para iPhone/iPad, Android y próximamente Windows Phone 7 (*).

Desde hace un tiempo, está disponible la aplicación Blog Shane, y desde hoy hay dos nuevos blogs que están disponibles en la App Store: Shunrize y Thibault Piron.

Advertencia: todo el contenido está en francés...

Les dejo un video de BlogShane para que conozcan la aplicación:



(*) Aclaro que yo solamente desarrolle la aplicación para iOS...

jueves, 9 de diciembre de 2010

Primeras impresiones de Ruby on Rails

Esta semana empecé a desarrollar una aplicación en Ruby on Rails, que no es una plataforma que domino, y quedé gratamente sorprendido por lo fácil que es empezar y las cosas que se logran con poco esfuerzo.

Pero primero que nada, ¿qué es Ruby on Rails? De hecho son dos cosas. Ruby es el lenguaje de programación, que tiene como característica que es bastante flexible. Como lenguaje me resultó sumamente interesante.

Rails por su parte, es un framework que extiende el lenguaje y se utiliza para crear aplicaciones web.

Scaffolding

Ruby on Rails se basa en el patrón Model-View-Controller, que (muy) básicamente permite separar la capa de presentación (view) de la capa de datos (model) y las conecta mediante un intermediario (controller).

Una funcionalidad muy buena de Rails, es que permite generar un Model con sus correspondientes Views y Controller en un solo comando. Esta operación se realiza con el comando scaffold (la traducción sería algo así como "andamio").

Para generar una nueva entidad, digamos por ejemplo Persona, con los campos nombre, apellido y fecha de nacimiento, sería algo así:
rails generate scaffold Persona nombre:string apellido:string fecha_nacimiento:datetime
Esto genera:
  • La clase Persona (model) con los campos persona_id, nombre, apellido, fecha_nacimiento, y por defecto agrega campos created_at y updated_at
  • El script para migrar la base de datos creando la nueva tabla
  • El controller para manejar varias operaciones: index (lista de elementos), show (detalle de un item), edit, delete, new y create.
  • Los archivos HTML correspondientes a las vistas, para cada una de las operaciones anteriores.
Si lo fuera a comprar con GeneXus, sería como generar la transacción y el patter WorkWith con los valores por defecto, con un solo comando...

Programación declarativa

No se si ese es el nombre que se le da, pero es la forma en que se programan muchas cosas.

Por ejemplo, si quiero agregar seguridad a mi aplicación usando Devise (ver más adelante), alcanza con poner la siguiente línea dentro de la clase controller
before_filter :authenticate_user!
Otro ejemplo, si quiero que el nombre de la persona sea obligatorio, puedo agregar una validación en la clase model, con lo siguiente:
validates :nombre, :presence => true
Listo, con ese código, si al crear una nueva persona dejo en blanco el nombre, me va a dar un error.

Gems

Las Gems en Ruby, son las bibliotecas de funciones.

Existen muchas que funcionan con Rails agregando funcionalidad específica, por ejemplo para agregar autenticación de usuarios y autorización.

Devise (autenticación)

Devise agrega una capa de autenticación de usuarios. Es sumamente flexible y a la vez fácil de instalar y configurar (no voy a entrar en detalles).

Para agregar autenticación alcanza con instalar este gem, ejecutar un par de comandos para que genere un model para los usuarios, y agregar el before_filter que figura más arriba para exigir que el usuario esté logueado para acceder a una determinada página.

CanCan (autorización)

CanCan se encarga de la autorización, y se integra con Devise o con cualquier otro sistema de autenticación.

Agregar autorización es tan simple como definir en un archivo que cosas puede hacer un usuario dado su rol, y preguntar si el usuario tiene permisos para realizar una determinada acción. Por ejemplo, para saber si el usuario puede modificar una persona, el código a agregar es el siguiente:
if can? :update, Persona
  # seguir adelante
else
  # ir a alguna página de error
end
Recursos

Con respecto a los recursos, para aprender un poco sobre Rails estuve leyendo Ruby on Rails Tutorial, que está bastante interesante y da una buena idea de como se trabaja en Rails. Además usa Test Driven Development como metodología, así que ya viene bien para conocer un poco de TDD.

Hay un sitio web llamado Railscasts que tiene videos que explican paso a paso como hacer varias cosas. Con más de 240 videos, hay como para entretenerse.

Conclusión

Me gustó tanto el lenguaje (Ruby) como la plataforma (Rails). Se pueden lograr cosas muy interesantes con relativamente poco esfuerzo.

Todavía soy un novato en este tema, pero parece ser muy bueno.

lunes, 6 de diciembre de 2010

Manejo de fechas en Objective-C

El lenguaje Objective-C tiene una carencia importante según yo lo veo, que es que hay cosas que deberían ser simples y llevan una cantidad importante de trabajo.

Un ejemplo es concatenar dos strings. En cualquier otro lenguaje, sería algo como:
result = s1 + s2;
En Objective-C, hacer lo mismo lleva mucho más código:
result = [NSString stringWithFormat:@"%@%@", s1, s2];
En particular, una de las cosas que me parecen de las más complicadas en Objective-C (desde el punto de la sintaxis), es el manejo de fechas.

Por ejemplo, para crear una fecha, el código es el siguiente:
NSDateComponents *comps = [[NSDateComponents alloc] init];
[comps setYear:2010];
[comps setMonth:12];
[comps setDay:6];

NSDate *date = [[NSCalendar currentCalendar] dateFromComponents:comps];

[comps release];
También si quiero obtener el día, mes y año de una fecha dada, es complicado:
NSDate *tmpDate = [NSDate date]; // today
NSDateComponents *comp = [[NSCalendar currentCalendar] components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:tmpDate];

int day = [comp day];
int month = [comp month];
int year = [comp year];
Claro que estas complicaciones tienen algunas ventajas. Por ejemplo, puedo tener una fecha y consultar el año en distintos calendarios (gregoriano, budista, hebreo, etc.), pero de todas formas, debería haber alguna forma más fácil de trabajar con fechas.

Por suerte, en Objective-C uno puede agregar métodos a clases ya existentes, por lo que es posible agregar algunos métodos a la clase NSDate para facilitar el trabajo. Por ejemplo:
@implementation NSDate (DateHelper)

+ (NSDate *) dateWithYear:(int)year month:(int)month day:(int)day {
NSDateComponents *comps = [[NSDateComponents alloc] init];
[comps setYear:year];
[comps setMonth:month];
[comps setDay:day];

NSDate *tmpDate = [[NSCalendar currentCalendar] dateFromComponents:comps];

[comps release];

return tmpDate;
}

- (int) getDay {
NSDateComponents *comp = [[NSCalendar currentCalendar] components:NSDayCalendarUnit fromDate:self];
return [comp day];
}

- (int) getMonth {
NSDateComponents *comp = [[NSCalendar currentCalendar] components:NSMonthCalendarUnit fromDate:self];
return [comp month];
}

- (int) getYear {
NSDateComponents *comp = [[NSCalendar currentCalendar] components:NSYearCalendarUnit fromDate:self];
return [comp year];
}

@end
Ahora entonces para crear una nueva fecha, podemos hacer simplemente:
NSDate *date = [NSDate dateWithYear:2010 month:12 day:6];
y para obtener el año de dicha fecha
int year = [date getYear];

viernes, 3 de diciembre de 2010

El portal del estado uruguayo y pagos a través de ANTEL

Hace un rato, tenía que ver como era el tema para renovar la cédula de identidad (documento que identifica a las personas en Uruguay...).

¿Cuál es el lugar para buscar esa información? Obviamente, el portal del estado uruguayo.

Busqué por "renovación cédula de identidad" y el resultado que estoy buscando aparece en el segundo o tercer lugar. Bien.

Primer problema: el sitio con la información correspondiente usa HTTPS pero el certificado no es de confianza... Por lo tanto Google Chrome me muestra una página toda roja, que generaría alarma en cualquier usuario desprevenido.

Viendo el certificado de la página, veo que fue emitido por el Correo Uruguayo, que obviamente no es reconocido como proveedor de confianza...

Sigo adelante.

Llego a una página donde me da toda la información de a qué número de teléfono tengo que llamar, la dirección de la oficina, etc., y un link para hacer el pedido de hora on-line. ¡Espectacular!

En el sitio dice que se puede pagar con Banred (que no tengo) o mediante ANTEL y viene el costo en la próxima factura del teléfono. Bien, pero antes, hay que registrarse en ANTEL.

Voy a la página de ANTEL y me registro. Me piden nombre, apellido, número de cédula, número de cuenta de ANTEL (que aparece en la factura), que elija un nombre de usuario y contraseña, pregunta de seguridad (!), y varios datos más.

Ahora que ingresé todo, confirmo. Y al confirmar me dice que la solicitud va a ser procesada el primer día hábil, y me van a mandar un mail cuando esté habilitado.

Yo pregunto... ¿por qué tiene que ser un día hábil? Si ya tienen todos mis datos, ¿no es hacer un select en la base de datos para ver que los datos sean correctos? Es más, yo se los escribo:
select count(*) from USUARIOS where Nombre = ? and Apellido = ? and Cedula = ? and Telefono = ? and NroCuenta = ?
Si eso da mayor que cero, entonces los datos están bien...

Recién me llamaron... para pedirme el número de cédula que ya se los dí en el sitio web, y dice que me va a llegar un mail en dos horas con la confirmación de la habilitación.

Como hay gente que le gusta hacer las cosas complicadas...