Pharo: cortito y al pie

Desde hace dos semanas que vengo con días muy intensos y la cuestión no va a aflojar por al menos dos semanas más: corrección de trabajos prácticos y parciales de facultad, Agiles 2011, Codecamp y eventos familiares entre otras cosas. Pero a pesar de todo esto no quería dejar compartir un post que hizo Sven Van Caekenberghe en la lista de distribución de Pharo motivado por este otro post de  Marcus Kazmierczak.

El titulo del post fue “One Liners to Impress Your Friends” y estos son los items que me parecieron más copados de los que incluyó Sven.


"---  multiplicar cada item de una lista por 2 ---"

(1 to: 10) collect: [ :each | each * 2 ]

"--- Sumar una lista de numeros: 4 opciones distintas  ---"

(1 to: 1000) inject: 0 into: [ :sum :each | sum + each ]

(1 to: 1000) sum.

"--- Leer un archivo ---"

(FileStream fileNamed: 'data.txt') contentsOfEntireFile

"--- Feliz cumpleaños ---"

1 to: 4 do: [ :each | Transcript crShow: 'Happy Birthday ', (each = 3 ifTrue: [ 'dear Mr. President' ] ifFalse: [ 'to You' ]) ]

"--- Filtrar una lista de numero: 2 opciones ---"

#(49 58 76 82 88 90) groupedBy: [ :each | each > 60 ]

"---  Consumir un servicio XML o JSON ---"

XMLDOMParser parse: (ZnNeoClient new get: '<a href="http://search.twitter.com/search.atom?&q=pharoproject" target="_blank">http://search.twitter.com/<wbr>search.atom?&q=pharoproject</wbr></a>')

JSJsonParser parse: (ZnNeoClient new get: '<a href="http://search.twitter.com/search.json?&q=pharoproject" target="_blank">http://search.twitter.com/<wbr>search.json?&q=pharoproject</wbr></a>')

"---  Encontrar el mínimo/máximo en una lista ---"

#(14 35 -7 46 98) min

#(14 35 -7 46 98) max

That’s all folks.

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)

 

 

 

“Mis” libros (¡aramos dijo el mosquito!)

Hace unos dias me cruzé en la facultad con Juan Gabardini a quien le comenté que en Algoritmos 1 estabamos enseñando programación usando Python y con un libro que la propia cátedra escribio: Algoritmos y Programación 1 con Python. Quedé en pasarle el link, ya que el libro está publicado en la web en formato .pdf bajo licencia Creative Commons. El libro fue escrito por varios integrantes de la cátedra e impulsado principalmente por Marga. En lo que a mi respecta, mi aporte pasó por redactar el capítulo de excepciones, un tema que siempre me interesó, pues muchos programadores utilizan mal las excepciones.

Otro libro en el que hice mi aporte fue en Programación Orientada a Objetos: Diseño y programación, de Carlos Fontela. Resulta que Carlos fue uno de los revisores de mi tesis sobre programación orientada a aspectos y al escribir su libro le parecío interesante incluir un capítulo sobre aspectos. Asi que luego de hablarlo conmigo, Carlos basó su capitulo de aspectos en mi tesis y tuvo la gentileza de mencionar mi trabajo. Al mismo tiempo yo me encargué de revisar el capítulo y validar algunos ejemplos de código.

Por último, actualmente me encuentro participando en la traducción a castellano del libro Pharo By Example. La traducción está en curso y esperamos tener un primer borrado de la obra completa hacia mitad de año. En este momento tenemos 3 capítulos completamente traducidos, en estos dias voy a intentar publicarlos.

That’s all folks.

Buenas nuevas para la comunidad Pharo

En primer lugar tenemos el release de la versión 1.2.1, iupi!!!! La imagen core incluye 693 issues resueltos y entre los cambios mas relevantes se encuentran:

  • Agregado del nuevo framework de undo
  • Agregado del nuevo DummyUIManager para trabajar sin UI
  • Inclusión del preview de SimpleMorphic
  • Un nuevo finder
  • Integración con SUnit 4
  • Muchísimos cambios en la estructura de clases del sistemas que ofrecen mejor modularización

En particular este último punto me pone muy contento ya que colaboré en la detección e implementación de algunos de los cambios.

Por otro lado, Mariano finalmente se decidió a compartir su conocimiento escribiendo un blog. Como bien el propio Mariano indica en su post inicial, si sos un experto en Smalltalk, poco tal sea poco lo que puedas aprender. Pero si sos un simple usuario con ganas de aprender y compartir conocimiento, estoy seguro que el blog de Mariano te resultará muy entretenido. Para los interesados, el blog es: http://marianopeck.wordpress.com. Felicitaciones Mariano, ¡nos leemos!

Otro argumento por Pharo

Esta mañana estaba leyendo la lista de correo de Pharo y encontré un mail de Stef. Duccase sobre la visión de Pharo, transcribo algunos de los párrafos que me parecen importantes.

“Some days ago we were chatting with igor and he made an interesting remark about a kind of hidden philosophy
behind pharo: the idea that we systematically want to make the system better.
In fact I realized that what we are doing is to make a system nice, robust and powerful so that everybody can use
to realize their goals. But we want to have a system where not only smart guys can manage to do something with it but also less talented people…”

“…I want a system that let me learn from itself. I think that lot of things fall naturally in place from this vision (documentation, oo practices – not having car inheriting from wheel, tests comments, adequate abstractions, modularity). I want a system that everybody can nicely build his own software.
So in short I want pharo to be like a nice garden with greenhouses for building new garden with tools versus a jungle where only skilled adventurers can make it through.”

Totalmente de acuerdo. Y esto me lleva a pretuntarte: ¿sabes tu cual es la visión que tienen los createdores de tu lenguaje de desarrollo preferido?

¿Por qué Pharo?

A la hora de trabajar con Smalltalk uno debe elegir algún dialecto al igual que al trabajar con Java uno debe de elegir algún IDE. El tema con Smalltalk es que el dialecto es algo mucho más relevante que el IDE, pues en la mayoría de los casos el dialecto determina no solo el IDE a utilizar sino que además determina entre otras la máquina virtual en la cual se ejecutará nuestra aplicación. En la actualidad existe una interesente variedad de dialectos entre los que se destacan: VisualWorks, Visual Age, GNU-Smalltalk, Dolphin, Squeak y Pharo.

Mi elección personal es Pharo, y en los siguientes párrafos voy exponer mis motivos.

Licencia

Pharo es gratuito y de código abierto, en particular es desarrollado bajo licencia MIT, lo cual otorga una gran libertad.

Comunidad

Sin duda es una de las comunidades más activas y es definitivamente la más activa de las que participo. Por la lista del proyecto pasan más de 60 mails diarios. Para una herramienta de desarrollo (sea IDE, framework, compilador, etc) la comunidad es clave y más aún en el caso de iniciativas código abierto. Adicionalmente es una comunidad muy abierta, todo el mundo puede commitear fixes y todas la preguntas son contestadas en la lista de correo.

Experiencia de usuario

Comenzando por la super cool interface de usuario, el logo RE-copado y siguiendo por las infinitas posibilidades de personalización que ofrece, no conozco otro IDE tan “feliz para el programador” (es cierto, este argumento es muuyyyy subjetivo, pero no deja de ser un argumento).

¿y todo es color de rosa?

Bueno, casi. Hay algunas funcionalidades que por momentos se tornan un poquitin inestable, pero creo que se debe a todas las yerbas particulares que le he agregado a mi imagen.

¡¡¡Aguante Pharo!!!

Pharo sprint en INRIA Lille

Junto con MartinD fuimos los primeros en llegar alrededor de las 9. Junto con Stef y Marcus hicimos el setup inicial de la sala acomodando mesas, sillas y cables. El grueso de la gente arribó alrededor de las 10.

El objetivo del sprint era avanzar hacia el release 1.2. La dinámica fue simple, revisamos la lista de issues abiertos, hicimos una grilla en el pizarrón con 4 columnas: número de issue, team member atacándolo, fix ready, already integrated. Una vez hecha la lista, cada uno (o en pares) tomaba un issue para trabajar, al completarlo marcaba la columna fix ready,  lo cual le indicaba al integrador que el fix estaba en condiciones de agregarse al siguiente build. Una vez que el fix era integrado en el build, se marcaba la columna already integrated y con ello se daba por cerrado el issue.

A lo largo del día ataqué 3 issues, el primero de ellos fue un refactoring en Monticello, el segundo tuvo que ver con la ajustar Anymorph para funcionar en 1.2 y el tercero estuvo relacionado a la relación SystemDictionary<->SystemOrganizer. Para este último caso trabamos en conjunto con DamienP utilizando un enfoque TDD.

Muy cerca mio estaba sentado MarianoP, quien me mostró la imagen tuneada que creó para trabajar en su proyecto de doctorado (codename: Marea). Más allá de las herramientas adicionales agregadas a la imagen, Mariano modificó algunas cuestiones estéticas de la imagen que le pedí que compartiera. Sumando las modificaciones que me pasó Mariano y los fixes que apliqué sobre Anymorph, ajusté la gráfica de mi imagen, aquí les comparto un screenshot.

Para lograr esto, basta con seguir los 3 pasos que indico a continuación.

Paso 1: cargar una imagen de fondo:

World backgroundImage: (ImageReadWriter formFromFileNamed: ‘pharoBackground.png’) layout: #scaled.

Paso 2: cargar el logo de fiuba:

myImage :=  ImageReadWriter formFromFileNamed: ‘pharoBackground.png’.
myImage asMorph openInWorld

Paso 3: cargar Anymorph, esto es un poquitin más complejo, por eso los voy explicar en un post siguiente.

Aqui dejo algunas fotos que saqué durante sprint.

Enjoy it!