Orientación a Obejtos Pura

Es común cuando se presenta Smalltalk mencionar que es un lenguaje orientado a objetos puro. También es común que la audiencia no logré captar el significado de esta afirmación inmediatamente. Yo mismo he analizado esta afirmación montones de veces, pensando que tal vez sea un poco extrema, pero esta semana, vi la luz y me dí cuenta de que es absolutamente acertada.

Resulta que por estos dias, me encuentro entrenando a un grupo de programadores en C#. Fue en este contexto que me encontré hablando de las diferencias y relaciones entre interfaces, clases, estructuras (structs) y enumerados, ¡recorcholis! 4 artefactos del lenguaje que NO son objetos. ¡Y aún no expliqué eventos, delegados, tipos primitivos y atributos (anotaciones)!. ¡Cuantas cosas que explicar!

¡Cuanto más fácil seria explicar Smalltalk!

¿Bug en Mercado Libre?

Busco un producto, reviso las opciones, finalmente me decido y compro.Voy a retirar el producto, llego a casa y veo que no tiene una característica que recuerdo explícitamente me interesaba.

Entro a mi cuenta de Mercado Libre a ver los detalles de la compra. En mi lista de compras figura el item comprado junto con su precio (digamos $100). Hago click en el item para ver el detalle de la compra y me lleva a la publicación. Pero…. ¡rechorlis! la publicación ha sido actualizada, el precio ya no es $100, sino $80 y la especificación a cambiado.

Llamo al vendedor, explico la situación. El flaco comprende el problema y admite que hubo una actualización en la publicación. Me indica que me acerque al local asi arreglamos la situación. Parece que no va a haber problemas, mañana les cuento.

Si el flaco no tenia buena onda, yo estaba al horno, pues al parecer Mercado Libre no guarda «una foto» de la publicación al realizar la compra. Hablando tecnicamente, parece que la entidad compra, no tiene los detalles de la compra sino simplemente una referencia a la entidad publicación. Puede que esto sea asi explícitamente por diseño, pero desde el punto de vista del negocio, yo creo que es un Bug, pues yo como comprador quiero poder tener el detalle exacto de lo que compré independientemente de que la publicación sea actualizada.

Por otro lado miro mi lista de compras y veo que solo figuran las más recientes, las compras que realicé hace 11 meses no figuran en el listado. Mmmm esto tampoco me gusta, pues tampoco veo ningún link del estilo «Ver compras anteriores».

Nota: si bien el post está escrito en primera persona, esta situación no me sucedió a mi sino mi hermano, pero yo la seguí de cerca e incluso la reproduje.

Sobre el hosteo de aplicaciones en Heroku

Luego de estar trabajando con Heroku por un par de semanas, hoy voy a compartir algunos algunos consejos útiles.

Suele ser una buena práctica al desarrollar una aplicación, manejar distintos ambientes. En general suelen manejarse al menos 4 ambientes, puede que los nombres varíen, pero en líneas generales podríamos decir:

  1. Desarrollo, donde se desarrolla aplicación
  2. Test/integración, ambiente similar de desarrollo donde se ejecutan la pruebas
  3. Staging, ambiente de prueba lo más parecido posible al de producción donde se realizan las pruebas de aceptación (UAT)
  4. Producción, ambiente final donde correr la aplicación

Al trabajar con Heroku tendremos

  1. Desarrollo es la maquina del desarrollador
  2. Test/integración, es el build server
  3. Producción ya dijimos que seria heroku, por lo cual
  4. Staging también debería ser heroku.

Si uno está dispuesto a pagar, heroku nos permite manejar más de un ambiente en la misma aplicación, pero si pretendemos un enfoque gasolero al máximo, entonces tendremos que generar 2 aplicaciones: una representará nuestro ambiente productivo y la otra a nuestro ambiente de staging. Dado que el comportamiento de ciertos componentes puede varias dependiendo de ambiente en que se encuentre, para que nuestra aplicación Heroku de staging se comporte como tal, tendremos que setear la correspondiente variable de entorno utilizando el siguiente comando

heroku config:add RACK_ENV=staging

Esta variable tiene como valor por defecto production y por eso es que no la modificaremos para nuestra aplicación de producción.

Utilizando esta variable podremos definir distintos parametros de configuración para cada uno de nuestros ambientes.

configure :production do
  DataMapper::setup(:default, ENV['DATABASE_URL'])
  DataMapper.auto_upgrade!
end

configure :staging do
  DataMapper::setup(:default, ENV['DATABASE_URL'])
  DataMapper.auto_upgrade!
end

configure :development do
  DataMapper::setup(:default, "sqlite3://#{Dir.pwd}/mydata.db")
  DataMapper::Model.raise_on_save_failure = true
  DataMapper.auto_upgrade!
end

configure :test do
  DataMapper.setup(:default, "sqlite::memory:")
end

Para poder desplegar nuestra aplicación a los correspondientes ambientes, tendremos que agregar los correspondientes repositorios git remotos. En general uno ya lo tendremos seguramente bajo el nombre heroku, pero para evitar confusiones lo mejor seria removerlo y volver a agregarlo con un nombre mas representativo. Para ello podemos hacer

git remote add production <git-de-la-app-heroku-de-production>
git remote add staging <git-de-la-app-heroku-de-staging>

El hecho de que el despligue a Heroku este basado en git, hace muy simple el versionado de la aplicación y la vuelta atras a una versión anterior. Pero más allá de esto hay un plugin que estoy utilizando llamado Releases. Este plugin ofrece cierta funcionalidad básica en su versión gratuita (como agregar un número amigable de versión a cada despliegue y la posibilidad de hacer un rollback del último despliegue).

Continuará…

Fin de mi primer cuatrimestre en Ingeniería de Software

Finalmente el lunes pasado cerramos la materia. Entregué las notas he hicimos una retrospectiva. Si bien la materia no salió exactamente como la había planeado, estoy conforme con el resultado. Creo que logré transmitir conceptos importantes y algunas herramientas concretas para el desarrollo profesional, la organización personal y el trabajo en equipo. Comencé el cuatrimestre con 15 alumnos y lo terminé con 12. Por lo que pude hablar con algunos alumnos, aquellos que dejaron la materia lo hicieron principalmente porque tenían otra expectativa respecto de la dedicación que la materia requería. Incluso los alumnos que completaron la materia, también coincidieron en este punto. Esto me parece totalmente entendible, pues hubo efectivamente un cambio de docente y con el ello también un cambio de dinámica. Varios alumnos venian con la expectativa de una materia más tradicional: asistir a clase, realizar un serie de trabajos prácticos y rendir un examen. En lugar de ello se encontraron con tareas semanales, muchas lecturas y varios entregables. Todo esto de forma constante a lo largo de todo el cuatrimestre. Y fue explícitamente así, pues a mi entender los proyectos se hacen día a día TODOS los días, de forma constante. Al mismo tiempo les pedí a los alumnos que dieran visibilidad constante y temprana, avisando cada vez que iban a faltar a clase o llegar tarde. Los alumnos que completaron la materia, comprendieron el objetivo de este pedido y reconocieron su importancia. La importancia no radica en avisar si faltan a la materia, sino en generar el hábito, hacer que los alumnos se acostumbren a dar visibilidad. En el contexto de toda actividad uno puede sufrir atrasos, imprevistos, etc, pero lo que NO puede hacer bajo ningún punto de vista es no dar visibilidad.

En fin, por ahora, esto es todo, más adelante comentaré algunas conclusiones de la retrospectiva.

Finalmente les dejo la foto de mi primera promoción de Ingeniería de Software, ¡felicitaciones estudiantes! (y gracias por aguantarme)

Y un día llegué a Ruby…y publiqué una gema

Y si, después de haber trabajado con Delphi, PHP, C#, Java, C/C++, Smalltalk y Python finalmente me tocó Ruby.

Recién estoy dando mis primeros pasos, no conozco bien la sintáxis y al mismo tiempo hay ciertos idioms que me resultan incómodos, pero más allá de eso he encontrado varias similitudes con Smalltalk que me han resultado muy amistosas.

A diferencia de muchos de los que se acercan a Ruby, no he hechado manos a Rails. Mi stack de desarrollo se compone de Sinatra+Datamapper+SimpleDB+Heroku. He aquí otro punto interesante, luego de trabajar con la plataforma Azure, Heroku me pareció extremadamente simple y sólido. La experiencia de usuario es muy….¿suave?, en inglés diria smooth, con lo cual creo que suave es una traducción aceptable.

La aplicación que estoy desarrollando tenia como requerimiento funcionar con identidad federada. Si bien en Southwoks ya teniamos un gema para resolver dicha cuestión, la misma corria sobre Ruby 1.8 y la idea era que mi aplicación corriera sobre 1.9 pues tiene varias mejoras interesantes. Asi que luego de un poco de investigación y algunas pruebas de concepto logré dar con un código que permite federar mi aplicación usando tokens del tipo SWT.

Y estaba tan entusiasmado que di un paso más y empaqueté dicho código en un gema (este es el nombre que se le da a las librerias reutilizables en Ruby). La gema está disponible en RubyGems y el código fuente en GitHub.

Próximamente más sobre mis aventuras en Ruby.

Encendí la luz y me encontré dos hobbits en el sillón…

¡Que buena frase para comenzar un libro! Lástima que estoy lejos de escribirlo. Por el momento sigo leyendo y en este post voy comentar algunos libros que leí durante este 2011.

Resulta que esta semana terminé de leer Juego de Tronos. Simplemente sin palabras, muy bueno. Tal vez hayan oído hablar de esta obra a partir de una serie de HBO que lleva el mismo nombre y que está basada en este libro. Yo me crucé con este libro al año pasado cuando estuve por Barcelona. Resulta que andaba buscando Leyendas de la Drangonlance (obra que no había podido conseguir en Argentina) y un amigo español me recomendó una librería donde podría conseguirlas. Efectivamente fue así, terrible librería, quedé deslumbrado con el tamaño y el tipo de obras que tenia. Me compré los 3 tomos de las leyendas y de paso le pregunté al vendedor que otro libro de estilo similar me podría recomendar. El vendedor me hizo tres recomendaciones:

  • Otros libros de la Dragonlance, que los descarté pues ya tenia bastante de Dragonlance y al mismo tiempo DiegoF me había dicho que con leer las Crónicas (que ya las había leido) y las Leyendas era suficiente, pues el resto era de otros autores y no tenia la misma calidad.
  • La saga del elfo oscuro, este me resultó muy interesante y estuve a punto de comprarlo, pero recordaba haberlo visto en Buenos Aires asi que no tenía sentido comprarlo allí.
  • Juego de Tronos, el titulo no prometía demasiado, pero la portada si, un hombre con una espada y un lobo. Eso sumado a la descripción del vendedor y el tamaño reducido de la edición de bolsillo, fueron suficiente para convencerme.

Así fue como llegué a Juego de Tronos, pero si bien el libro lo tengo desde Septiembre de 2010, recién lo empecé a leer cuando escuché el anuncio de la serie de HBO. Este libro es parte de una Saga y finalizar te deja a medio camino pues la historia no se resuelve. Por lo que estuve averiguando el siguiente libro de la saga (Choque de Reyes) llegará a Argentina para marzo de 2012.

Entre las otras obras que leí este año están (excluyendo aquellas relacionadas a mi profesión):

  • Fundación e Imperio y Segunda Fundación, ambos de la Trilogia de la Fundación, de Isaac Asimov, excelentes, llegué a esto por recomendación de ManuelT. Sin duda clásicos obligados de la ciencia ficción.
  • Leyendas de la Dragonlance (1 y 2), algo ya mencioné, muy buenas. Creo que es una lectura recomendada para todo aquel que le haya gustado la onda del Señor de los Anillos, pero temo que primero habría que Las Crónicas.

Resumiendo leí 5 libros, y me todos me han resultado muy buenos. Ayer comencé a leer el tercer y último libro de las leyendas.

En 1 mes les cuento que onda.

Sinatra Modular Applications with Ruby 1.9

Disclaimer: what I write here is something that is working for me, but I am not an expert, so I cannot declare this to be the best solution.

I am working on a small application that I know it will grow, so the traditional Sinatra application could be a mess when I have more than 10 routes.

So the strategy I have chosen is to create a base class called BaseController inheriting from Sinatra::Application, this base clase will handle global application settings.


#./base_controller.rb
require 'sinatra/base'

class BaseController < Sinatra::Base
  get '/' do
    'Home (base controller)'
  end
end

Then, I create one controller class for each application module, each of this controllers should inherit from my BaseController.

#/controllers/module1_controller.rb
require File.join(File.dirname(__FILE__),'..', 'base_controller.rb')

class Module1Controller < BaseController
  get '/' do
    'Module 1'
  end
end

Finally, in the config.ru file I define the base routes for each controller.

# config.ru
require './base_controller.rb'
require './controllers/module1_controller.rb'

map '/' do
  run BaseController
end

map '/module1' do
  run Module1Controller
end

Note: the code snippets above assume that the base_controller.rb and config.ru files are located in the root directory while every all controller files are located under «/controllers» directory.

You can download the source code from here.

(FIUBA + Pharo)++

El próximo lunes 19 de diciembre a las 17 hs. en el Laboratorio «E» del 4to. piso, el estudiante Diego Kogan presentará su Trabajo Profesional titulado “Herramienta de integración continua para sistemas desarrollados en Pharo”, que desarrollara  bajo la dirección del Ing. Guillermo Pantaleo.

El trabajo consiste en el desarrollo de una herramienta que da soporte a la práctica de integración continua para sistemas desarrollados en Pharo. Dicha herramienta esta desarrollada íntegramente en Pharo. La herramienta permite ejecutar un conjunto de tareas de verificación  de software sobre un proyecto Pharo, entre ellas:

  • Test.
  • Cobertura de Tests.
  • Inspecciones de Código.
  • Reportes de Builds.
  • Integración con Monticello (SCM para squeak/pharo).

En verdad suena interesante, porque si bien la práctica de integración contínua es común en Pharo, en general suele utilizarse Jenkins. Espero poder hacer un rato para asistir.

Censo Docente UBA (+1)

Hace un tiempo escribí sobre mi experiencia completando el censo docente de UBA. La buena noticia es que el mensaje que envié vía la página de visitas de la UBA, llegó a buen puerto y me contactaron vía mail. En el mail me daban algunas explicaciones y me pedían más detalles sobre los puntos flojos que yo mencionaba. Algo que me llamó la atención es que algo que yo veía como un issue, para los responsables del censo es en realidad un feature. Puntualmente estoy hablando del feature/issue que impide que uno regrese a modificar los datos ingresados en una sección del censo luego de haberla completado.

En fin, ayer me senté y contesté el mail, dando tantos detalles como recordaba (pues el sistema no me permite ingresar otra vez para analizarlo). Al mismo tiempo, para cada punto mencionado, intenté sugerir una posible solución y finalmente envié un link al material de usabilidad que vemos en algo3.

Más allá de las opiniones y de si tienen en cuenta mis comentarios o no, creo que lo importante es que dieron una respuesta a mi inquietud a pesar de que la misma fue enviada por un canal informal. Esto es algo que en instituciones tan grandes y burocráticas como UBA muchas veces es difícil.