March 2013 - Posts
Gracias a la gente del MUG Argentina (http://www.mug.org.ar), dí una charla de dos horas sobre cómo es TDD, con un ejemplo en Visual Studio.
Desarrollamos algunos tests, cumpliendo con el ciclo rojo, verde, refactor, sobre una Factura con Productos y Cantidades. Pueden ver el código en:
https://github.com/ajlopez/TddOnTheRocks/tree/master/Ventas
Los commits, con la evolución paso a paso, están en
https://github.com/ajlopez/TddOnTheRocks/commits/master
Mencioné algunos posts en la charla. Son mis posts sobre TDD, pero destaqué:
Escribiendo un intérprete en .NET (Parte 10) donde van a ver un caso distinto y más extenso
TDD y Diseño de Implementación (1) donde voy a escribir sobre cómo queda simple el diseño de implementación usando TDD y la cabeza
TDD como Compilador para ver cómo TDD es el compilador de estos años: nos avisa cuando algo está mal, mucho mejor que los compiladores de lenguajes tipados
TDD y Base de Datos sobre alternativas de qué hacer cuando tenemos bases de datos en nuestros tests
TDD y Baby Steps sobre ¿cómo comerse un elefante? Pedacito a pedacito
TDD y el juego del Go sobre “el sistema está en buena forma” a cada momento, listo para abrazar el cambio y los próximos casos de uso.
TDD, Test Unitarios y Mocks sobre usar mocks solamente cuando es necesario.
TDD y Casos de Uso sobre cómo ir acompañando la implementación de casos de uso con TDD. Lean el post de “Uncle Bob” No DB
Escribiendo una Aplicación usando TDD (parte 5) sobre algunos pasos que se pueden dar con ASP.NET MVC
Para los que quieran ver cómo desarrollo partiendo de los controllers, en vez que desde el dominio de negocio, ver
Desarrollando una aplicación con TDD desde 0
donde por temas de tiempo, me salteé la evolución guiada por casos de uso. Pero ahí se ve cómo van surgiendo patrones, arquitectura, reparto de responsabilidades, pero PRIMERO LOS TESTS!
Para practicar, coleccioné algunos enlaces en:
http://delicious.com/ajlopez/tdd+codekata
Para aprender más:
https://delicious.com/ajlopez/tdd+tutorial
Para ejemplos en video:
https://delicious.com/ajlopez/tdd+video
Nos leemos!
Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez
Hoy paso a comentar dos entregables que se publicaron: una entrevista, y una charla como podcast.
El año pasado, el bueno de @santiagobasulto (desarrollador de software, emprendedor, programador Python, colaborador en proyectos de código abierto) tuvo la paciencia de hacerme una entrevista en persona, acá en Buenos Aires, tomándose el trabajo de viajar desde su La Plata en un día atareado. Estuvimos charlando como dos horas (en un bar histórico de la ciudad, donde se filmó la escena del billete y el mozo, de la película “Nueve Reinas”, les dejo como trabajo para el hogar averiguar cuál es). Justamente, ese bar tiene también algo que ver con la entrevista, porque he pasado por él varias veces en las décadas que llevo de programar.
Santiago la pasó en limpio, la pueden leer en:
http://charliedontcode.com/entrevistas/2012/08/12/entrevista-angel-java-lopez.html
Algo más de contexto, lo escribí hace algo más de cuatro años:
http://msmvps.com/blogs/lopez/archive/2008/12/31/treinta-a-241-os-en-desarrollo-de-software.aspx
Visiten el blog de Santiago:
http://charliedontcode.com/
Muy buena la escena de cine de donde toma el nombre (ya me imagino a @santiagobasulto cruzándose con Robert Duvall, acá en Buenos Aires, supongo que en otro bar histórico, La Biela ;-).
Y también tuve una charla, esta vez a distancia, con los buenos @roundcrisis @dvilchez, publicada hoy como podcast:
http://www.32minutos.net/?p=106
Ah! Pusieron una foto mía, debe ser la “clásica” ;-) (no me saco muchas fotos). Tratamos temas de desarrollo de software, algo de desarrollo ágil, insistí bastante sobre el tema TDD, también sobre generación de código como sistema experto, y “ver la luz”. Y hasta apareció algo de Anglish ;-).
Vean que han producido varios podcast en:
http://www.32minutos.net/
como el de Programación Funcional con el bueno de @martinsalias, o el de Node.js con @woloski, @jfroma y @theprogrammer. Hace unas semanas grabamos otro podcast, esta vez con Martin, para 32 minutos, y se conversó bastante sobre agilidad. Veremos si queda publicado en estos días. Estén atentos.
Les agradezco a los tres haberme permitido conversar y expresar algunas ideas, que pueden servir o no.
Pero lo bueno que están haciendo, es dejar entregables consumibles. Eso es importante. Internet (y la Web en particular) está permitiendo la generación de contenido y compartirlo con todos los interesados, de una forma accesible. Pienso que es una revolución tan grande como la de Gutenberg, y los primeros libros de Manuccio.
Nos leemos!
Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez
Gracias de nuevo a la gente del MUG (http://www.mug.org.ar ), en Abril voy a dar un curso de todo un día (arancelado) en Buenos Aires, ver:
http://www.mug.org.ar/Eventos/3876.aspx
Como vamos a ejecutar y practicar algún código, para aprovecharlo conviene venir con notebook. Se necesitaría tener conocimientos previos HTML y nociones de JavaScript. En la notebook propia instalar previamente: Node y Git.
El instalador de Node (para Windows y otros) está en http://nodejs.org/download/
Git se puede bajar de http://git-scm.com/
Lo que vamos a ejecutar puede usarse en Windows, Linux, Mac OS.
Lugar, horario y temas a tratar:
Jueves, 18 de Abril, 2013
Lugar: Auditorio del MUG, Rivadavia 1479, 1er Piso Oficina A. Ciudad de Buenos Aires
Horario de 09:00 a 18:00 hs.
Contenidos:
1. Introducción a Node.js
1.1. Programación Javascript desde Node sobre el motor V8
1.2. Entrada/Salida asincrónica
1.3. Módulos
1.4. Manejador de paquetes npm
1.5. Elementos de Test-Driven Development
2. Programación Web con Node.js
2.1. Módulo HTTP
2.2. Manejo asincrónico
2.3. Frameworks web con middleware
2.4. Framework MVC: Express
2.5. Acceso a Base de datos
3. Socket.IO
3.1. Comunicación con el browser
3.2. WebSockets y alternativas
3.3. Ejemplo multiusuario en tiempo real
3.4. Usando HTML5 y canvas
3.5. Chat simple
3.6. Juego simple
3.7. Ejemplo distribuido: varios servidores, varios clientes
Es un temario ambicioso. Al principio, veremos algunos temas básicos en detalle, y luego ya iremos más rápido, para tener experiencia concreta de qué aplicaciones pueden hacerse en Node.js. De ahí la inclusión de Socket.IO para soporte de tiempo real y múltiples clientes. Como no podía faltar, veremos algo de TDD, aunque algo mínimo para poder aprovechar el tiempo con el resto de los temas.
JavaScript es muy flexible, y combinado con Node.js y su gran ecosistema, es muy poderoso. Como otras veces (tres jornadas anteriores, en Cuenca (Ecuador), Buenos Aires y Rosario), el material visitado será publicado en este blog.
Nos leemos!
Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez
Cuando investigo un tema, voy anotando qué recursos he utilizado, ya sea libros, notas, enlaces, etc. Es algo que he tomado como hábito, luego de adaptar una recomendación de Clifford Stoll en su libro The Cuckoo’s Egg: llevar una libreta (notebook) con lo que se hace (algo que Stoll recibió del premio nobel Alvarez). Cuando es algo que está público en Internet, desde hace años uso mi cuenta de Delicious para ir anotando esa información:
https://delicious.com/ajlopez
Y sí, también mantengo libretas (de papel) con notas, ideas y lo que fui haciendo para resolver algo.
Cada tanto voy publicado en mi blog en inglés (o en Anglish) lo que me pareció interesante compartir. Siempre pueden entrar en:
http://ajlopez.wordpress.com/category/links
Los temas que más me han importado en estos años:
Test-Driven Development
Artificial Intelligence
Node.js
CQRS
Distributed Computing
Bioinformatics
Smalltalk
Python
COBOL
Game Development
Genetic Algorithms
Socket.IO
Express
MongoDB
y mil temas más.
Aprovecho este post de recuerdo, para agregar otros posts con links de temas que no son de desarrollo de software, pero que pueden interesar:
Teoría de Categorías
Gauss
Fermat
Topología
Teoría de Números
Teoría de Grupos
Geometría
Astronomía
Historia de las Matemáticas
Matemáticas
Cálculo
Teoría de Cuerdas
Richard Feynman
y de nuevo, mil temas más.
Tantos temas interesantes, una sola vida 
Nos leemos!
Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez
Hace una semana moví mi proyecto de generación de código AjGenesis (la versión .NET) desde Codeplex a GitHub. El sitio de Codeplex tiene una nueva versión publicada AjGenesis 0.6 (no lo puse en GitHub porque hace un tiempo removieron de ahí la posibilidad de tener downloads de binarios). Recuerden que es un proyecto de código abierto, así que aparte de bajarse los binarios se bajan el código correspodiente. Si no conocen AjGenesis, pueden leer mis posts sobre el tema.
La nueva versión es el compilado del trunk de Codeplex. Tiene pequeñas correcciones y alguna mejora, y ha sido usado en proyectos reales. Hasta parece que lo han usado para generar código para Ruby On Rails, pero nadie del proyecto ha publicado un post todavía así que no tengo evidencia para mostrarles.
Es tiempo de pensar la próxima versión. Algunas ideas a implementar, como “roadmap” tentativo:
- Refactorizar los tests, para usar las tools de Visual Studio
- Reescribir AjGenesis Web Studio, en ASP.MVC 3, using C#, Razor, and Bootstrap 2.0
- Un nuevo programa principal de consola, renombrado a ajgen (en vez del actual, AjGenesis.Console, un nombre largo para estos tiempos ;-).
- Soporte de comandos en repositorios. Esto es (algo está implementado en la versión actual, pero es “Work in Progress”), poder usar un nombre/verbo cuando se lanza el programa principal de consola, por ejemplo:
ajgen generate <parameters>
ajgen newentity <parameters>
La forma general es
ajgen <verb> <parameters>
Los verbos estarán definidos en repositorios, y cualquiera podrá escribir nuevos comandos (en principio, serán tareas usuales de AjGenesis). De esta manera, podría soportar generación de código de una forma más fácil y extensible: en vez de especificar archivos específicos de tareas y modelos, éstos podrían ser ubicados en lugares definidos. En las versiones anteriores, yo estuve reluctante a agregar eso, búsqueda automática de tareas: preferí lo explícito a lo implícito. Pero luego de ver cómo se maneja la generación de código en frameworks como Ruby on Rails, Django, Express, me gustaría explorar esta forma.
La manera usual
ajgen <task or model files>
seguirá soportada como siempre, sin cambios. Sólo si el primer parámetro es un nombre, se lo tomará como verbo y se buscará la tarea asociada.
Algunos objetivos para más adelante:
- Soporte de JSON para escribir modelos
- AjSharp/AjBasic como lenguajes de scripting. Ahora, AjBasic está acoplado, interno al proyecto AjGenesis
Ah! Y no se olviden que hay nuevas versiones de AjGenesis: AjGenesisNode implementado en JavaScript usando Node.js, y AjGenesisRuby usando Ruby.
Nos leemos!
Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez
Anteriores posts de la serie:
Escribiendo un Intérprete en .NET (Parte 9)
Escribiendo un Intérprete en .NET (Parte 8)
Escribiendo un Intérprete en .NET (Parte 7)
Escribiendo un Intérprete en .NET (Parte 6)
Escribiendo un Intérprete en .NET (Parte 5)
Escribiendo un Intérprete en .NET (Parte 4)
Escribiendo un Intérprete en .NET (Parte 3)
Escribiendo un Intérprete en .NET (Parte 2)
Escribiendo un Intérprete en .NET (Parte 1)
Hace unos meses que no escribo en esta serie, pero es porque he directamente escrito varios intérpretes, usando TDD, y haciendo “commits” prácticamente por tests en mi cuenta de GitHub, siguiendo las ideas de esos posts.
Intérpretes que estoy escribiendo, parecidos al descripto en los posts, son:
PythonSharp (ver los commits) (lo presenté en la PyCon Argentina 2012)
RubySharp (ver los commits)
Y para un ejemplo de un lenguaje diferente, vean una implementación de Clojure que estoy escribiendo en C#:
ClojSharp
Por ejemplo, hoy escribi un nuevo verbo de ClojSharp, la que se llama “let special form”, tienen los commits por tests de hoy:
https://github.com/ajlopez/ClojSharp/commits/master
Pueden ver uno en:
https://github.com/ajlopez/ClojSharp/commit/51c678ece96d6d1cef92f36afda8d8fc711ffd8c
donde GitHub nos muestra los cambios en el código.
Otro ejemplo, lo que hice ayer, test por test, en RubySharp:
https://github.com/ajlopez/RubySharp/commits/master
Espero que estos ejemplos les sirvan para ir viendo cómo se puede usar TDD para este tipo de proyectos. Tengo más ejemplos de otros tipos de aplicaciones en mis posts de TDD.
Nos leemos!
Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez
Gracias al MUG Argentina podré dar en unos días una gratuita charla sobre TDD con Visual Studio:
Introducción a TDD con Visual Studio
Martes 26 de Marzo
Lugar: Auditorio del MUG, Rivadavia 1479 1er Piso, Buenos Aires.
Horario: 18:30 a 20:30 hs.
Describiremos brevemente lo que es y no es Test-Driven Development, pasando luego a escribir código.
Armaremos un dominio simple, usando TDD, y el ciclo de: test, rojo, verde, refactor. Veremos como entonces va “creciendo” nuestro código de manera orgánica, consiguiendo un diseño adecuado a lo que se necesita.
Los tests nos guían en la construcción del software, siendo más que tests, especificaciones, ejemplos de uso esperado del software en construcción y hasta conseguimos ser más productivos y con código mantenible, evitando la sobre-ingeniería, y arquitecturas complicadas.
Es gratuito, pero hay que registrase aquí.
Ya saben que TDD es uno de mis temas favoritos. Pero ¿por qué? Porque es la disciplina de programación que pone en marco y contexto todas las demás. Si saben SOLID, patrones y “tutti li fiocci” pero no hacen TDD, será hacer lo bueno, pero no lo correcto. Será como alinear las sillas en la cubierta del Titanic ;-)
No quiero aburrirlos más, ya escribí bastante en mis posts sobre TDD. Y cada día publico código que sigue TDD en mi cuenta de GitHub.
Nos leemos!
Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez
En la última década, al menos tres veces me topé con esta situación: una empresa, que desarrolla software, tiene un sistema “estrella”, desarrollado digamos en los noventa, con una amplia base de clientes. Es un programa que se ejecuta en una red local, con clientes Windows. Tuvo una versión 1.x, y con su éxito, hasta una versión 2.x mejorada. Pueden imaginarse:
- Un sistema contable
- Un sistema de stock
- Un sistema de manejo de personal
- etc…
Pero quiere actualizarlo, y tener una nueva versión, acorde a los nuevos tiempos del tercer milenio.
Se necesita:
- Tener la posibilidad de brindar el servicio como “Software as a Service”, via Internet/Web
- Tener la posibilidad de tener un sistema “on premise”
- Contar con programas clientes ubicuos, desde programas desktop de una plataforma (Linux, BSD, *nix, Windows, Mac, Androir, mobile, etc…)
- Brindar lo mismo que la versión “normal”, o más
- Permitir la evolución (que no pase como con el sistema inicial de los noventa, donde todo anduvo bien, pero que quedó en el tiempo, sin soporte de tecnología, herramientas, etc..)
- Se está en libertad de elegir la tecnología, el equipo y el proceso de desarrollo.
¿Cómo atacar esta construcción de la versión 3.x?
Bien, esta es la presentación del problema. Comentaré algunas soluciones, caminos a explorar en los próximos posts.
Nos leemos!
Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez
Sirva el post de hoy como introducción a un gran tema, que seguramente no podré comentar completamente. Es el tema de la relación entre TDD (Test-Driven Development) y diseño de implementación (no de interfaz o experiencia de usuario, digamos, diseño del código y su arquitectura).
Comienzo con una pregunta:
¿Qué esperamos de un sistema o aplicación?
Lo primero que se me ocurre, es que funcione bien. Imaginemos que estamos usando un procesador de texto, y cuando guardamos el documento se graba nada más que la mitad y lo demás se pierde. No será lo que esperamos. A esta altura de la historia del software, esperamos que una aplicación funcione bien, sin ese tipo de problemas. Yendo más específico, debería:
- Brindar la salida esperada, ante una entrada esperada
- Reaccionar de forma adecuada, ante una entrada no esperada
- Reaccionar de forma adecuada ante una falla en el entorno (por ejemplo, pérdida de conexión con la base de datos)
Seguramente se les ocurriran más puntos de este estilo.
Ahora bien, me puedo imaginar una aplicación así, y que no esté bien diseñada. Muchos de nosotros recordamos (y aún puede ser que tengamos) aplicaciones Visual Fox, o Visual Basic clásico, donde todo está escrito en el botón de aceptar. Conozco aplicaciones así, que funcionan según lo esperado. Y los clientes y usuarios están contentos.
Pero muéstrenme un ejemplo de una aplicación exitosa así, y casi seguro que los creadores de ese sistema tuvieron que lidiar bastante en sacar nuevas versiones, y todavía están viendo cómo migrarlas a la web y dispositivos móviles, impulsados por lo que la gente y el mercado espera hoy.
Entonces ¿qué esperamos de un buen diseño de implementación? No sé ustedes, pero yo espero que el diseño de implementación (el código, su funcionalidad interna, su distribución, su arquitectura) sea simple. ¿Por qué? Porque es la cualidad más importante para conseguir que sea mantenible.
Si un sistema exitoso no necesitara cambios, no buscaríamos mantenibilidad. Pero si un sistema es exitoso, casi seguro que sobrevivirá en el tiempo, y como la realidad cambia, habrá que actualizarlo. Un contraejemplo: si conseguimos escribir un sistema que nos dé el número ganador de la próxima gran lotería en EE.UU. y de sólo esa lotería, con un grandísimo premio, el cliente final no se va a preocupar por la mantenibilidad o nos va a pedir actualizaciones. Pero en general, los sistemas y aplicaciones exitosos necesitan evolucionar.
Por supuesto, podemos conseguir sistemas y aplicaciones exitosos programando sin buen diseño, por ejemplo, para llegar primeros a un mercado. Algunas de las aplicaciones Visual Fox que mencionaba antes, al salir rápidamente, consiguieron que la empresa creadora pudiera llegar primero a un nicho de mercado, y eso fue más importante que el tener un buen diseño desde el comienzo. Luego, se pudo pagar la deuda técnica en la versión 2.x con todo el ingreso y el posicionamiento que se consiguión en la versión 1.x.
Entonces, volviendo a la mantenibilidad, ¿por qué pido que la implementación sea simple? Porque será entonces
- más entendible para quien quiera que venga (individuo o equipo) a escribir la versión 2.0
- tendrá menos piezas, y cada modificación se podrá encarar tocando pocas de esas piezas a la vez
Por añadidura, una aplicación internamente simple, se verá expuesta a menos fallas de las piezas (en general) por tener menos puntos de posibles problemas en ejecución. No es lo mismo tener una aplicación que actualice una sola base de datos, que otra que tenga que actualizar 10 bases de datos distribuidas y heterogéneas.
Hay quien pedirá: no, yo no quiero que el diseño sea simple, sino flexible. Acá llegamos a un punto crucial, para lo que quiero tratar y todavía no apareció: desarrollar con TDD.
Bien, bastante por hoy, veré de escribir en próximos posts:
- Lo simple vs lo flexible
- Cómo TDD promueve lo simple
- Cómo TDD nos ayuda a conseguir lo “flexible” por añadidura y sin gran esfuerzo
- Cómo TDD nos da una mano para conseguir lo primero que mencioné: que la aplicación funcione como esperamos
- Cómo un buen diseñador puede diseñar “mejor” con TDD, y además cómo eso beneficia a quien quiera que venga a mantener el sistema
Vean que pongo “TDD promueve”, “TDD nos ayuda”, porque TDD solo no hace nada. Hay que poner cabeza. Pero desde hace unos años veo que TDD + Cabeza, nos da un sistema mejor que sólo aplicar Cabeza, es decir, sólo con nuestros conocimientos y destrezas.
Nos leemos!
Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez
Esta semana viene movida en el tema de reuniones para programadores. En primer lugar, la gente de Ruby Argentina vuelve al ruedo luego de un merecido descanso de verano, y luego de la Ruby Conf 2012. Como se habían planteado desde el año pasado, hacen un meetup el primer miércoles de cada mes. Se anunció la lista RubySur:
https://groups.google.com/group/rubysur/browse_thread/thread/2c27490fc752a41b#
vamos a hacer el primer meetup de 2013 en las oficinas de SCV Soft.
Para participar, les pedimos que completen el siguiente formulario: http://goo.gl/jOoIv
Quienes quieran proponer una charla, pueden hacerlo mediante el mismo formulario.
Cuando?
Miércoles 6 de marzo de 2013 a las 19:00 hs.
Donde?
Oficinas de SCV Soft
Nicolás Repetto 1841, Ciudad Aut. de Buenos Aires
(mapa: http://goo.gl/maps/EiZT4)
Para conocer la lista de personas anotadas: http://goo.gl/nN1Rr
Por otro lado, el mismo día (!) la gente de Python Argentina PyAr se reúne:
http://python.org.ar/pyar/Eventos/Reuniones/2013/Reunion59
http://listas.python.org.ar/pipermail/pyar/2013-March/023406.html
Reunión 59 - Miércoles 6 de Marzo de 2013 - Buenos Aires, Post Street Bar - 19hs
Temario
-
PyCon 2013
-
PyCamp 2013
-
Manejo de dinero en PyAr
- Mentores de charlas
- Raspberry Pi
-
Sitio de PyAr
- Capacitación introductoria a python
- ¿...?
Fecha y Hora
- Miércoles 6 de Marzo de 2013, 19 hs
Lugar
Post Street Bar, en la terraza
Y para el viernes tenemos la frutilla de la torta, Node.js sobre Raspberry Pi, por la gente de Node.js Argentina:
http://www.meetup.com/NodeJS-Argentina/events/105375852/
Usando Node.js y MongoDB en RaspBerryPI
La idea es instalar Node.js y MongoDB (en cluster) en varias Raspberry Pi.
Bueno, tenemos de todo esta semana. Tendría que comentar también sobre una meetup a la que asistí, de desarrolladores y usuarios de Salesforce, en Buenos Aires. Pero queda para otro posts.
Nos leemos!
Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez
Primero, una revisión de las de Febrero:
- Comenzar SimpleDatabase [completo] ver repo
- Actualizar SimplePermissions [pendiente] ver repo un ejemplo de roles, sujetos, permisos con modelo en memoria
- Actualizar SimpleStorm (implements ack, maybe integrate with MultiNodes) [pendiente] ver repo por ahora el proyecto con más estrellas en mi GitHub
- Actualizar SimpleMapReduce [completo] ver repo
- Actualizar SimpleKeeper, con líder [completo] ver repo falta ejemplo distribuido
- Actualizar AjFabriqNode, integrarlo con el nuevo SimpleMessages, posiblemente agregarle MultiNodes [pendiente] ver repo
- Actualizar MultiNodes [completo] ver repo
- Actualizar AjGenesisNode, para tener un comando global y tareas [pendiente] ver repo me gustaría actualizarlo
- Dar un curso de un todo un día sobre Node.js [completo] ver post
Adicionalmente, estuve trabajando en:
- Update Inmob [completo] ver repo
- Update AjConsorSite [completo] ver repo
- Update AjGroupsJs [completo] ver repo
- Update SimpleBoard [completo] ver repo
- Update SimpleChess [completo] ver repo
- Update SimpleGo [completo] ver repo
- Update NodeSamples [completo] ver repo
Mis resoluciones para este Marzo:
- Comenzar ClojSharp
- Comenzar NodeAima
- Actualizar AjGenesisRb (¿podré hacerlo una gema?)
- Comenzar RubySharp
- Actualizar SimpleGo
- Actualizar SimpleChess
- Actualizar Inmob
- Actualizar AjConsorSite
Más trabajo, pero también diversión ;-)
Nos leemos!
Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez