Categoría: technology

Coursera: Curso de Android, Semana #1

Acabo de completar la primer semana de este curso. Me llevó unas 4 horas de estudio entre videos, cuestionarios, tareas de programación y configuración/troubleshooting de las herramientas de desarrollo.

Por ahora viene bastante tranquilo, lo cual es lógico para ser la primer semana, pero pinta realmente muy interesante.

Si quieren aprender Android, creo que aún estan a tiempo de sumarse al curso.

Continuará…

 

Javascript tests running on Jenkins

Nowadays, no matter what technology you use to build your web application, it is almost sure you will need to write some JavaScript code. At the same Javascript script code is not only used to animate the web pages, it is also used to handle validations and application flow. Because of this, everyday is more needed to write unit tests for the Javascript code.

There are several unit testing frameworks for Javascript. In my case I choose Qunit, that is testing framework developed by the jQuery guys.

Of course that in order to be able to write unit tests for your code, you will need to follow some design guidelines, but that is part of another post. Let’s suppose you followed that guidelines and now you want to write some test, these are the steps you should follow to run your tests:

  1. Download qunit.js
  2. Download qunit.css
  3. Write your tests in a javascript file
  4. Create a html page referencing the 3 previous files

With these 4 steps you are almost done, open the html file and you will have your tests executed.

What is missing, is how to run these tests in the build server. The interesting point here is that to run Javascript t tests we need a Javascript engine. In a develop machine, it is not a problem, you can use your browser, but in the build server is not so easy. The approach I took was to use PhantomJS, a tool that among other things, can run Javascript without needing a browser.

So using PhantomJS and MSbuild I was able to have my Jenkins running my Javascript tests.

Here you can download a running example.

ASP.NET: WebForms and MVC Side by Side

This is the situation I am facing:

I have a WebForms application that has been running for years. It was initially built with VS2008 (net 3), then was updated to VS2010 (net 4) and was recently updated to VS2012 (net 4.5).

The client has decided to redesign the UI of some pages. He hired a group of designers that produced a very cool set of new pages based on HTML5 and CSS. Now I need to take that HTML and CSS and adjust the webforms application. As you can imagine this can be a really hard work, because among other things, the webforms application uses several non-standart asp.net webcontrols.

So, what I would like to do is to implement these new pages using ASP.NET MVC. I did some googling and it seems it is possible to have WebForms and MVC living side by side in the same application. But before going further I would like to hear some opinions.

La explicación del porqué estoy codeando un Applet

¿Acaso pensabas que con HTML5 y el ascenso de Javascript podrías deshacerte de los applets y los ActiveX? Pues aún no es posible. Aunque cueste creerlo hay ciertas cuestiones que aún hoy se encuentran fuera del alcance de HTML5 y JavaScript. Les cuento el caso de un proyecto en el que estoy trabajando y para el cual tuve que desarrollar un applet.

Resulta que un sistema en el que estoy trabajando es una aplicación web en la que algunos usuarios deben cargar información sensible. Por esto se ha definido que cuando un usuario cargue esta información sensible, la mista deberá ser firmada. Para esto cada usuario cuenta con un token. Cuando digo token me refiero a un dispositivo físico que almacena certificados y que permite que los mismo sean utilizados para distintas cuestiones. Físicamente estos tokens son como llaves USB. Por razones de seguridad, no es posible acceder directamente a los certificados del token, sino que el acceso debe hacerse mediante un driver particular que provee el fabricante del token. Entonces nos encontramos con una página web cuya información debe ser firmada y para generar la firma resulta necesario interactuar con el driver del token. Hoy en día aún no es posible hacer esto (interactuar con un token) con HTML5/JavaScript desde un browser y la solución que nos resultó más razonable fue usar un applet. Puede que el applet parezca algo feo, pero sin duda es mucho mejor que usar componente ActiveX que sólo correría en Windows.

En próximos post compartiré algunas cuestiones que he ido aprendiendo durante la construcción de este applet.

Primeros pasos con Windows 8 y Visual Studio 2012

Apenas apereció el primer el preview de Windows 8 hace ya un par de meses, lo instalé en una máquina virtual, le di una mirada muy superficial y nunca más lo usé.

Hace un par de semanas comencé a trabajar en un nuevo proyecto en Southworks y tuve que volver a instalarlo. En esta ocasión no utilicé una máquina virtual tradicional, sino que seguí un procedimiento mixto que consiste en crear un disco virtual (vhd), bootear la maquína con un pendrive con Windows 8 es hacer la instalación en el disco virtual. El proceso de instalación se encarga de setear un nuevo bootloader que permite elegir qué sistema iniciar cuando bootea la máquina: Windows8 (instalado dentro del vhd) u otro sistema instalado en el disco fisico. El detalle del procedimiento que utilicé, está documento en este post de Scott Hanselman. Una vez completa la instalación de Windows 8, procedí a la instalación de Visual Studio 2012, la cual resultó muy más rápida de lo que esperaba.

Sinceramente no estaba al tanto de las novedades de ninguno de los dos productos, con lo cual todo me está resultando nuevo. Respecto a Windows8 destaco:

  • Un cambio importante en la interface de usuario, da la impresión que ha sido diseñada para ser utilizada con dispositivos táctiles.
  • Viene con soporte nativo para montar imágenes ISO.

Respecto de Visual Studio 2012 destaco:

  • Importantes cambios a nivel visual: renovación total de íconos y nueva estética
  • Nuevos tipos de proyectos y nuevas funcionalidades acordes a la evolución del .Net Frameworks
  • Mejoras en el soporte de refactoring

Instalación de Ruby (la posta para mi)

En los últimos meses instalé Ruby en al menos 4 máquinas distintas (mi máquina personal, mi desktop del trabajo, una máquina virtual y mi build server). En todos los casos intenté seguir el mismo procedimiento, pero en todos me encontré con distintos issues, estimo que debido a que los ambientes eran levemente distintos (pero todos eran Ubuntu).

Cuando hablo de instalación de Ruby, no estoy hablando de la instalación base de ruby para hacer un “Hola  mundo”, sino una instalación como para crear una aplicación “de verdad” (básicamente aplicación web, con conexión a internet, manejo de xml, pruebas y build automatizado).

Habiendo seteado el contexto paso a describir los pasos comunes que logré identificar en todas las instalación que realicé y que voy a seguir la próxima vez que tenga que preparar un ambiente.

Vamos a comenzar por instalar Ruby usando apt-get, no importa si luego queremos utilizar otra versión, yo me inclino por comenzar instalando ruby con apt-get pues eso se encargará de hacer varios seteos. Entonces abrimos una terminal y ejecutamos

sudo apt-get install ruby

Si no tenemos instalado Git aún, es un buen momento para instalarlo.

sudo apt-get install git

Luego vamos a instalar Ruby Version Manager (rvm). Esta herramienta nos va permitir instalar y administrar distintas versiones de Ruby en una misma máquina. Pero para instalar RVM primero tendremos que instalar git y curl, entonces:

sudo apt-get install curl
bash -s stable < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer )
echo '[[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm" # Load RVM function' >> ~/.bashrc

Cuando finalice la instalación de estos componentes cerramos la terminal.

Ahora instalaremos ruby 1.9.2 usando RVM, para ello abrimos una nueva terminal y ejecutamos

rvm install 1.9.2

El siguiente paso es installar RubyGem, un administrador de paquetes (que en ruby se llaman gemas). La instalación de esta herramienta consisten en descargar el paquete desde http://rubygems.org/pages/download , descomprimirlo y ejecutar setup.rb (ruby setup.rb). Con esto ya estamos en condiciones de comenzar a installar gemas, pero resulta que algunas gemas en su proceso de instalación incluyen un proceso de compilación de código C, el cual puede requerir de la existencia de ciertas librerías nativas en nuestro ambiente. Por suerte las mismas pueden instalarse fácilmente utilizando apt-get.

sudo apt-get install libmysqlclient-dev libpq-dev libsqlite3-dev zlib1g-dev libreadline5-dev libssl-dev libxml2-dev libopenssl-ruby libxslt1-dev

Ahora  si, podemos proceder a la instalación de dos gemas fundamentales: rake (ruby make) y bundler (un administrador de dependencias en un punto similar a Maven).

gem install rake
gem install bundler

Con esto estamos listos para comenzar, cuando creemos nuestras aplicaciones tendremos un archivo llamado Gemfile en el cual especificaremos las dependencias de nuestra aplicación (las gemas) y con solo ejecutar bundle install, bundler se encargará de instalar las gemas especificadas.

Espero que esto les resulte útil.

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á…

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.

Variables de clase y de instancia en Smalltalk

Este tema incluye algunas particularidades que me parece en general no se le presta mucha atención y por ello hoy quiero dedicarle un par de líneas.

Analicemos la definición de clase CuentaBancaria:

Object subclass: #CuentaBancaria
	instanceVariableNames: 'numero saldo'
	classVariableNames: 'SiguienteNumero'
	poolDictionaries: ''
	category: 'algo3-ejemplos'

instanceVariableNames, indica las variables de instancia, también conocidas como atributos de instancia. En Smalltalk, estas variables tienen visibilidad protegida aunque en general se las trata como si fueran privadas. En este caso tenemos las variables de instancia numero y saldo. Un detalle interesante es que las variables son protegidas de las instancia, ¿que significa esto? supongamos que tengo dos instancias de la clase CuentaBancaria: cuenta1 y cuenta2, entonces cuenta1 no puede acceder al atributo numero de la cuenta cuenta2, pues si bien cuenta2 es una instancia del mismo tiempo, resulta que otra instancia y aqui la protección es a nivel de instancias.

classVariableNames, como su nombre sugiere son variables de clase, lo cual significa que son accesibles por el objeto clase, pero al mismo tiempo también son accesibles y compartidas por todas las instancias de la clase, o sea, si una instacia modifica el valor de dicha variable, dicho cambio afecta a todas las instancias. En este caso tenemos tenemos el siguienteNumeroDisponible como variable de clase, la cual es incrementada por cada instancia cada es inicializada.

initialize
	saldo := 0.
	numero := siguienteNumero.
	siguienteNumero := siguienteNumero + 1.

Un punto importante para considerar es que esta variable también es accesible por la clase CuentaBancanria.

Por otro lado, si vamos a la definición de la clase CuentaBancaria y vemos la parte de clase, veremos.

CuentaBancaria class
	instanceVariableNames: 'MaximoNumero'

instanceVariablesNames, en este caso representa las variables exclusivas del objeto clase y como tales son accesibles por la clase, pero no por las instancias de  la clase. Un detalle interesante respecto de estas variables es donde inicializarlas. Bien, en general se suele agregar un método de clase que se encarga de inicializarlas, pero ojo este seria un método de clase.

Bien, por último, si volvemos a la definición de la clase CuentaBancaria, veremos que aún nos queda por mencionar los poolDictionaries. Estas variables son variables compartidas por instancias de distintas clases.  Es algo relativamente raro (al menos a mi parecer) y por eso es que no se ocurre como utilizarlas en el ejemplo, pero prometo escribir otro post al respecto.

Para finalizar les ofrezco un gráfico para intentar resumir el ejemplo.

(gracias Mariano por la correción)

 

 

 

Proyecto Seed (tercera parte)

En el post anterior nos habíamos quedado en: ¿que es lo mínimo que debemos poner dentro de la una imagen?

La respuesta depende de qué querramos hacer con la imagen. Básicamente podriamos decir que hay dos fines posibles:

- Cargar la imagen y trabajar creando instancias de las clases existentes, SIN agregar nuevas clases ni modificar las existentes.

- Idem caso anterior pero agregando capacidades para que la imagen pueda evolucionar incorporando nuevas clases. Para este caso es hay varias alternativas todas ellas partiendo del caso anterior y agregando por ejemplo un Compilador o algún componente capaz de cargar código binario (hay gente del equipo RMoD trabajando en esta última alternativa).

Casualmente esta mañana tuvimos una reunión en la que reorientamos nuestro enfoque y en este momento el plan es comenzar trabajando con el kernel definido por Pavel, analizarlo con algunas herramientas de análisis componentes y en base a eso identificar concretamente los cambios a realizar en cuanto a la estructura de paquetes y dependencias. El resultado de este análisis será un conjunto de backlog items para la una futura versión de Pharo (tentativamente la 1.2).

Bien, con este último post de esta serie de 3 doy por terminada la explicación de lo que intentamos hacer con el Proyecto Seed. En futuros post iré compartiendo los avances que tengamos.

Espero que se haya entendido.