<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://msmvps.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Angel "Java" Lopez</title><link>http://msmvps.com/blogs/lopez/default.aspx</link><description>NET, Java, PHP y Desarrollo de Software</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP2 (Build: 40407.4157)</generator><item><title>Un Buen Proyecto (1)</title><link>http://msmvps.com/blogs/lopez/archive/2013/05/16/un-buen-proyecto-1.aspx</link><pubDate>Thu, 16 May 2013 10:41:13 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1830380</guid><dc:creator>lopez</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1830380</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2013/05/16/un-buen-proyecto-1.aspx#comments</comments><description>&lt;p&gt;En mis charlas de TDD (Test-Driven Development) comento algunas características de lo que tendría que ser un proyecto bien terminado. Algo ya comenté en &lt;a href="http://msmvps.com/blogs/lopez/archive/2013/03/08/tdd-y-dise-241-o-de-implementaci-243-n-1.aspx"&gt;TDD y Diseño de Implementación (1)&lt;/a&gt;. Hoy quiero escribir (es decir, pasar en limpio, compartir, explicar un tema para ver si lo entiendo) sobre un tema más amplio: lo que considero un buen proyecto. Pensé inicialmente que bastaría un solo post, pero nones: éste va a ser el primero, y luego seguiré escribiendo.&lt;/p&gt;  &lt;p&gt;Pongo algo de contexto. Voy a escribir sobre un proyecto:&lt;/p&gt;  &lt;p&gt;- Profesional&lt;/p&gt;  &lt;p&gt;- Con desarrollo ágil en equipo, con iteractiones, backlog, etc..&lt;/p&gt;  &lt;p&gt;- Cliente externo, con un representante&lt;/p&gt;  &lt;p&gt;- Para ejecutar en producción&lt;/p&gt;  &lt;p&gt;Es decir, no necesariamente tiene que ser de código abierto (en mi caso en general no es), no es algo que armamos en nuestro tiempo libre (no, es un proyecto de nuestro trabajo de desarrollo de software), no es una demo, va a estar en producción y tendrá un ciclo de vida (no necesariamente apoyado por nosotros: el proyecto tiene una terminación y una entrega final). Igual admito que es difícil abarcar todos los proyectos profesionales. Pero creo que con lo que voy a describir varios proyectos serán incluidos en esta exposición.&lt;/p&gt;  &lt;p&gt;Entonces, en este marco, ¿cuáles son las características que tendría que tener un proyecto terminado para que digamos: “es un buen proyecto”? En el sentido de sentir y pensar que lo que entregamos es bueno. Claro, depende de bueno ¿para quién? Como estamos en un proyecto profesional, lo principal es que sea bueno para el cliente (empresa) que nos contrata. Puede ser bueno para nosotros (“uy, aprendí un montón de MVC”), para el equipo (“nos integramos y conocimos”), para nuestra consultora (“uy, con lo que ganamos podemos comprar nuevas oficinas”, o “ahora podemos ser conocidos por haber trabajado en este gran proyecto”), para el mundo (“ahora hay un nuevo framework que todos podrían usar para ser más productivos, etc… “). Pero lo que importa es:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;TIENE QUE SER BUENO PARA EL CLIENTE&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Vean que más arriba escribí “cliente (empresa)”. Es decir, tiene que ser bueno para la empresa o sector de la empresa que nos contrata. No hay que medir (en principio) que sea “bueno para Charles”, por ser Charles nuestro contacto principal en la empresa. A no ser que sea Charles el que pague la factura, no es el “cliente”. Es un representante del cliente.&lt;/p&gt;  &lt;p&gt;Para ponerlo en claro: no es QUE NO IMPORTA absolutamente que nosotros encontremos que el proyecto haya sido bueno para Charles, para el equipo, o para nosotros mismos. No, estoy tratando de encontrar cuál es lo MAS importante.&lt;/p&gt;  &lt;p&gt;Pues bien, después de haber participado en este siglo en varios proyectos ágiles, y también viendo el resultado de otros varios más proyectos, con casos de éxitos y fracasos, lo mejor que puedo decir es:&lt;/p&gt;  &lt;p&gt;Un proyecto es un buen proyecto terminado y entregado, &lt;strong&gt;SI SOLUCIONA EL PROBLEMA DEL CLIENTE&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;No nos piden simplemente “necesitamos el sistema X”, sino, “necesitamos el sistema X que solucione el problema P”. Otras veces, nos dan más libertad “necesitamos una solución S que solucione el problema P”, pero es menos frecuente el caso. Pero muchas veces (la mayoría de ellas) nos piden “necesitamos el sistema X” sin poner muy en claro el problema que tiene que solucionar.&lt;/p&gt;  &lt;p&gt;Para poner un ejemplo. Supongamos que nos piden “Necesitamos un Sistema de Producción”. Puede ser que el contexto del cliente sea:&lt;/p&gt;  &lt;p&gt;“Somos una empresa productora familiar, que en los últimos años, con la entrada de la tercera generación en la gerencia, ha podido expandir el mercado en el exterior”&lt;/p&gt;  &lt;p&gt;Entonces, puede el problema a solucionar puede ser uno de éstos, entre tantos:&lt;/p&gt;  &lt;p&gt;1 - “Se nos ha ido de las manos la producción, necesitamos un sistema que nos permita manejar mejor la asignación de las máquinas. Hoy las desaprovechamos”&lt;/p&gt;  &lt;p&gt;2 - “Las máquinas las asignamos bien, pero tenemos problemas en el seguimiento de los insumos que necesitamos y cuándo los necesitamos. No queremos tener stock de esos insumos en estos tiempos de cambio”&lt;/p&gt;  &lt;p&gt;3 - “Nuestros principales clientes del exterior nos piden trazabilidad norma (y aquí viene una sigla desconocida para nosotros) de acá a fin de año, sino perdemos nuestro principal contrato con China”&lt;/p&gt;  &lt;p&gt;4 – etc&lt;/p&gt;  &lt;p&gt;Vean que entendiendo el problema podemos poner distinto énfasis en lo que vamos a construir, y con el representante del cliente, podemos tener más en claro qué es lo que aporta más valor al cliente. En el caso 1, tendremos que poner mayor esfuerzo en un plan de asignación de máquinas, y no tanto en el stock de insumos. En el caso 2, es al contrario. Y en el caso 3, tendremos que estudiar qué es eso que piden de trazabilidad.&lt;/p&gt;  &lt;p&gt;Pero vean a lo que voy: podemos entregar el mejor sistema de producción, que asigne con algoritmos de inteligencia artificial las máquinas de la mejor forma posible, escrito con todos los patrones encima, con la mejor UI para desktop, web, tablet, y hasta TV,&amp;#160; pero no es la solución del problema del cliente, si estamos en el caso 3.&lt;/p&gt;  &lt;p&gt;ESO ES LO QUE HAY QUE ENTENDER PRIMERO.&lt;/p&gt;  &lt;p&gt;A ver, de nuevo:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;EL ENTREGABLE DEL PROYECTO DEBE SOLUCIONAR EL PROBLEMA DEL CLIENTE&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Y acá entra la capacidad del representante del cliente para ponernos más en claro cuál es el problema real.&lt;/p&gt;  &lt;p&gt;No quisiera terminar el post, sin comentar algo. Hay diferencia entre problema y solución. Como escribía arriba, muchas veces nos piden el sistema. Pero tenemos que esforzarnos, como profesionales, para ver si el sistema inicial pedido soluciona o no el problema, o si es el mejor camino para solucionar el problema. En general, eso ya se definió antes de llegar el proyecto a nuestro equipo. Pero igual deberíamos tenerlo en cuenta. Tal vez, en vez de hacer sistema S, podemos hacer sistema S’ que tenga algunas características sugeridas por nosotros que mejoren alcanzar la solución del problema. &lt;/p&gt;  &lt;p&gt;Siempre recuerdo a Henry Ford, diciendo: “Si le hubiera preguntado a mis potenciales clientes qué querian, me hubieran pedido ‘caballos más rápidos’”.&lt;/p&gt;  &lt;p&gt;Nos leemos!&lt;/p&gt;  &lt;p&gt;Angel “Java” Lopez   &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1830380" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+de+Software/default.aspx">Desarrollo de Software</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+Agil/default.aspx">Desarrollo Agil</category></item><item><title>Aprendiendo Ruby</title><link>http://msmvps.com/blogs/lopez/archive/2013/05/14/aprendiendo-ruby.aspx</link><pubDate>Tue, 14 May 2013 11:46:47 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1830194</guid><dc:creator>lopez</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1830194</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2013/05/14/aprendiendo-ruby.aspx#comments</comments><description>&lt;p&gt;Como &lt;a href="http://msmvps.com/blogs/lopez/archive/2013/05/07/introducci-243-n-a-ruby-en-buenos-aires.aspx"&gt;ya había anunciado&lt;/a&gt;, ayer dí una charla de introducción a Ruby, pueden ver y descargar la presentación en &lt;a href="https://skydrive.live.com/redir?resid=9F903F3D6DB0C176!5909&amp;amp;authkey=!AB8vrN-kqFTFTgs"&gt;mi Skydrive&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;En la presentación hay tres slides todavía en blanco, y slides al final de temas que quedaron expresamente afuera. Pero lean más abajo donde está toda la presentación explicada en detalle, y los ejemplos que usamos.&lt;/p&gt;  &lt;p&gt;Para la instalación de Ruby, comenté:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.ruby-lang.org/en/downloads/"&gt;http://www.ruby-lang.org/en/downloads/&lt;/a&gt;    &lt;br /&gt;En Windows &lt;a href="http://rubyinstaller.org/"&gt;http://rubyinstaller.org/&lt;/a&gt;    &lt;br /&gt;Dev Kit &lt;a href="https://github.com/oneclick/rubyinstaller/wiki/Development-Kit"&gt;https://github.com/oneclick/rubyinstaller/wiki/Development-Kit&lt;/a&gt;    &lt;br /&gt;Mingw, Minimalist GNU for Windows    &lt;br /&gt;&lt;a href="http://www.mingw.org/"&gt;http://www.mingw.org/&lt;/a&gt;&lt;/p&gt; Para esta charla usé Ruby 2.0.0, y aclaré que lo más usado todavía es 1.9.x. Igual, los cambios son evolutivos, no hay grandes “roturas” en 2.0.0, pero como hay algunas gemas y frameworks que todavían corren solamente en 1.9.x, les conviene revisar cuál quieren usar. Al menos en Windows, se pueden instalar las dos versiones, y luego agregar al PATH cuál es directorio binario que queremos usar.  &lt;br /&gt;  &lt;p&gt;Estuvimos viendo temas de Ruby como lenguaje dinámico e interpretado, sintaxis básica, todo es un objeto, todo es un valor, módulos (comentando al pasar include, faltó extend), evaluación dinámica, su relación con Smalltalk, clases abiertas, ejemplo de Domain-Specific Language, y levantamos un sitio con tres páginas simples, con Sinatra y ERB.&lt;/p&gt;  &lt;p&gt;Algunos temas más:&lt;/p&gt;  &lt;p&gt;Mencioné que Sinatra usa WeBrick &lt;a href="http://www.ruby-doc.org/stdlib-2.0/libdoc/webrick/rdoc/WEBrick.html"&gt;http://www.ruby-doc.org/stdlib-2.0/libdoc/webrick/rdoc/WEBrick.html&lt;/a&gt; incorporado desde hace un tiempo directamente en Ruby.&lt;/p&gt;  &lt;p&gt;Mencioné Rack &lt;a href="http://rack.github.io/"&gt;http://rack.github.io/&lt;/a&gt; que habría que estudiar alguna vez para entender la infraestructura web de Sinatra y Ruby On Rails (no es necesario pero es intersante). Rack se inspira en trabajos anteriores, principalmente en Python ver &lt;a href="http://en.wikipedia.org/wiki/Web_Server_Gateway_Interface"&gt;http://en.wikipedia.org/wiki/Web_Server_Gateway_Interface&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Los ejemplos (tres páginas en Sinatra, y un DSL), quedaron en:&lt;/p&gt;  &lt;p&gt;&lt;a href="https://github.com/ajlopez/AprendiendoRuby/tree/master/ejemplos"&gt;https://github.com/ajlopez/AprendiendoRuby/tree/master/ejemplos&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;El ejemplo de DSL fue una simple traducción a español del ejemplo de &lt;a href="http://jroller.com/rolsen/entry/building_a_dsl_in_ruby"&gt;http://jroller.com/rolsen/entry/building_a_dsl_in_ruby&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Si les interesa el tema DSL, estoy publicado enlaces en mi otro blog: &lt;a href="http://ajlopez.wordpress.com/category/domain-specific-languages/"&gt;http://ajlopez.wordpress.com/category/domain-specific-languages/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Y finalmente, la presentación me sirvió para ir escribiendo las primeras páginas de mi tutorial de Ruby en línea:&lt;/p&gt;  &lt;p&gt;&lt;a href="https://github.com/ajlopez/AprendiendoRuby#aprendiendo-ruby"&gt;https://github.com/ajlopez/AprendiendoRuby#aprendiendo-ruby&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/aprruby01.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;Lo voy a ir completando con más capítulos, detalle, referencias, fuentes consultadas, ejercicios. También tengo que poner en línea lo que armé alguna vez en PHP: sitio con exámenes por preguntas y respuestas. Tengo también material (si recuerdan este blog, publicado hace ya un tiempo) de PHP y Java para poner en páginas GitHub. Algo más demandante sería escribir sobre Node.js, pero es candidato. Y sobre Clojure. Como mencioné en otro post, &lt;a href="http://msmvps.com/blogs/lopez/archive/2013/05/04/aplicaciones-distribuidas-y-node-js.aspx"&gt;al explicar terminamos entendiendo&lt;/a&gt; ;-)&lt;/p&gt;  &lt;p&gt;Nos leemos!&lt;/p&gt;  &lt;p&gt;Angel “Java” Lopez   &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1830194" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/Lenguajes+de+Programaci_26002300_243_3B00_n/default.aspx">Lenguajes de Programaci&amp;#243;n</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Ruby/default.aspx">Ruby</category></item><item><title>Mass Lenguaje de Programación (4) Lexer y Parser</title><link>http://msmvps.com/blogs/lopez/archive/2013/05/12/mass-lenguaje-de-programaci-243-n-4-lexer-y-parser.aspx</link><pubDate>Sun, 12 May 2013 08:40:21 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1830015</guid><dc:creator>lopez</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1830015</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2013/05/12/mass-lenguaje-de-programaci-243-n-4-lexer-y-parser.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2013/04/28/mass-lenguaje-de-programaci-243-n-3-comandos.aspx"&gt;Anterior Post&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;En la implementación del lenguaje Mass, tengo una enumeración y una clase:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/mass0401.jpg" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;Un Token representa una palabra del código a procesar. El encargado de separar el código en palabras es el Lexer. Y con el Parser se transforma esa corriente de Tokens en expresiones y comandos:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/mass0402.jpg" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;El constructor de Lexer recibe un string:&lt;/p&gt;  &lt;pre style="background-color:black;width:600px;color:white;font-size:10pt;"&gt;&lt;span style="color:orange;"&gt;public&lt;/span&gt; Lexer&lt;span style="color:cyan;"&gt;(&lt;/span&gt;&lt;span style="color:orange;"&gt;string&lt;/span&gt; text&lt;span style="color:cyan;"&gt;)&lt;/span&gt;
&lt;span style="color:cyan;"&gt;{&lt;/span&gt;
    &lt;span style="color:orange;"&gt;this&lt;/span&gt;.text = text&lt;span style="color:cyan;"&gt;;&lt;/span&gt;
&lt;span style="color:cyan;"&gt;}&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Y ese string es procesado para separarlo en tokens. Vean que el Lexer distingue entre operadores (como +) y separadores (como los paréntesis). También toma en cuenta al fin de línea como token (en otros lenguajes, como C, un fin de línea se puede tomar como un espacio en blanco en muchas situaciones). El principal método de Lexer es NextToken, que devuelve el próximo Token del texto. En algunas pocas situaciones, se hace necesario devolver el Token consumido, y para eso está PushToken y varianes.&lt;/p&gt;

&lt;p&gt;El Parser interamente maneja un Lexer. Le podemos pedir el próximo comando con ParseCommand, y la próxima expresión con ParseExpression. Cuando el texto en proceso se acaba, esos métodos devuelven null.&lt;/p&gt;

&lt;p&gt;Voy a modificar el Lexer para consumir un stream de texto, para poder procesar, por ejemplo, entrada de consola&lt;/p&gt;

&lt;p&gt;Tengo que seguir pensando si internamente, unifico comandos y expresiones, como pasa en Ruby, donde cada “comando” tiene un valor (en Mass también es así), y no solamente eso, sino que puede ser usado como expresión en el contexto de un comando.&lt;/p&gt;

&lt;p&gt;Nos leemos!&lt;/p&gt;

&lt;p&gt;Angel “Java” Lopez 
  &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt; 

  &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1830015" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Lenguajes+de+Programaci_26002300_243_3B00_n/default.aspx">Lenguajes de Programaci&amp;#243;n</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/TDD/default.aspx">TDD</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Proyectos+de+C_26002300_243_3B00_digo+Abierto/default.aspx">Proyectos de C&amp;#243;digo Abierto</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Mass/default.aspx">Mass</category></item><item><title>Introducción a Ruby, en Buenos Aires</title><link>http://msmvps.com/blogs/lopez/archive/2013/05/07/introducci-243-n-a-ruby-en-buenos-aires.aspx</link><pubDate>Tue, 07 May 2013 16:37:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1829610</guid><dc:creator>lopez</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1829610</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2013/05/07/introducci-243-n-a-ruby-en-buenos-aires.aspx#comments</comments><description>&lt;p&gt;
&lt;p&gt;Gracias a la gente del Microsoft User Group de Argentina, el pr&amp;oacute;ximo lunes 
dar&amp;eacute; una charla sobre&lt;/p&gt;
&lt;p&gt;Introducci&amp;oacute;n a Ruby para Programadores .NET (o para programadores)&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.mug.org.ar/Eventos/3893.aspx"&gt;http://www.mug.org.ar/Eventos/3893.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;(vean de visitar la p&amp;aacute;gina porque hay que inscribirse)&lt;/p&gt;
&lt;p&gt;El evento es gratuito, y es el lunes 13 de Mayo, desde las 18:30 hasta las 
20:30. La idea es explicar algo de Ruby, introductorio, para programadores (sean 
de .NET o de otros lenguajes/tecnolog&amp;iacute;as) que no sepan Ruby.&lt;/p&gt;
&lt;p&gt;Los temas a visitar:&lt;/p&gt;
&lt;p&gt;- Sintaxis b&amp;aacute;sica &lt;br /&gt;- Valores b&amp;aacute;sicos: n&amp;uacute;meros, string, arreglos, hashes 
&lt;br /&gt;- Comandos if, for, ciclos &lt;br /&gt;- Clases y objetos &lt;br /&gt;- Herencia &lt;br /&gt;- 
Creaci&amp;oacute;n de objetos &lt;br /&gt;- Variables de instancia y de clase &lt;br /&gt;- M&amp;oacute;dulos &lt;br /&gt;- 
Elementos de metaprogramaci&amp;oacute;n &lt;br /&gt;- Definiendo DSL (Domain Specific Languages) 
internos en Ruby &lt;br /&gt;- Gemas (paquetes de Ruby) &lt;br /&gt;- Ecosistema de desarrollo 
&lt;br /&gt;- Desarrollo Web, especialmente Sinatra, que usa Rack&lt;/p&gt;
&lt;p&gt;Espero poder explicar en dos horas cu&amp;aacute;l es el panorama de desarrollo Ruby, 
para cualquier programador interesado en comenzar con este lenguaje.&lt;/p&gt;
&lt;p&gt;Nos leemos!&lt;/p&gt;
&lt;p&gt;Angel &amp;ldquo;Java&amp;rdquo; Lopez &lt;br /&gt;&lt;a href="http://www.ajlopez.com/"&gt;http://www.ajlopez.com&lt;/a&gt; &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1829610" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/Lenguajes+de+Programaci_26002300_243_3B00_n/default.aspx">Lenguajes de Programaci&amp;#243;n</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Argentina/default.aspx">Argentina</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Ruby/default.aspx">Ruby</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Buenos+Aires/default.aspx">Buenos Aires</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Reuniones/default.aspx">Reuniones</category></item><item><title>Resoluciones del Nuevo Mes: Mayo 2013</title><link>http://msmvps.com/blogs/lopez/archive/2013/05/05/new_2D00_months_2D00_resolutions_2D00_may_2D00_2013.aspx</link><pubDate>Sun, 05 May 2013 10:34:27 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1829432</guid><dc:creator>lopez</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1829432</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2013/05/05/new_2D00_months_2D00_resolutions_2D00_may_2D00_2013.aspx#comments</comments><description>&lt;p&gt;Primero, una revisión de &lt;a href="http://msmvps.com/blogs/lopez/archive/2013/04/03/new_2D00_months_2D00_resolutions_2D00_april_2D00_2013.aspx"&gt;mis resoluciones de Abril&lt;/a&gt;:&lt;/p&gt;  &lt;p&gt;- Actualizar Mass [&lt;strong&gt;&lt;font color="#008000"&gt;completo&lt;/font&gt;&lt;/strong&gt;] &lt;a href="https://github.com/ajlopez/Mass"&gt;ver repo&lt;/a&gt;     &lt;br /&gt;- Comenzar NodeAima [&lt;strong&gt;&lt;font color="#008000"&gt;completo&lt;/font&gt;&lt;/strong&gt;] &lt;a href="https://github.com/ajlopez/NodeAima"&gt;ver repo&lt;/a&gt;     &lt;br /&gt;- Dar curso de un día de Node.js [&lt;strong&gt;&lt;font color="#008000"&gt;completo&lt;/font&gt;&lt;/strong&gt;]     &lt;br /&gt;- Actualizar AjGenesis [&lt;strong&gt;&lt;font color="#800000"&gt;pendiente&lt;/font&gt;&lt;/strong&gt;]     &lt;br /&gt;- Actualizar AjGenesisRuby [&lt;strong&gt;&lt;font color="#800000"&gt;pendiente&lt;/font&gt;&lt;/strong&gt;]     &lt;br /&gt;- Actualizar SimpleGo [&lt;strong&gt;&lt;font color="#800000"&gt;pendiente&lt;/font&gt;&lt;/strong&gt;]     &lt;br /&gt;- Actualizar RubySharp [&lt;strong&gt;&lt;font color="#008000"&gt;completo&lt;/font&gt;&lt;/strong&gt;] &lt;a href="https://github.com/ajlopez/RubySharp"&gt;ver repo&lt;/a&gt;&amp;#160; &lt;br /&gt;- Actualizar ClojSharp [&lt;strong&gt;&lt;font color="#800000"&gt;pendiente&lt;/font&gt;&lt;/strong&gt;]&lt;/p&gt;  &lt;p&gt;Tambié estuve trabajando en:&lt;/p&gt;  &lt;p&gt;- Actualizar AjFabriqNode [&lt;strong&gt;&lt;font color="#008000"&gt;completo&lt;/font&gt;&lt;/strong&gt;] &lt;a href="https://github.com/ajlopez/AjFabriqNode"&gt;ver repo&lt;/a&gt;     &lt;br /&gt;- Actualizar NodeSamples [&lt;strong&gt;&lt;font color="#008000"&gt;completo&lt;/font&gt;&lt;/strong&gt;] &lt;a href="https://github.com/ajlopez/NodeSamples"&gt;ver repo&lt;/a&gt; (ver &lt;a href="https://github.com/ajlopez/NodeSamples/tree/master/Fractal/distributed"&gt;Distributed Fractal&lt;/a&gt;)     &lt;br /&gt;- Actualizar SimpleStorm [&lt;strong&gt;&lt;font color="#008000"&gt;completo&lt;/font&gt;&lt;/strong&gt;] &lt;a href="https://github.com/ajlopez/SimpleStorm"&gt;ver repo&lt;/a&gt;     &lt;br /&gt;- Actualizar SimpleBus [&lt;strong&gt;&lt;font color="#008000"&gt;completo&lt;/font&gt;&lt;/strong&gt;] &lt;a href="https://github.com/ajlopez/SimpleBus"&gt;ver repo&lt;/a&gt;     &lt;br /&gt;- Actualizar SimpleBroadcast [&lt;strong&gt;&lt;font color="#008000"&gt;completo&lt;/font&gt;&lt;/strong&gt;] &lt;a href="https://github.com/ajlopez/SimpleBroadcast"&gt;ver repo&lt;/a&gt;     &lt;br /&gt;- Actualizar SimpleGA [&lt;strong&gt;&lt;font color="#008000"&gt;completo&lt;/font&gt;&lt;/strong&gt;] &lt;a href="https://github.com/ajlopez/SimpleGA"&gt;ver repo&lt;/a&gt;    &lt;br /&gt;- Comenzar SharpAima [&lt;strong&gt;&lt;font color="#008000"&gt;completo&lt;/font&gt;&lt;/strong&gt;] &lt;a href="https://github.com/ajlopez/SharpAima"&gt;ver repo&lt;/a&gt; ver &lt;a href="http://msmvps.com/blogs/lopez/archive/2013/04/21/inteligencia-artifical-en-c-1-primeros-agentes.aspx"&gt;post Inteligencia Artificial en C# (1)&lt;/a&gt;    &lt;br /&gt;- Dar charla de Aplicaciones Distribuidas y Node.js [&lt;strong&gt;&lt;font color="#008000"&gt;completo&lt;/font&gt;&lt;/strong&gt;] &lt;a href="http://msmvps.com/blogs/lopez/archive/2013/05/04/aplicaciones-distribuidas-y-node-js.aspx"&gt;ver post&lt;/a&gt;    &lt;br /&gt;- Actualizar AjErl, mi implementación de Erlang en C# [&lt;strong&gt;&lt;font color="#008000"&gt;completo&lt;/font&gt;&lt;/strong&gt;] &lt;a href="https://github.com/ajlopez/AjErl"&gt;ver repo&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Mucho de ese trabajo adicional estuvo relacionado con el material que presenté en &lt;a href="http://msmvps.com/blogs/lopez/archive/2013/05/04/aplicaciones-distribuidas-y-node-js.aspx"&gt;Aplicaciones Distribuidas y Node.js&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Ahora, las resoluciones para Mayo:&lt;/p&gt;  &lt;p&gt;- Actualizar Mass    &lt;br /&gt;- Update RubySharp     &lt;br /&gt;- Dar una charla, Introducción a Ruby     &lt;br /&gt;- Actualizar AjGenesis     &lt;br /&gt;- Actualizar ClojSharp     &lt;br /&gt;- Nuevos posts sobre Mass     &lt;br /&gt;- Nuevos posts sobre Aplicaciones Distribuidas y Node.js    &lt;br /&gt;- Nuevos posts sobre TDD&lt;/p&gt;  &lt;p&gt;Nos leemos!&lt;/p&gt;  &lt;p&gt;Angel “Java” Lopez    &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;     &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1829432" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Javascript/default.aspx">Javascript</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Proyectos+de+C_26002300_243_3B00_digo+Abierto/default.aspx">Proyectos de C&amp;#243;digo Abierto</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/NodeJs/default.aspx">NodeJs</category></item><item><title>Aplicaciones Distribuidas y Node.js</title><link>http://msmvps.com/blogs/lopez/archive/2013/05/04/aplicaciones-distribuidas-y-node-js.aspx</link><pubDate>Sat, 04 May 2013 19:36:52 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1829398</guid><dc:creator>lopez</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1829398</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2013/05/04/aplicaciones-distribuidas-y-node-js.aspx#comments</comments><description>&lt;p&gt;Como &lt;a href="http://msmvps.com/blogs/lopez/archive/2013/04/24/node-js-charlas-en-buenos-aires-aplicaciones-distribuidas-introducci-243-n-a-zmq.aspx"&gt;ya lo había anunciado&lt;/a&gt;, el martes pasado estuve dando una charla de aplicaciones distribuidas y Node.js, gracias a la gente de &lt;a href="http://www.meetup.com/NodeJS-Argentina/"&gt;Node.js Argentina&lt;/a&gt;,&amp;#160; en el auditorio del &lt;a href="http://www.mug.org.ar"&gt;Microsoft User Group de Argentina&lt;/a&gt;, en Buenos Aires. &lt;/p&gt;  &lt;p&gt;Pueden ver y bajarse &lt;a href="https://skydrive.live.com/redir?resid=9F903F3D6DB0C176!5908&amp;amp;authkey=!AIwllKMuh7vXJrE"&gt;la presentación desde mi Skydrive&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;La idea fue mostrar algunos conceptos, y experimentos que estuve haciendo con Node.js, convirtiendo anteriores trabajos en otras tecnologías. Y mostrar código con ejemplos concretos.&lt;/p&gt;  &lt;p&gt;Primero, expliqué lo que era una aplicación distribuida en el contexto de esta charla. Una aplicación distribuida es una aplicación que se ejecuta en varias computadoras, conectadas en red, que interactúan para resolver un problema. Ver &lt;a href="http://en.wikipedia.org/wiki/Distributed_computing"&gt;http://en.wikipedia.org/wiki/Distributed_computing&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Es decir, va más allá del clásico cliente servidor. Podemos tener varias computadoras para hacer web crawling de un sitio, o resolviendo la renderización de escenas de una película 3d. Las computadores que intervienen en el trabajo no necesariamente tienen el mismo software o programa: puede que algunas se ocupen solamente de algún paso del problema. Tampoco tienen que tener la misma plataforma o lenguaje de programación. &lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/distrnode01.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;Lo que quise destacar, entonces, en la charla, son las facilidades que nos da Node.js y JavaScript para construir este tipo de aplicaciones. Ya en otras charlas afirmé “JavaScript es una manteca”, para destacar su flexibilidad. Y ahora, en esta charla, tuve la oportunidad de mostrar un tópico donde Node.js brilla: tanto por su soporte de red en los módulos “built-in”, como por su ecosistema, como por la filosofía de combinar módulos (como en Unix, ver &lt;a href="http://blog.izs.me/post/48281998870/unix-philosophy-and-node-js"&gt;Unix philosophy and Node.js&lt;/a&gt; de &lt;a href="http://twitter.com/izs"&gt;@izs&lt;/a&gt;) &lt;/p&gt;  &lt;p&gt;Mencioné &lt;a href="http://mythz.servicestack.net/blog/2013/02/27/the-deep-insights-of-alan-kay/"&gt;una entrevista&lt;/a&gt; a &lt;a href="http://en.wikipedia.org/wiki/Alan_Kay"&gt;Alan Kay&lt;/a&gt; (ver su &lt;a href="http://en.wikipedia.org/wiki/Dynabook"&gt;Dynabook&lt;/a&gt;)&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/distrnode02.png" alt="" /&gt; &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;     &lt;br /&gt;I thought of objects being like biological cells and/or individual computers on a network, only able to communicate with messages      &lt;br /&gt;…      &lt;br /&gt;Until real software engineering is developed, the next best practice is to develop with a dynamic system that has extreme late binding in all aspects      &lt;br /&gt;…      &lt;br /&gt;&lt;strong&gt;The big idea is “messaging”&lt;/strong&gt; &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Es interensante que Kay mencionara células biológicas: nuestros nodos en ejecución pueden tomarse como células, que forman el organismo de nuestra aplicación distribuida. Como dice Kay, el gran tema es el “messaging”, el envío de mensajes entre las partes. Las aplicaciones distribuidas nos dan la oportunidad de olvidarnos del concepto de función/rutina a la que llamamos con parámetros y esperamos que termine de ejecutar para dar un resultado, y aún de una llamada con callback: un elemento de nuestra aplicación distribuida enviará un mensaje, desentendiéndose de obtener una respuesta.&lt;/p&gt;  &lt;p&gt;También mencioné a &lt;a href="http://en.wikipedia.org/wiki/Richard_Feynman"&gt;Richard Feynman&lt;/a&gt; (algún post &lt;a href="http://ajlopez.zoomblog.com/archivo/2012/11/20/richard-Feynman-Enlaces-y-Recursos-2.html"&gt;de mis enlaces&lt;/a&gt;), ver &lt;/p&gt; &lt;a title="http://boards.straightdope.com/sdmb/showthread.php?t=159936&amp;#13;&amp;#10;" href="http://boards.straightdope.com/sdmb/showthread.php?t=159936"&gt;http://boards.straightdope.com/sdmb/showthread.php?t=159936   &lt;br /&gt;&lt;/a&gt;  &lt;blockquote&gt;   &lt;p&gt;Feynman was once asked by a Caltech faculty member to explain why spin 1/2 particles obey Fermi-Dirac statistics. He gauged his audience perfectly and said &amp;quot;I&amp;#39;ll prepare a freshman lecture on it.&amp;quot; But a few days later he returned and said, &amp;quot;You know, I couldn&amp;#39;t do it. I couldn&amp;#39;t reduce it to the freshman level. That means we really don&amp;#39;t understand it.&amp;quot;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Adaptando su frase a “si no lo podemos explicar, es que no lo entendemos” como motivación personal para dar charlas. Recordé su trabajo de estudio “por su cuenta” de la física cuántica según &lt;a href="http://ajlopez.zoomblog.com/archivo/2011/03/09/richard-Feynman-por-Freeman-Dyson.html"&gt;Feyman por Dyson&lt;/a&gt;, como justificación lejana a experimentar con un tema, en vez de tomar lo que ya está hecho directamente.&lt;/p&gt;  &lt;p&gt;Pues lo que presenté luego, son experimentos sobre Node.js para aplicaciones distribuidas. Pero ¿por qué Node.js? En JavaScript, un mensaje puede ser un simple objeto serializable a JSON (un objeto sin ciclos, o sea, un árbol). Y para el transporte del mensaje podemos elegir multitud de módulos en el ecosistema de Node, como usar el require(‘net’) o require(‘http’) que vienen “built-it” en el núcleo de Node.js&lt;/p&gt;  &lt;p&gt;Preguntas que tenemos que hacernos en cada caso de aplicación distribuida:&lt;/p&gt;  &lt;p&gt;¿Qué elementos de nuestra aplicación producen mensajes?&lt;/p&gt;  &lt;p&gt;¿Qué elementos consumen mensajes?&lt;/p&gt;  &lt;p&gt;Un mensaje ¿es consumido por un solo elemento? ¿o puede ser procesado por varios elementos interesados?&lt;/p&gt;  &lt;p&gt;Las máquinas y programas que ejecutan ¿están determinados desde el comienzo? ¿o pueden variar con el tiempo? Por ejemplo, me gustaría sumar a mi aplicación distribuida unas cuarenta máquinas que a la noche están ociosas. ¿Se puede hacer? ¿Necesitamos esta característica?&lt;/p&gt;  &lt;p&gt;Un mensaje producido en un elemento de una máquina ¿se consume localmente? ¿o puede viajar a otra máquina? ¿quién decide eso? ¿el programador, el programa supervisor?&lt;/p&gt;  &lt;p&gt;Y dado un mensaje que tiene que llegar a otra máquina ¿cómo llega? ¿con qué transporte?&lt;/p&gt;  &lt;p&gt;Si un mensaje tiene que ser procesado remotamente ¿cómo se selecciona la máquina destino? ¿por programa? ¿por algún balanceo de carga?&lt;/p&gt;  &lt;p&gt;Esas preguntas se contestarán diferente en cada experimento o ejemplo que tengamos.&lt;/p&gt;  &lt;p&gt;Uno de los experimentos (repetido de distintas formas) es un web crawler, compuesto lógicamente (partes lógicas, luego a implementar de distinta forma según el ejemplo/experimento):&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/distrnode03.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;Cuando tengamos que recuperar las páginas de un sitio, primero enviamos una URL inicial a un elemento Resolver. Este elemento mantiene la lista de páginas ya visitadas. Si la URL es una página no procesada aún, se envía la URL a un elemento Downloader (elemento lógico que puede estar implementado en varias máquinas). Es el encargado de conseguir el contenido de la página. Luego le pasa ese dato al elemento Harvester, que extrae los enlaces que consigue encontrar en la nueva página. Los enlaces se envían al Resolver, que examina si corresponde o no procesar esas URLs.&lt;/p&gt;  &lt;p&gt;Un módulo que escribí (no fue el primero, sino que surgió de refactor y extracción de otros casos de uso) es ObjectStream&lt;/p&gt;  &lt;p&gt;&lt;a href="https://github.com/ajlopez/ObjectStream"&gt;https://github.com/ajlopez/ObjectStream&lt;/a&gt;    &lt;br /&gt;&lt;a href="https://github.com/ajlopez/ObjectStream/tree/master/samples/broadcast"&gt;https://github.com/ajlopez/ObjectStream/tree/master/samples/broadcast&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/distrnode04.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;que me permite enviar un objeto JavaScript (serializable a JSON) a un Object Stream, un stream que recibe objetos. Este stream puede enviar ese objeto, ya serializado a texto, por otro stream. Y hay un Object Stream que toma esas líneas de texto y las reconstruye como objetos. Esto me permite usar, por ejemplo, un stream de socket para enviar objetos JavaScript de una máquina a otra. Vean en los enlaces de arriba el ejemplo de Broadcast que mostré en la charla.&lt;/p&gt;  &lt;p&gt;Basado en ObjectStream, me animé luego a armar&lt;/p&gt;  &lt;p&gt;&lt;a href="https://github.com/ajlopez/SimpleMessages"&gt;https://github.com/ajlopez/SimpleMessages&lt;/a&gt;    &lt;br /&gt;&lt;a href="https://github.com/ajlopez/SimpleMessages/tree/master/samples/Broadcast"&gt;https://github.com/ajlopez/SimpleMessages/tree/master/samples/Broadcast&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/distrnode05.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;Permite que dos procesos establezcan canales bidireccionales de envío de mensajes, que arrivan en cualquier momento. Desde el punto de vista del código, uno puede exponer un servidor (o varios) o crear clientes que se conectan a otros servidores. Pero luego de efectuada la conexión, el intercambio de mensajes es simétrico: cualquiera de las partes puede enviar un mensaje en cualquier momento. Ya con esto podemos entretenernos bastante, escribiendo aplicaciones distribudas basadas en mensajes.&lt;/p&gt;  &lt;p&gt;Pero a veces, necesitamos más que enviar un simple mensaje. Por ejemplo, se nos puede presentar la necesidad de llamar a un objeto que está ejecutando en otra máquina. Podemos implementar un Remote Procedure Call. Lo hice en:&lt;/p&gt;  &lt;p&gt;&lt;a href="https://github.com/ajlopez/SimpleRemote"&gt;https://github.com/ajlopez/SimpleRemote&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/distrnode06.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;Basado en SimpleMessages, tanto el cliente como el servidor pueden exponer un objeto “hacia afuera”, y la otra parte lo puede invocar, como si fuera un objeto local. Solamente que como el retorno de la respuesta no es inmediato, el programador que llama al método agrega un callback para procesar la respuesta cuando ésta llegue.&lt;/p&gt;  &lt;p&gt;Para alternativas pueden ver:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://stackoverflow.com/questions/5010814/whats-the-best-way-to-make-one-node-js-server-talk-to-another"&gt;http://stackoverflow.com/questions/5010814/whats-the-best-way-to-make-one-node-js-server-talk-to-another&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://stackoverflow.com/questions/7986088/rpc-and-messagequeues-in-node-js"&gt;http://stackoverflow.com/questions/7986088/rpc-and-messagequeues-in-node-js&lt;/a&gt;    &lt;br /&gt;&lt;a href="https://github.com/substack/dnode"&gt;https://github.com/substack/dnode&lt;/a&gt;    &lt;br /&gt;&lt;a href="https://github.com/Flotype/now"&gt;https://github.com/Flotype/now&lt;/a&gt;    &lt;br /&gt;&lt;a href="https://code.google.com/p/protobuf-for-node/"&gt;https://code.google.com/p/protobuf-for-node/&lt;/a&gt;    &lt;br /&gt;&lt;a href="https://code.google.com/p/protobuf/"&gt;https://code.google.com/p/protobuf/&lt;/a&gt;    &lt;br /&gt;&lt;a href="https://github.com/Frans-Willem/IPCNode"&gt;https://github.com/Frans-Willem/IPCNode&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Vean dnode, cómo tienen clientes para distintos lenguajes. O vean también algo más agnóstico, &lt;a title="http://en.wikipedia.org/wiki/JSON-RPC" href="http://en.wikipedia.org/wiki/JSON-RPC"&gt;http://en.wikipedia.org/wiki/JSON-RPC&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Tuve un caso de uso donde necesitaba repartir mensajes, no solamente enviar un mensaje desde A hasta B. Entonces nació:&lt;/p&gt;  &lt;p&gt;&lt;a href="https://github.com/ajlopez/SimpleBroadcast"&gt;https://github.com/ajlopez/SimpleBroadcast&lt;/a&gt;    &lt;br /&gt;&lt;a href="https://github.com/ajlopez/SimpleBroadcast/tree/master/samples/Broadcast"&gt;https://github.com/ajlopez/SimpleBroadcast/tree/master/samples/Broadcast&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/distrnode07.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;De esta manera, un cliente puede enviar un mensaje a un servidor, y éste repartirlo en los demas clientes conectados. Vean que el mensaje no se transmite al cliente que lo originó, sólo a los demás. Hasta puede haber una “estrella” de servidores, donde cada servidor atiende a sus clientes, y actúa como cliente de los otros servidores:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/distrnode08.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;Esto permite la escalabilidad agregando servidores a la estrella. También tiene un concepto algo más sofisticado, el servidor repetidor (ver el código y tests). En este software tuve colaboración de Fernando Lores.&lt;/p&gt;  &lt;p&gt;En otros casos de uso, en vez de enviar mensajes, necesité que los que iban a procesar mensajes los pidieran explícitamente. Como quería realizar todos estos experimentos en Node.js, sin depender de software externo, escribí:&lt;/p&gt;  &lt;p&gt;&lt;a href="https://github.com/ajlopez/SimpleQueue"&gt;https://github.com/ajlopez/SimpleQueue&lt;/a&gt;    &lt;br /&gt;&lt;a href="https://github.com/ajlopez/SimpleQueue/tree/master/samples/DistributedProducerConsumer"&gt;https://github.com/ajlopez/SimpleQueue/tree/master/samples/DistributedProducerConsumer&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/distrnode09.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;Al principio, implementé una cola en memoria, local. Y luego la expuse hacia otras máquinas usando SimpleRemote.&lt;/p&gt;  &lt;p&gt;Otro caso de uso con el que me encontré es: necesito publicar mensajes, pero no sé de antemano a quién le interesa. Es similar a los eventos de Node.js: uno emite un evento, pero no sabe quienes se suscribieron a ellos. Llevado eso a algo distribuido escribí:&lt;/p&gt;  &lt;p&gt;&lt;a href="https://github.com/ajlopez/SimpleBus"&gt;https://github.com/ajlopez/SimpleBus&lt;/a&gt;    &lt;br /&gt;&lt;a href="https://github.com/ajlopez/SimpleBus/tree/master/samples/Market"&gt;https://github.com/ajlopez/SimpleBus/tree/master/samples/Market&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/distrnode10.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;Tanto los que publican como los que se suscriben a mensajes pueden estar en máquinas distintas.&lt;/p&gt;  &lt;p&gt;En el ejemplo de Market que mostré en la charla (ver el enlace de arriba) la suscripción a los mensajes se puede hacer dando un mensaje ejemplo: todos los mensajes que tengan las mismas propiedades que el ejemplo, serán tomados para procesar por el subscriptor. También puedo enviar un predicado, y notablemente, ese predicado puede “viajar” desde el suscriptor a la maquina que tiene el servidor de bus (que podrían ser varias máquinas en estrella usando SimpleBroadcast).&lt;/p&gt;  &lt;p&gt;Muchos de estos casos de uso fueron motivados por implementaciones que tuve que escribir en otras tecnologías. El trabajo que más influyó es lo que hice cuando trabajé para &lt;a href="http://twitter.com/asehmi"&gt;@asehmi&lt;/a&gt;:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/distrnode11.jpg" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;Ver &lt;a href="http://ajlopez.wordpress.com/2007/10/15/remember-fabriq/"&gt;Remember Fabriq&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Basado en su proyecto Fabriq, reescribí algo en AjFabriqNode:&lt;/p&gt;  &lt;p&gt;&lt;a href="https://github.com/ajlopez/AjFabriqNode"&gt;https://github.com/ajlopez/AjFabriqNode&lt;/a&gt;    &lt;br /&gt;&lt;a href="https://github.com/ajlopez/AjFabriqNode/tree/master/samples/WebCrawler"&gt;https://github.com/ajlopez/AjFabriqNode/tree/master/samples/WebCrawler&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;AjFabriq se basa en tener varios nodos ejecutándose, cada uno declara un árbol de procesadores de mensajes. En base al contenido del mensajem se determina qué procesador de mensaje puede atenderlo. Cada nodo se puede conectar a otro de la red, y entre varios se intercambian cuáles procesadores de mensajes tiene cada uno. Entonces, podemos tener un Web Crawler distribuido donde en un nodo tenemos el resolver, y en otros tenemos downloaders y harvesters.&lt;/p&gt;  &lt;p&gt;Otros prefieren enviar los mensajes directamente a un elemento específico. Basado en la implementación de actores en Akka/Scala, ver:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://doc.akka.io/docs/akka/snapshot/general/actor-systems.html"&gt;http://doc.akka.io/docs/akka/snapshot/general/actor-systems.html&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://doc.akka.io/docs/akka/snapshot/general/actors.html"&gt;http://doc.akka.io/docs/akka/snapshot/general/actors.html&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://doc.akka.io/docs/akka/snapshot/general/addressing.html"&gt;http://doc.akka.io/docs/akka/snapshot/general/addressing.html&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;implementé algo más simple:&lt;/p&gt;  &lt;p&gt;&lt;a href="https://github.com/ajlopez/SimpleActors"&gt;https://github.com/ajlopez/SimpleActors&lt;/a&gt;    &lt;br /&gt;&lt;a href="https://github.com/ajlopez/SimpleActors/tree/master/samples/DistributedWebCrawler"&gt;https://github.com/ajlopez/SimpleActors/tree/master/samples/DistributedWebCrawler&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/distrnode12.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;Pero vean que en Akka, un mensaje se envía en general a un actor, identificado por su dirección.&lt;/p&gt;  &lt;p&gt;Hay un proyecto Java, Storm Project en:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://storm-project.net/"&gt;http://storm-project.net/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/distrnode13.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;donde se puede armar una topología con los elementos lógicos que van a recibir, procesar y emitir tuplas (lo que para esta charla es mensajes). Hay productores de mensajes, los Spout, y procesadores de mensajes, los Bolt. Luego cada elemento puede ejecutarse en varias máquinas. Así, podemos tener una topología de Web Crawler con Resolver, Downloader y Harvester. Pero luego poner 20 downloaders en 10 máquinas, y 5 harvesters en las mismas máquinas u otras.&lt;/p&gt;  &lt;p&gt;Así que, ni lerdo ni perezoso, escribí algo simple en Node.js:&lt;/p&gt;  &lt;p&gt;&lt;a href="https://github.com/ajlopez/SimpleStorm"&gt;https://github.com/ajlopez/SimpleStorm&lt;/a&gt;    &lt;br /&gt;&lt;a href="https://github.com/ajlopez/SimpleStorm/tree/master/samples/DistributedWebCrawler"&gt;https://github.com/ajlopez/SimpleStorm/tree/master/samples/DistributedWebCrawler&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/distrnode14.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;Lo que ví en mis experimentos, es que muchas veces necesito levantar varias máquinas, indicarles qué hacer, que aplicaciones lógicas ejecutar (por ejemplo, el web crawler), y que puedan intercambiar mensajes entre ellos. Mostré:&lt;/p&gt;  &lt;p&gt;&lt;a href="https://github.com/ajlopez/MultiNodes"&gt;https://github.com/ajlopez/MultiNodes&lt;/a&gt;    &lt;br /&gt;&lt;a href="https://github.com/ajlopez/MultiNodes/tree/master/samples/collatz"&gt;https://github.com/ajlopez/MultiNodes/tree/master/samples/collatz&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Lo interesante es que un nuevo nodo que se incorpora a la red, puede ser instruido dinámicamente a ejecutar algo (como instalar y lanzar una nueva instancia del web crawler).&lt;/p&gt;  &lt;p&gt;Dos ejemplos finales:&lt;/p&gt;  &lt;p&gt;Una implementación de algoritmo genético distribuido:&lt;/p&gt;  &lt;p&gt;&lt;a href="https://github.com/ajlopez/SimpleGA"&gt;https://github.com/ajlopez/SimpleGA&lt;/a&gt;    &lt;br /&gt;&lt;a href="https://github.com/ajlopez/SimpleGA/tree/master/samples/tspdistr"&gt;https://github.com/ajlopez/SimpleGA/tree/master/samples/tspdistr&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/distrnode15.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;Y un fractal que se puede calcular en el browser, o en un servidor Node.js/Express, solo o ayudado por nodos worker adicionales:&lt;/p&gt;  &lt;p&gt;&lt;a href="https://github.com/ajlopez/NodeSamples/tree/master/Fractal"&gt;https://github.com/ajlopez/NodeSamples/tree/master/Fractal&lt;/a&gt;    &lt;br /&gt;&lt;a href="https://github.com/ajlopez/NodeSamples/tree/master/Fractal/html"&gt;https://github.com/ajlopez/NodeSamples/tree/master/Fractal/html&lt;/a&gt;    &lt;br /&gt;&lt;a href="https://github.com/ajlopez/NodeSamples/tree/master/Fractal/server"&gt;https://github.com/ajlopez/NodeSamples/tree/master/Fractal/server&lt;/a&gt;    &lt;br /&gt;&lt;a href="https://github.com/ajlopez/NodeSamples/tree/master/Fractal/distributed"&gt;https://github.com/ajlopez/NodeSamples/tree/master/Fractal/distributed&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/distrnode16.jpg" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;Al final, mencioné varias razones para investigar con aplicaciones distribuidas: desde lo interesante del tema, como lo práctico (para Big Data, cálculo distribuido y en paralelo, etc). Pero resalté que tenemos que seguir investigando sobre aplicaciones distribuidas e inteligencia artificial. Nuestro sistema nervioso funciona con varios nodos, surgiendo una aplicación distribuidas en neuronas (¿recuerdan a Alan Kay hablando de células con mensajes?)&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/distrnode17.jpg" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;Otro de los temas que me interesan es tener lenguajes dinámicos que puedan distribuirse fácilmente entre nodos distribuidos (de hecho, me gustó JavaScript con Node.js, porque me libera de implementar eso). Ver:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2013/02/11/programming_2D00_languages_2D00_distributed_2D00_computing_2D00_and_2D00_artificial_2D00_intelligence.aspx"&gt;Lenguajes de Programación, Computación Distribuida, Inteligencia Artificial&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2012/09/11/experimentos-distribuidos.aspx"&gt;Experimentos Distribuidos&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Nos leemos!&lt;/p&gt;  &lt;p&gt;Angel “Java” Lopez   &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1829398" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/Aplicaciones+Distribuidas/default.aspx">Aplicaciones Distribuidas</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Javascript/default.aspx">Javascript</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Proyectos+de+C_26002300_243_3B00_digo+Abierto/default.aspx">Proyectos de C&amp;#243;digo Abierto</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/NodeJs/default.aspx">NodeJs</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Reuniones/default.aspx">Reuniones</category></item><item><title>Mass Lenguaje de Programación (3) Comandos</title><link>http://msmvps.com/blogs/lopez/archive/2013/04/28/mass-lenguaje-de-programaci-243-n-3-comandos.aspx</link><pubDate>Sun, 28 Apr 2013 11:24:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1828666</guid><dc:creator>lopez</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1828666</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2013/04/28/mass-lenguaje-de-programaci-243-n-3-comandos.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2013/04/27/mass-lenguaje-de-programaci-243-n-2-primeras-expresiones.aspx"&gt;Anterior Post&amp;nbsp;&lt;/a&gt;&amp;nbsp;&lt;br /&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2013/05/12/mass-lenguaje-de-programaci-243-n-4-lexer-y-parser.aspx"&gt;Siguiente Post&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Veamos hoy c&amp;oacute;mo est&amp;aacute;n implementados los comandos en Mass (&lt;a href="http://github.com/ajlopez/Mass"&gt;ver repo&lt;/a&gt;). En el proyecto de librer&amp;iacute;a de clases, tengo:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/mass0301.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;Hay comandos para if, while, for, for each, etc&amp;hellip;. Todos implementan la interfaz ICommand:&lt;/p&gt;
&lt;pre style="background-color:black;color:white;"&gt;&lt;span style="color:orange;"&gt;public&lt;/span&gt; &lt;span style="color:orange;"&gt;interface&lt;/span&gt; ICommand
&lt;span style="color:cyan;"&gt;{&lt;/span&gt;
    &lt;span style="color:orange;"&gt;object&lt;/span&gt; Execute&lt;span style="color:cyan;"&gt;(&lt;/span&gt;Context context&lt;span style="color:cyan;"&gt;);&lt;/span&gt;
&lt;span style="color:cyan;"&gt;}&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Vean que es muy parecido a IExpression. Igual quise mantener comandos y expresiones por separado, por lo menos en esta primera implementaci&amp;oacute;n, para tener un claro delineamiento de los conceptos de base del lenguaje.&lt;/p&gt;
&lt;p&gt;Un ejemplo t&amp;iacute;pico de comando es el WhileCommand (parte del c&amp;oacute;digo):&lt;/p&gt;
&lt;pre style="background-color:black;color:white;"&gt;&lt;span style="color:orange;"&gt;public&lt;/span&gt; &lt;span style="color:orange;"&gt;class&lt;/span&gt; WhileCommand : ICommand
&lt;span style="color:cyan;"&gt;{&lt;/span&gt;
    &lt;span style="color:orange;"&gt;private&lt;/span&gt; &lt;span style="color:orange;"&gt;static&lt;/span&gt; &lt;span style="color:orange;"&gt;int&lt;/span&gt; hashcode = &lt;span style="color:orange;"&gt;typeof&lt;/span&gt;&lt;span style="color:cyan;"&gt;(&lt;/span&gt;WhileCommand&lt;span style="color:cyan;"&gt;)&lt;/span&gt;.GetHashCode&lt;span style="color:cyan;"&gt;();&lt;/span&gt;

    &lt;span style="color:orange;"&gt;private&lt;/span&gt; IExpression condition&lt;span style="color:cyan;"&gt;;&lt;/span&gt;
    &lt;span style="color:orange;"&gt;private&lt;/span&gt; ICommand command&lt;span style="color:cyan;"&gt;;&lt;/span&gt;

    &lt;span style="color:orange;"&gt;public&lt;/span&gt; WhileCommand&lt;span style="color:cyan;"&gt;(&lt;/span&gt;IExpression condition&lt;span style="color:cyan;"&gt;,&lt;/span&gt; ICommand command&lt;span style="color:cyan;"&gt;)&lt;/span&gt;
    &lt;span style="color:cyan;"&gt;{&lt;/span&gt;
        &lt;span style="color:orange;"&gt;this&lt;/span&gt;.condition = condition&lt;span style="color:cyan;"&gt;;&lt;/span&gt;
        &lt;span style="color:orange;"&gt;this&lt;/span&gt;.command = command&lt;span style="color:cyan;"&gt;;&lt;/span&gt;
    &lt;span style="color:cyan;"&gt;}&lt;/span&gt;

    &lt;span style="color:orange;"&gt;public&lt;/span&gt; &lt;span style="color:orange;"&gt;object&lt;/span&gt; Execute&lt;span style="color:cyan;"&gt;(&lt;/span&gt;Context context&lt;span style="color:cyan;"&gt;)&lt;/span&gt;
    &lt;span style="color:cyan;"&gt;{&lt;/span&gt;
        &lt;span style="color:orange;"&gt;for&lt;/span&gt; &lt;span style="color:cyan;"&gt;(&lt;/span&gt;&lt;span style="color:orange;"&gt;object&lt;/span&gt; value = &lt;span style="color:orange;"&gt;this&lt;/span&gt;.condition.Evaluate&lt;span style="color:cyan;"&gt;(&lt;/span&gt;context&lt;span style="color:cyan;"&gt;);&lt;/span&gt; 
            value &lt;span style="color:cyan;"&gt;!&lt;/span&gt;= &lt;span style="color:orange;"&gt;null&lt;/span&gt; &lt;span style="color:cyan;"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color:cyan;"&gt;!&lt;/span&gt;&lt;span style="color:orange;"&gt;false&lt;/span&gt;.Equals&lt;span style="color:cyan;"&gt;(&lt;/span&gt;value&lt;span style="color:cyan;"&gt;);&lt;/span&gt;
            value = &lt;span style="color:orange;"&gt;this&lt;/span&gt;.condition.Evaluate&lt;span style="color:cyan;"&gt;(&lt;/span&gt;context&lt;span style="color:cyan;"&gt;))&lt;/span&gt;
        &lt;span style="color:cyan;"&gt;{&lt;/span&gt;
            &lt;span style="color:orange;"&gt;this&lt;/span&gt;.command.Execute&lt;span style="color:cyan;"&gt;(&lt;/span&gt;context&lt;span style="color:cyan;"&gt;);&lt;/span&gt;
            &lt;span style="color:orange;"&gt;if&lt;/span&gt; &lt;span style="color:cyan;"&gt;(&lt;/span&gt;context.HasContinue&lt;span style="color:cyan;"&gt;())&lt;/span&gt;
                context.ClearContinue&lt;span style="color:cyan;"&gt;();&lt;/span&gt;
            &lt;span style="color:orange;"&gt;if&lt;/span&gt; &lt;span style="color:cyan;"&gt;(&lt;/span&gt;context.HasBreak&lt;span style="color:cyan;"&gt;())&lt;/span&gt;
            &lt;span style="color:cyan;"&gt;{&lt;/span&gt;
                context.ClearBreak&lt;span style="color:cyan;"&gt;();&lt;/span&gt;
                &lt;span style="color:orange;"&gt;break&lt;/span&gt;&lt;span style="color:cyan;"&gt;;&lt;/span&gt;
            &lt;span style="color:cyan;"&gt;}&lt;/span&gt;
        &lt;span style="color:cyan;"&gt;}&lt;/span&gt;

        &lt;span style="color:orange;"&gt;return&lt;/span&gt; &lt;span style="color:orange;"&gt;null&lt;/span&gt;&lt;span style="color:cyan;"&gt;;&lt;/span&gt;
    &lt;span style="color:cyan;"&gt;}&lt;/span&gt;
&lt;span style="color:cyan;"&gt;}&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Para Mass: cualquier valor null o false es falso. Todo lo dem&amp;aacute;s es verdadero. Un tema a refactorizar: poner un m&amp;eacute;todo IsFalse para se usado tanto en la implementaci&amp;oacute;n de While como de If.&lt;/p&gt;
&lt;p&gt;Otro ejemplo es el ForEachCommand (parte del c&amp;oacute;digo):&lt;/p&gt;
&lt;pre style="background-color:black;color:white;"&gt;&lt;span style="color:orange;"&gt;public&lt;/span&gt; &lt;span style="color:orange;"&gt;class&lt;/span&gt; ForEachCommand : ICommand
&lt;span style="color:cyan;"&gt;{&lt;/span&gt;
    &lt;span style="color:orange;"&gt;private&lt;/span&gt; &lt;span style="color:orange;"&gt;string&lt;/span&gt; name&lt;span style="color:cyan;"&gt;;&lt;/span&gt;
    &lt;span style="color:orange;"&gt;private&lt;/span&gt; IExpression expression&lt;span style="color:cyan;"&gt;;&lt;/span&gt;
    &lt;span style="color:orange;"&gt;private&lt;/span&gt; ICommand command&lt;span style="color:cyan;"&gt;;&lt;/span&gt;

    &lt;span style="color:orange;"&gt;public&lt;/span&gt; ForEachCommand&lt;span style="color:cyan;"&gt;(&lt;/span&gt;&lt;span style="color:orange;"&gt;string&lt;/span&gt; name&lt;span style="color:cyan;"&gt;,&lt;/span&gt; IExpression expression&lt;span style="color:cyan;"&gt;,&lt;/span&gt; ICommand command&lt;span style="color:cyan;"&gt;)&lt;/span&gt;
    &lt;span style="color:cyan;"&gt;{&lt;/span&gt;
        &lt;span style="color:orange;"&gt;this&lt;/span&gt;.name = name&lt;span style="color:cyan;"&gt;;&lt;/span&gt;
        &lt;span style="color:orange;"&gt;this&lt;/span&gt;.expression = expression&lt;span style="color:cyan;"&gt;;&lt;/span&gt;
        &lt;span style="color:orange;"&gt;this&lt;/span&gt;.command = command&lt;span style="color:cyan;"&gt;;&lt;/span&gt;
    &lt;span style="color:cyan;"&gt;}&lt;/span&gt;

    &lt;span style="color:orange;"&gt;public&lt;/span&gt; &lt;span style="color:orange;"&gt;object&lt;/span&gt; Execute&lt;span style="color:cyan;"&gt;(&lt;/span&gt;Context context&lt;span style="color:cyan;"&gt;)&lt;/span&gt;
    &lt;span style="color:cyan;"&gt;{&lt;/span&gt;
        var values = &lt;span style="color:cyan;"&gt;(&lt;/span&gt;IEnumerable&lt;span style="color:cyan;"&gt;)&lt;/span&gt;&lt;span style="color:orange;"&gt;this&lt;/span&gt;.expression.Evaluate&lt;span style="color:cyan;"&gt;(&lt;/span&gt;context&lt;span style="color:cyan;"&gt;);&lt;/span&gt;

        &lt;span style="color:orange;"&gt;foreach&lt;/span&gt; &lt;span style="color:cyan;"&gt;(&lt;/span&gt;var value &lt;span style="color:orange;"&gt;in&lt;/span&gt; values&lt;span style="color:cyan;"&gt;)&lt;/span&gt;
        &lt;span style="color:cyan;"&gt;{&lt;/span&gt;
            context.Set&lt;span style="color:cyan;"&gt;(&lt;/span&gt;&lt;span style="color:orange;"&gt;this&lt;/span&gt;.name&lt;span style="color:cyan;"&gt;,&lt;/span&gt; value&lt;span style="color:cyan;"&gt;);&lt;/span&gt;
            &lt;span style="color:orange;"&gt;this&lt;/span&gt;.command.Execute&lt;span style="color:cyan;"&gt;(&lt;/span&gt;context&lt;span style="color:cyan;"&gt;);&lt;/span&gt;
            &lt;span style="color:orange;"&gt;if&lt;/span&gt; &lt;span style="color:cyan;"&gt;(&lt;/span&gt;context.HasContinue&lt;span style="color:cyan;"&gt;())&lt;/span&gt;
                context.ClearContinue&lt;span style="color:cyan;"&gt;();&lt;/span&gt;
            &lt;span style="color:orange;"&gt;if&lt;/span&gt; &lt;span style="color:cyan;"&gt;(&lt;/span&gt;context.HasBreak&lt;span style="color:cyan;"&gt;())&lt;/span&gt;
            &lt;span style="color:cyan;"&gt;{&lt;/span&gt;
                context.ClearBreak&lt;span style="color:cyan;"&gt;();&lt;/span&gt;
                &lt;span style="color:orange;"&gt;break&lt;/span&gt;&lt;span style="color:cyan;"&gt;;&lt;/span&gt;
            &lt;span style="color:cyan;"&gt;}&lt;/span&gt;
        &lt;span style="color:cyan;"&gt;}&lt;/span&gt;

        &lt;span style="color:orange;"&gt;return&lt;/span&gt; &lt;span style="color:orange;"&gt;null&lt;/span&gt;&lt;span style="color:cyan;"&gt;;&lt;/span&gt;
    &lt;span style="color:cyan;"&gt;}&lt;/span&gt;
&lt;span style="color:cyan;"&gt;}&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Vean que para Mass, todo lo que sea IEnumerable se puede usar para ser consumido por este comando. Tuve que poner algunos datos en el contexto, para saber si se hab&amp;iacute;a hecho un break o un continue.&lt;/p&gt;
&lt;p&gt;Y como siempre, todo esto desarrollado con TDD: pueden &lt;a href="https://github.com/ajlopez/Mass/commits/master"&gt;ver los commits del repo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Pr&amp;oacute;ximos posts: Lexer y Parser, ejemplos de Mass para scripting.&lt;/p&gt;
&lt;p&gt;Nos leemos!&lt;/p&gt;
&lt;p&gt;Angel &amp;ldquo;Java&amp;rdquo; Lopez 
  &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt; 
  &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1828666" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Lenguajes+de+Programaci_26002300_243_3B00_n/default.aspx">Lenguajes de Programaci&amp;#243;n</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/TDD/default.aspx">TDD</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Proyectos+de+C_26002300_243_3B00_digo+Abierto/default.aspx">Proyectos de C&amp;#243;digo Abierto</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Mass/default.aspx">Mass</category></item><item><title>Mass Lenguaje de Programación (2) Primeras Expresiones</title><link>http://msmvps.com/blogs/lopez/archive/2013/04/27/mass-lenguaje-de-programaci-243-n-2-primeras-expresiones.aspx</link><pubDate>Sat, 27 Apr 2013 13:26:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1828597</guid><dc:creator>lopez</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1828597</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2013/04/27/mass-lenguaje-de-programaci-243-n-2-primeras-expresiones.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2013/04/08/mass-lenguaje-de-programaci-243-n-1-or-237-genes.aspx"&gt;Anterior Post&amp;nbsp;&lt;/a&gt;&amp;nbsp;&lt;br /&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2013/04/28/mass-lenguaje-de-programaci-243-n-3-comandos.aspx"&gt;Siguiente Post&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Antes de ver c&amp;oacute;mo usar el lenguaje Mass (&lt;a href="http://github.com/ajlopez/Mass"&gt;ver repo&lt;/a&gt;), quisiera tratar algunos temas de implementaci&amp;oacute;n. Primero, una novedad: ahora hay una soluci&amp;oacute;n (en &lt;a href="https://github.com/ajlopez/Mass/blob/master/Src/Mass.sln"&gt;https://github.com/ajlopez/Mass/blob/master/Src/Mass.sln&lt;/a&gt;) que puede compilarse con alg&amp;uacute;n Visual Studio C# Express, de libre bajada e instalaci&amp;oacute;n.&lt;/p&gt;
&lt;p&gt;La soluci&amp;oacute;n Mass tiene un proyecto de librer&amp;iacute;a de clases. Ah&amp;iacute; hay un namespace dedicado a expresiones:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/mass0201.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;Una expresi&amp;oacute;n es algo que cumple con IExpression:&lt;/p&gt;
&lt;pre style="background-color:black;width:600px;color:white;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;
&lt;span style="color:orange;"&gt;public&lt;/span&gt; &lt;span style="color:orange;"&gt;interface&lt;/span&gt; IExpression
&lt;span style="color:cyan;"&gt;{&lt;/span&gt;
	&lt;span style="color:orange;"&gt;object&lt;/span&gt; Evaluate&lt;span style="color:cyan;"&gt;(&lt;/span&gt;Context context&lt;span style="color:cyan;"&gt;);&lt;/span&gt;
&lt;span style="color:cyan;"&gt;}&lt;/span&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Un Context mantiene un diccionario de nombre/valor, para guardar las variables actuales:&lt;/p&gt;
&lt;pre style="background-color:black;width:600px;color:white;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;
&lt;span style="color:orange;"&gt;public&lt;/span&gt; &lt;span style="color:orange;"&gt;void&lt;/span&gt; Set&lt;span style="color:cyan;"&gt;(&lt;/span&gt;&lt;span style="color:orange;"&gt;string&lt;/span&gt; name&lt;span style="color:cyan;"&gt;,&lt;/span&gt; &lt;span style="color:orange;"&gt;object&lt;/span&gt; value&lt;span style="color:cyan;"&gt;)&lt;/span&gt;
&lt;span style="color:cyan;"&gt;{&lt;/span&gt;
	&lt;span style="color:orange;"&gt;this&lt;/span&gt;.values&lt;span style="color:cyan;"&gt;[&lt;/span&gt;name&lt;span style="color:cyan;"&gt;]&lt;/span&gt; = value&lt;span style="color:cyan;"&gt;;&lt;/span&gt;
&lt;span style="color:cyan;"&gt;}&lt;/span&gt;

&lt;span style="color:orange;"&gt;public&lt;/span&gt; &lt;span style="color:orange;"&gt;object&lt;/span&gt; Get&lt;span style="color:cyan;"&gt;(&lt;/span&gt;&lt;span style="color:orange;"&gt;string&lt;/span&gt; name&lt;span style="color:cyan;"&gt;)&lt;/span&gt;
&lt;span style="color:cyan;"&gt;{&lt;/span&gt;
	&lt;span style="color:orange;"&gt;if&lt;/span&gt; &lt;span style="color:cyan;"&gt;(&lt;/span&gt;&lt;span style="color:orange;"&gt;this&lt;/span&gt;.values.ContainsKey&lt;span style="color:cyan;"&gt;(&lt;/span&gt;name&lt;span style="color:cyan;"&gt;))&lt;/span&gt;
		&lt;span style="color:orange;"&gt;return&lt;/span&gt; &lt;span style="color:orange;"&gt;this&lt;/span&gt;.values&lt;span style="color:cyan;"&gt;[&lt;/span&gt;name&lt;span style="color:cyan;"&gt;];&lt;/span&gt;

	&lt;span style="color:orange;"&gt;if&lt;/span&gt; &lt;span style="color:cyan;"&gt;(&lt;/span&gt;&lt;span style="color:orange;"&gt;this&lt;/span&gt;.parent &lt;span style="color:cyan;"&gt;!&lt;/span&gt;= &lt;span style="color:orange;"&gt;null&lt;/span&gt;&lt;span style="color:cyan;"&gt;)&lt;/span&gt;
		&lt;span style="color:orange;"&gt;return&lt;/span&gt; &lt;span style="color:orange;"&gt;this&lt;/span&gt;.parent.Get&lt;span style="color:cyan;"&gt;(&lt;/span&gt;name&lt;span style="color:cyan;"&gt;);&lt;/span&gt;

	&lt;span style="color:orange;"&gt;return&lt;/span&gt; &lt;span style="color:orange;"&gt;null&lt;/span&gt;&lt;span style="color:cyan;"&gt;;&lt;/span&gt;
&lt;span style="color:cyan;"&gt;}&lt;/span&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;(vean de refil&amp;oacute;n, que soporta contextos anidados: cada contexto puede &amp;ldquo;heredar&amp;rdquo; de un contexto parent).&lt;/p&gt;
&lt;p&gt;La expresi&amp;oacute;n m&amp;aacute;s simple es la que devuelve una constante, que puede ser cualquier valor/objecto .NET:&lt;/p&gt;
&lt;pre style="background-color:black;width:600px;color:white;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;
&lt;span style="color:orange;"&gt;public&lt;/span&gt; &lt;span style="color:orange;"&gt;class&lt;/span&gt; ConstantExpression : IExpression
&lt;span style="color:cyan;"&gt;{&lt;/span&gt;
	// ...

	&lt;span style="color:orange;"&gt;private&lt;/span&gt; &lt;span style="color:orange;"&gt;object&lt;/span&gt; value&lt;span style="color:cyan;"&gt;;&lt;/span&gt;

	&lt;span style="color:orange;"&gt;public&lt;/span&gt; ConstantExpression&lt;span style="color:cyan;"&gt;(&lt;/span&gt;&lt;span style="color:orange;"&gt;object&lt;/span&gt; value&lt;span style="color:cyan;"&gt;)&lt;/span&gt;
	&lt;span style="color:cyan;"&gt;{&lt;/span&gt;
		&lt;span style="color:orange;"&gt;this&lt;/span&gt;.value = value&lt;span style="color:cyan;"&gt;;&lt;/span&gt;
	&lt;span style="color:cyan;"&gt;}&lt;/span&gt;

	&lt;span style="color:orange;"&gt;public&lt;/span&gt; &lt;span style="color:orange;"&gt;object&lt;/span&gt; Evaluate&lt;span style="color:cyan;"&gt;(&lt;/span&gt;Context context&lt;span style="color:cyan;"&gt;)&lt;/span&gt;
	&lt;span style="color:cyan;"&gt;{&lt;/span&gt;
		&lt;span style="color:orange;"&gt;return&lt;/span&gt; &lt;span style="color:orange;"&gt;this&lt;/span&gt;.value&lt;span style="color:cyan;"&gt;;&lt;/span&gt;
	&lt;span style="color:cyan;"&gt;}&lt;/span&gt;

	// ...
&lt;span style="color:cyan;"&gt;}&lt;/span&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;La siguiente expresi&amp;oacute;n m&amp;aacute;s simple es la evaluaci&amp;oacute;n de un nombre de variable en el contexto actual:&lt;/p&gt;
&lt;pre style="background-color:black;width:600px;color:white;"&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;
&lt;span style="color:orange;"&gt;public&lt;/span&gt; &lt;span style="color:orange;"&gt;class&lt;/span&gt; NameExpression : IExpression
&lt;span style="color:cyan;"&gt;{&lt;/span&gt;
	// ...
	
	&lt;span style="color:orange;"&gt;private&lt;/span&gt; &lt;span style="color:orange;"&gt;string&lt;/span&gt; name&lt;span style="color:cyan;"&gt;;&lt;/span&gt;

	&lt;span style="color:orange;"&gt;public&lt;/span&gt; NameExpression&lt;span style="color:cyan;"&gt;(&lt;/span&gt;&lt;span style="color:orange;"&gt;string&lt;/span&gt; name&lt;span style="color:cyan;"&gt;)&lt;/span&gt;
	&lt;span style="color:cyan;"&gt;{&lt;/span&gt;
		&lt;span style="color:orange;"&gt;this&lt;/span&gt;.name = name&lt;span style="color:cyan;"&gt;;&lt;/span&gt;
	&lt;span style="color:cyan;"&gt;}&lt;/span&gt;

	&lt;span style="color:orange;"&gt;public&lt;/span&gt; &lt;span style="color:orange;"&gt;object&lt;/span&gt; Evaluate&lt;span style="color:cyan;"&gt;(&lt;/span&gt;Context context&lt;span style="color:cyan;"&gt;)&lt;/span&gt;
	&lt;span style="color:cyan;"&gt;{&lt;/span&gt;
		&lt;span style="color:orange;"&gt;return&lt;/span&gt; context.Get&lt;span style="color:cyan;"&gt;(&lt;/span&gt;&lt;span style="color:orange;"&gt;this&lt;/span&gt;.name&lt;span style="color:cyan;"&gt;);&lt;/span&gt;
	&lt;span style="color:cyan;"&gt;}&lt;/span&gt;
	
	// ...
&lt;span style="color:cyan;"&gt;}&lt;/span&gt;
&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Es necesario especificar el contexto (por ejemplo, el contexto de la funci&amp;oacute;n actual, de una clausura, del objeto actual, del m&amp;oacute;dulo actual, etc), porque un mismo nombre puede tener distintas variables asociadas, como pasa en otros lenguajes.&lt;/p&gt;
&lt;p&gt;Como siempre, cada una de estas clases (Expresiones, Contexto, &amp;hellip;) fue armada usando el flujo de trabajo de TDD (ver el proyecto de tests, y la &lt;a href="https://github.com/ajlopez/Mass/commits/master"&gt;historia de commits del repo&lt;/a&gt; donde dej&amp;eacute; evidencia de c&amp;oacute;mo fue el desarrollo en el tiempo).&lt;/p&gt;
&lt;p&gt;Pr&amp;oacute;ximos posts: algunas expresiones adicionales, comandos, usando Mass para scripting, usando Mass desde nuestro programa .NET, etc..&lt;/p&gt;
&lt;p&gt;Nos leemos!&lt;/p&gt;
&lt;p&gt;Angel &amp;ldquo;Java&amp;rdquo; Lopez 
  &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt; 
  &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1828597" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Lenguajes+de+Programaci_26002300_243_3B00_n/default.aspx">Lenguajes de Programaci&amp;#243;n</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/TDD/default.aspx">TDD</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Proyectos+de+C_26002300_243_3B00_digo+Abierto/default.aspx">Proyectos de C&amp;#243;digo Abierto</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Mass/default.aspx">Mass</category></item><item><title>Node.js, Charlas en Buenos Aires: Aplicaciones Distribuidas; Introducción a ZMQ</title><link>http://msmvps.com/blogs/lopez/archive/2013/04/24/node-js-charlas-en-buenos-aires-aplicaciones-distribuidas-introducci-243-n-a-zmq.aspx</link><pubDate>Wed, 24 Apr 2013 10:16:49 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1828225</guid><dc:creator>lopez</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1828225</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2013/04/24/node-js-charlas-en-buenos-aires-aplicaciones-distribuidas-introducci-243-n-a-zmq.aspx#comments</comments><description>&lt;p&gt;La gente de Node.js Argentina prepara una nueva reunión para el próximo martes 30 de abril:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.meetup.com/NodeJS-Argentina/events/112809892/"&gt;http://www.meetup.com/NodeJS-Argentina/events/112809892/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Revisen el horario, la idea era que fuera de 18:30 a 21hs en la zona de Congreso, Buenos Aires, cerca de subtes y multitud de colectivos.&lt;/p&gt;  &lt;p&gt;Además de reunión, habrá dos charlas. Una de Fernando Alonso, sobre Introducción a ZMQ con Node, no tengo el temario en detalle. Y además, estaré dando otra charla, sobre uno de mis temas preferidos: aplicaciones distribuidas, en este caso con Node.js. Puede ver &lt;a href="http://msmvps.com/blogs/lopez/archive/tags/Aplicaciones+Distribuidas/default.aspx"&gt;mis posts sobre aplicaciones distribuidas&lt;/a&gt; en general. Pero esta vez, trataré el tema desde Node.js, que me parece una plataforma excelente para experimentar y trabajar con este tipo de aplicaciones. Algo ya adelanté el año pasado en mi charla del Día del Programador:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2012/09/11/experimentos-distribuidos.aspx"&gt;Experimentos distribuidos&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Ahí encontraran algunos enlaces sobre lo que estoy probando y armando. Algo más lateral, pero para explicar mi interés en el tema distribuido y su relación con otros temas que ven que trato frecuentemente por acá:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2013/02/11/programming_2D00_languages_2D00_distributed_2D00_computing_2D00_and_2D00_artificial_2D00_intelligence.aspx"&gt;Lenguajes de Programación, Computación Distribuida, Inteligencia Artificial&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Espero poder transmitir algo de todo esto en la charla del Node.js meetup. Recuerden de revisar la página del grupo, que se vienen más reuniones con otros temas (por ejemplo, la anterior fue sobre Node.js y Raspberry Pi).&lt;/p&gt;  &lt;p&gt;Nos leemos!&lt;/p&gt;  &lt;p&gt;Angel “Java” Lopez   &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1828225" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/Argentina/default.aspx">Argentina</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Aplicaciones+Distribuidas/default.aspx">Aplicaciones Distribuidas</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/NodeJs/default.aspx">NodeJs</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Buenos+Aires/default.aspx">Buenos Aires</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Reuniones/default.aspx">Reuniones</category></item><item><title>Nuevo Podcast de 32minutos.net: Agilidad con Martín Salías</title><link>http://msmvps.com/blogs/lopez/archive/2013/04/22/nuevo-podcast-de-32minutos-net-agilidad-con-mart-237-n-sal-237-as.aspx</link><pubDate>Mon, 22 Apr 2013 10:21:20 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1827998</guid><dc:creator>lopez</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1827998</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2013/04/22/nuevo-podcast-de-32minutos-net-agilidad-con-mart-237-n-sal-237-as.aspx#comments</comments><description>&lt;p&gt;El sábado pasado apareció publicado un podcast en el que participé con &lt;a href="http://twitter.com/martinsalias"&gt;@martinsalias&lt;/a&gt;, conversando sobre agilidad en general. Fue gracias a la gente de &lt;a href="http://www.32minutos.net/"&gt;http://www.32minutos.net/&lt;/a&gt;, &lt;a href="http://twitter.com/roundcrisis"&gt;@roundcrisis&lt;/a&gt;, &lt;a href="http://twitter.com/dvilchez"&gt;@dvilchez&lt;/a&gt;, &lt;a href="http://twitter.com/jorgegamba"&gt;@jorgegamba&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;El podcast en:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.32minutos.net/?p=119"&gt;07×03 Agile con Ángel Java López y Martín Salias&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Hemos charlado de todo, los principales temas:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Disposición al cambio &lt;/li&gt;    &lt;li&gt;Entrega continua &lt;/li&gt;    &lt;li&gt;Retrasar la toma de decisiones &lt;/li&gt;    &lt;li&gt;Product owner &lt;/li&gt;    &lt;li&gt;Empresas y administración &lt;/li&gt;    &lt;li&gt;Equipos &lt;/li&gt;    &lt;li&gt;Stand up &lt;/li&gt;    &lt;li&gt;Retrospectiva &lt;/li&gt;    &lt;li&gt;Equipos remotos&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Vean que Martín toco varios de esos temas, contando experiencias en proyectos y equipos reales. Yo continué sobre la facilidad que da lo ágil para abrazar el cambio, y tomar decisiones ALAP (“as late as possible”). Si tienen alguna duda, le preguntan a &lt;a href="http://twitter.com/martinsalias"&gt;@martinsalias&lt;/a&gt; ;-)&lt;/p&gt;  &lt;p&gt;Gracias a 32minutos!&lt;/p&gt;  &lt;p&gt;Nos leemos!&lt;/p&gt;  &lt;p&gt;Angel “Java” Lopez   &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1827998" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+de+Software/default.aspx">Desarrollo de Software</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+Agil/default.aspx">Desarrollo Agil</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Reuniones/default.aspx">Reuniones</category></item><item><title>Inteligencia Artifical en C# (1) Primeros Agentes</title><link>http://msmvps.com/blogs/lopez/archive/2013/04/21/inteligencia-artifical-en-c-1-primeros-agentes.aspx</link><pubDate>Sun, 21 Apr 2013 09:04:59 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1827934</guid><dc:creator>lopez</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1827934</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2013/04/21/inteligencia-artifical-en-c-1-primeros-agentes.aspx#comments</comments><description>&lt;p&gt;Ayer comencé a implementar ejemplos del libro Artificial Intelligence: A Modern Approach, de &lt;a href="http://www.cs.berkeley.edu/~russell"&gt;Stuart Russell&lt;/a&gt; y &lt;a href="http://www.norvig.com/"&gt;Peter Norvig&lt;/a&gt;. Ver el sitio del libro&lt;/p&gt;  &lt;p&gt;&lt;a href="http://aima.cs.berkeley.edu/"&gt;http://aima.cs.berkeley.edu/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Hay implementaciones en distintos lenguajes:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://aima.cs.berkeley.edu/code.html"&gt;http://aima.cs.berkeley.edu/code.html&lt;/a&gt; (hay en Python, Java, C#, Prolog, Lisp, … )&lt;/p&gt;  &lt;p&gt;Mi implementación en&lt;/p&gt;  &lt;p&gt;&lt;a href="https://github.com/ajlopez/SharpAima"&gt;https://github.com/ajlopez/SharpAima&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Quiero ir armándola con TDD. Por ahora me baso en la versión en Python, pero puede que también vea la versión en Java, debido a las diferencias de los lenguajes: C# y Java son lenguajes tipados.&lt;/p&gt;  &lt;p&gt;La versión que presento hoy es la 0.0.1&lt;/p&gt;  &lt;p&gt;&lt;a href="https://github.com/ajlopez/SharpAima/tree/0.0.1"&gt;https://github.com/ajlopez/SharpAima/tree/0.0.1&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Por cada post iré “taggeando” una nueva versión. Mi primer código trata de implementar los primeros agentes descriptos en el capítulo 2. Me basé en el código de:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://aima-python.googlecode.com/svn/trunk/agents.py"&gt;http://aima-python.googlecode.com/svn/trunk/agents.py&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Tengo una solución con dos proyectos: uno de clases y otro de tests:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/sharpaima0101.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;La idea es tener agentes en un ambiente:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/sharpaima0102.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;(Adaptado de la figura 2.1 del libro)&lt;/p&gt;  &lt;p&gt;El agente recibe percepciones y genera acciones. La primera implementación es:&lt;/p&gt;  &lt;pre style="background-color:black;color:white;"&gt;
&lt;span style="color:orange;"&gt;public&lt;/span&gt; &lt;span style="color:orange;"&gt;abstract&lt;/span&gt; &lt;span style="color:orange;"&gt;class&lt;/span&gt; Agent&lt;span style="color:cyan;"&gt;&amp;lt;&lt;/span&gt;TLocation&lt;span style="color:cyan;"&gt;,&lt;/span&gt; TPerception&lt;span style="color:cyan;"&gt;,&lt;/span&gt; TAction&lt;span style="color:cyan;"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color:cyan;"&gt;{&lt;/span&gt;
	&lt;span style="color:orange;"&gt;public&lt;/span&gt; TLocation Location &lt;span style="color:cyan;"&gt;{&lt;/span&gt; get&lt;span style="color:cyan;"&gt;;&lt;/span&gt; set&lt;span style="color:cyan;"&gt;;&lt;/span&gt; &lt;span style="color:cyan;"&gt;}&lt;/span&gt;

	&lt;span style="color:orange;"&gt;public&lt;/span&gt; &lt;span style="color:orange;"&gt;int&lt;/span&gt; Performance &lt;span style="color:cyan;"&gt;{&lt;/span&gt; get&lt;span style="color:cyan;"&gt;;&lt;/span&gt; set&lt;span style="color:cyan;"&gt;;&lt;/span&gt; &lt;span style="color:cyan;"&gt;}&lt;/span&gt;

	&lt;span style="color:orange;"&gt;public&lt;/span&gt; &lt;span style="color:orange;"&gt;abstract&lt;/span&gt; TAction GetAction&lt;span style="color:cyan;"&gt;(&lt;/span&gt;TPerception perception&lt;span style="color:cyan;"&gt;);&lt;/span&gt;
&lt;span style="color:cyan;"&gt;}&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Y las implementaciones en concreto son de un agente robot máquina aspiradora (VacuumAgent y variantes).&lt;/p&gt;

&lt;p&gt;Vean la historia del proyecto, cómo fue evolucionando desde TDD. Primero implementé un agente concreto, y luego fue surgiendo la abstracción de arriba. Noten que en C# tenemos que apelar a algo tipado, y de ahí el uso de tipos genéricos: un tipo de agente concreto se define dando el tipo de lugares (location) que maneja (por ejemplo, una posición X, Y, a implementar en la próxima versión), el tipo de percepciones que recibe (ej: “estoy en lugar A y el lugar está limpio”), y el tipo de acciones (“Limpiar”, “Ir a la Derecha”, … ). En Python es más simple, por no tener tipos.&lt;/p&gt;

&lt;p&gt;Nos leemos!&lt;/p&gt;

&lt;p&gt;Angel “Java” Lopez 
  &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt; 

  &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1827934" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Inteligencia+Artificial/default.aspx">Inteligencia Artificial</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Proyectos+de+C_26002300_243_3B00_digo+Abierto/default.aspx">Proyectos de C&amp;#243;digo Abierto</category></item><item><title>TDD Kata (4): La cortadora de césped</title><link>http://msmvps.com/blogs/lopez/archive/2013/04/20/tdd-kata-4-la-cortadora-de-c-233-sped.aspx</link><pubDate>Sat, 20 Apr 2013 17:42:46 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1827888</guid><dc:creator>lopez</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1827888</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2013/04/20/tdd-kata-4-la-cortadora-de-c-233-sped.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2013/04/15/tdd-kata-3-tatet-237-tomek.aspx"&gt;Anterior Post&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Como comentaba en el anterior post, hace una semana participé de la ronda preliminar del &lt;a href="https://code.google.com/codejam"&gt;Google Code Jam&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;El ejercicio B fue el Lawnmover:&lt;/p&gt;  &lt;p&gt;&lt;a title="https://code.google.com/codejam/contest/2270488/dashboard#s=p1" href="https://code.google.com/codejam/contest/2270488/dashboard#s=p1"&gt;https://code.google.com/codejam/contest/2270488/dashboard#s=p1&lt;/a&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Problem &lt;/p&gt;    &lt;p&gt;Alice and Bob have a lawn in front of their house, shaped like an N metre by M metre rectangle. Each year, they try to cut the lawn in some interesting pattern. They used to do their cutting with shears, which was very time-consuming; but now they have a new automatic lawnmower with multiple settings, and they want to try it out. &lt;/p&gt;    &lt;p&gt;The new lawnmower has a height setting - you can set it to any height h between 1 and 100 millimetres, and it will cut all the grass higher than h it encounters to height h. You run it by entering the lawn at any part of the edge of the lawn; then the lawnmower goes in a straight line, perpendicular to the edge of the lawn it entered, cutting grass in a swath 1m wide, until it exits the lawn on the other side. The lawnmower&amp;#39;s height can be set only when it is not on the lawn. &lt;/p&gt;    &lt;p&gt;Alice and Bob have a number of various patterns of grass that they could have on their lawn. For each of those, they want to know whether it&amp;#39;s possible to cut the grass into this pattern with their new lawnmower. Each pattern is described by specifying the height of the grass on each 1m x 1m square of the lawn. &lt;/p&gt;    &lt;p&gt;The grass is initially 100mm high on the whole lawn.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Lo pude solucionar, ver:&lt;/p&gt;  &lt;p&gt;&lt;a href="https://github.com/ajlopez/TddOnTheRocks/tree/master/Lawnmover"&gt;https://github.com/ajlopez/TddOnTheRocks/tree/master/Lawnmover&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Como siempre, la historia, prácticamente por test:&lt;/p&gt;  &lt;p&gt;&lt;a href="https://github.com/ajlopez/TddOnTheRocks/commits/master/Lawnmover"&gt;https://github.com/ajlopez/TddOnTheRocks/commits/master/Lawnmover&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Pude resolver el primer “set” pequeño de problemas que me entregó Google. No pude resolver el “set” grande, porque me equivoqué de algoritmo a seguir, y no cumplí en resolverlo en 8 minutos. Mi algoritmo inicial (pueden ver los commits) resolvía el problema partiendo de los números mayores. Lo cambié para que comenzara a resolver los números menores primero, y ahí anduvo más rápido. Un tema que aprendí: algunos problemas de Google Code Jam son difíciles de probar a mano, como no tenemos los casos de uso (entrada y salida esperada), hay que trabajar con cuidado en esos temas.&lt;/p&gt;  &lt;p&gt;Nos leemos!&lt;/p&gt;  &lt;p&gt;Angel “Java” Lopez   &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1827888" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+Agil/default.aspx">Desarrollo Agil</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/TDD/default.aspx">TDD</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Google/default.aspx">Google</category></item><item><title>TDD Kata (3): TaTeTíTomek</title><link>http://msmvps.com/blogs/lopez/archive/2013/04/15/tdd-kata-3-tatet-237-tomek.aspx</link><pubDate>Mon, 15 Apr 2013 10:41:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1827351</guid><dc:creator>lopez</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1827351</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2013/04/15/tdd-kata-3-tatet-237-tomek.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2013/04/12/tdd-kata-2-lenguaje-alien-237-gena.aspx"&gt;Anterior Post&amp;nbsp;&lt;/a&gt;&amp;nbsp;&lt;br /&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2013/04/20/tdd-kata-4-la-cortadora-de-c-233-sped.aspx"&gt;Siguiente Post&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;El s&amp;aacute;bado pasado estuve participando del Google Code Jam. El ejercicio A fue TicTacToeTomek:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://code.google.com/codejam/contest/2270488/dashboard"&gt;https://code.google.com/codejam/contest/2270488/dashboard&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;h5&gt;Problem&lt;/h5&gt;
&lt;p&gt;Tic-Tac-Toe-Tomek is a game played on a 4 x 4 square board. The board starts empty, except that a single &amp;#39;T&amp;#39; symbol may appear in one of the 16 squares. There are two players: X and O. They take turns to make moves, with X starting. In each move a player puts her symbol in one of the empty squares. Player X&amp;#39;s symbol is &amp;#39;X&amp;#39;, and player O&amp;#39;s symbol is &amp;#39;O&amp;#39;.&lt;/p&gt;
&lt;p&gt;After a player&amp;#39;s move, if there is a row, column or a diagonal containing 4 of that player&amp;#39;s symbols, or containing 3 of her symbols and the &amp;#39;T&amp;#39; symbol, she wins and the game ends. Otherwise the game continues with the other player&amp;#39;s move. If all of the fields are filled with symbols and nobody won, the game ends in a draw. See the sample input for examples of various winning positions.&lt;/p&gt;
&lt;p&gt;Given a 4 x 4 board description containing &amp;#39;X&amp;#39;, &amp;#39;O&amp;#39;, &amp;#39;T&amp;#39; and &amp;#39;.&amp;#39; characters (where &amp;#39;.&amp;#39; represents an empty square), describing the current state of a game, determine the status of the Tic-Tac-Toe-Tomek game going on. The statuses to choose from are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;quot;X won&amp;quot; (the game is over, and X won) &lt;/li&gt;
&lt;li&gt;&amp;quot;O won&amp;quot; (the game is over, and O won) &lt;/li&gt;
&lt;li&gt;&amp;quot;Draw&amp;quot; (the game is over, and it ended in a draw) &lt;/li&gt;
&lt;li&gt;&amp;quot;Game has not completed&amp;quot; (the game is not over yet)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If there are empty cells, and the game is not over, you should output &amp;quot;Game has not completed&amp;quot;, even if the outcome of the game is inevitable.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Se nos da un archivo de entrada con distintas posiciones de tablero, y tenemos que producir una salida diciendo si X gan&amp;oacute;, O gan&amp;oacute;, empate, o todav&amp;iacute;a falta completar el juego.&lt;/p&gt;
&lt;p&gt;Lo resolv&amp;iacute; usando TDD, y pueden ver el resultado en:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/ajlopez/TddOnTheRocks/tree/master/TicTacToeTomek"&gt;https://github.com/ajlopez/TddOnTheRocks/tree/master/TicTacToeTomek&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Y la historia, pr&amp;aacute;cticamente con commits por tests, en:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/ajlopez/TddOnTheRocks/commits/master/TicTacToeTomek"&gt;https://github.com/ajlopez/TddOnTheRocks/commits/master/TicTacToeTomek&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Fue un ejercicio sencillo, y bien adaptado para TDD. Google me acept&amp;oacute; tanto la soluci&amp;oacute;n de un archivo de entrada peque&amp;ntilde;o, y de otro grande. Tengo que escribir sobre los otros ejercicios (B, C, D), que se complican por:&lt;/p&gt;
&lt;p&gt;- Hay que resolver el problema en un tiempo adecuado&lt;/p&gt;
&lt;p&gt;- El algoritmo a implementar no es evidente, o no se puede implementar &amp;ldquo;de a poco&amp;rdquo;, con &amp;ldquo;baby steps&amp;rdquo;, con lo que a veces hay grandes refactor&lt;/p&gt;
&lt;p&gt;- A veces, dada la entrada, es dif&amp;iacute;cil calcular la salida correcta, a&amp;uacute;n manualmente. Entonces, muchos de mis intentos fueron rechazados al subir el archivo soluci&amp;oacute;n a Google.&lt;/p&gt;
&lt;p&gt;Nos leemos!&lt;/p&gt;
&lt;p&gt;Angel &amp;ldquo;Java&amp;rdquo; Lopez   &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1827351" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+Agil/default.aspx">Desarrollo Agil</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/TDD/default.aspx">TDD</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Google/default.aspx">Google</category></item><item><title>TDD Kata (2): Lenguaje Alienígena</title><link>http://msmvps.com/blogs/lopez/archive/2013/04/12/tdd-kata-2-lenguaje-alien-237-gena.aspx</link><pubDate>Fri, 12 Apr 2013 13:03:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1827165</guid><dc:creator>lopez</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1827165</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2013/04/12/tdd-kata-2-lenguaje-alien-237-gena.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2013/04/10/tdd-kata-1-piedra-papel-tijera-lagarto-spock.aspx"&gt;Anterior Post&lt;/a&gt;&amp;nbsp;&lt;br /&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2013/04/15/tdd-kata-3-tatet-237-tomek.aspx"&gt;Siguiente Post&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;En la lista &lt;a href="https://groups.google.com/group/tddev-sp?hl=es&amp;amp;pli=1"&gt;TDDev en espa&amp;ntilde;ol&lt;/a&gt; se mencion&amp;oacute; hace poco el &lt;a href="https://code.google.com/codejam/"&gt;Google Code Jam&lt;/a&gt;. Uno de los &lt;a href="https://code.google.com/codejam/contests.html"&gt;pasados desaf&amp;iacute;os&lt;/a&gt; de esa competencia, es el &lt;a href="https://code.google.com/codejam/contest/90101/dashboard#s=p0"&gt;Alien Language&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;After years of study, scientists at Google Labs have discovered an alien language transmitted from a faraway planet. The alien language is very unique in that every word consists of exactly L lowercase letters. Also, there are exactly D words in this language. &lt;/p&gt;
&lt;p&gt;Once the dictionary of all the words in the alien language was built, the next breakthrough was to discover that the aliens have been transmitting messages to Earth for the past decade. Unfortunately, these signals are weakened due to the distance between our two planets and some of the words may be misinterpreted. In order to help them decipher these messages, the scientists have asked you to devise an algorithm that will determine the number of possible interpretations for a given pattern. &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A pattern consists of exactly L tokens. Each token is either a single lowercase letter (the scientists are very sure that this is the letter) or a group of unique lowercase letters surrounded by parenthesis ( and ). For example: (ab)d(dc) means the first letter is either a or b, the second letter is definitely d and the last letter is either d or c. Therefore, the pattern (ab)d(dc) can stand for either one of these 4 possibilities: add, adc, bdd, bdc.&lt;/p&gt;
&lt;p&gt;Me gust&amp;oacute; como problema. Vean en la p&amp;aacute;gina que tambi&amp;eacute;n se pide leer un archivo de entrada con las palabras y los patrones a procesar. Se pueden bajar archivos de entrada desde la p&amp;aacute;gina del problema, y se debe entregar un archivo de salida para que Google nos diga si est&amp;aacute; bien. Hoy escrib&amp;iacute; una soluci&amp;oacute;n usando TDD:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/ajlopez/TddOnTheRocks/tree/master/AlienLanguage"&gt;https://github.com/ajlopez/TddOnTheRocks/tree/master/AlienLanguage&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Pueden ver la historia de los commits, pr&amp;aacute;cticamente por test:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/ajlopez/TddOnTheRocks/commits/master/AlienLanguage"&gt;https://github.com/ajlopez/TddOnTheRocks/commits/master/AlienLanguage&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Una de las &amp;uacute;ltimas cosas que hice fue refactorizar, para mejorar, si fuera necesario, la detecci&amp;oacute;n de palabras que cumplen con un patr&amp;oacute;n. Podr&amp;iacute;a mejorarlo m&amp;aacute;s, por ejemplo, haciendo que en vez de tener una lista de palabras, mantener un &amp;aacute;rbol de palabras con ramas por letra, como hice en &lt;a href="https://github.com/ajlopez/SimpleBoggle"&gt;SimpleBoggle&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Al final, escrib&amp;iacute; un programa de consola que acepta un archivo de entrada y produce un archivo de salida como pide Google. Me baj&amp;eacute; un archivo grande de Google, lo proces&amp;eacute;, y la salida obtenida lo sub&amp;iacute; a Google, para que lo revise autom&amp;aacute;tica. Y di&amp;oacute; bien:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/tddkata0201.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;Otro triunfo de TDD ;-)&lt;/p&gt;
&lt;p&gt;Nos leemos!&lt;/p&gt;
&lt;p&gt;Angel &amp;ldquo;Java&amp;rdquo; Lopez   &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1827165" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+Agil/default.aspx">Desarrollo Agil</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/TDD/default.aspx">TDD</category></item><item><title>TDD Kata (1): Piedra Papel Tijera Lagarto Spock</title><link>http://msmvps.com/blogs/lopez/archive/2013/04/10/tdd-kata-1-piedra-papel-tijera-lagarto-spock.aspx</link><pubDate>Wed, 10 Apr 2013 14:43:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1826997</guid><dc:creator>lopez</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1826997</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2013/04/10/tdd-kata-1-piedra-papel-tijera-lagarto-spock.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2013/04/12/tdd-kata-2-lenguaje-alien-237-gena.aspx"&gt;Siguiente Post&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;En estos d&amp;iacute;as, le&amp;iacute; en la lista de &lt;a href="https://groups.google.com/group/tddev-sp?hl=es&amp;amp;pli=1"&gt;TDDev&lt;/a&gt; en espa&amp;ntilde;ol una &lt;a href="https://groups.google.com/group/tddev-sp/browse_thread/thread/3b1877112d2c5de2?hl=es"&gt;nueva kata&lt;/a&gt; publicada en el blog de &lt;a href="https://aprendiendotdd.wordpress.com/"&gt;Aprendiendo TDD&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://aprendiendotdd.wordpress.com/2013/04/08/kata-tdd-piedra-papel-tijera-lagarto-spock/"&gt;Piedra Papel Tijera Lagarto Spock&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;basado en el problema publicado en&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.solveet.com/exercises/Kata-Piedra-Papel-Tijera-Lagarto-Spock/20" title="http://www.solveet.com/exercises/Kata-Piedra-Papel-Tijera-Lagarto-Spock/20"&gt;http://www.solveet.com/exercises/Kata-Piedra-Papel-Tijera-Lagarto-Spock/20&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Tom&amp;eacute; la descripci&amp;oacute;n del art&amp;iacute;culo de la Wikipedia:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Rock-paper-scissors-lizard-Spock"&gt;http://en.wikipedia.org/wiki/Rock-paper-scissors-lizard-Spock&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The rules of Rock-paper-scissors-lizard-Spock are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Scissors"&gt;Scissors&lt;/a&gt; cut &lt;a href="http://en.wikipedia.org/wiki/Paper"&gt;paper&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Paper covers &lt;a href="http://en.wikipedia.org/wiki/Rock_(geology)"&gt;rock&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Rock crushes &lt;a href="http://en.wikipedia.org/wiki/Lizard"&gt;lizard&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Lizard poisons &lt;a href="http://en.wikipedia.org/wiki/Spock"&gt;Spock&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Spock smashes (or melts) scissors &lt;/li&gt;
&lt;li&gt;Scissors decapitate lizard &lt;/li&gt;
&lt;li&gt;Lizard eats paper &lt;/li&gt;
&lt;li&gt;Paper disproves Spock &lt;/li&gt;
&lt;li&gt;Spock vaporizes rock &lt;/li&gt;
&lt;li&gt;Rock breaks scissors&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Y entonces me puse a codificarla usando TDD. Pueden ver el resultado en:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/ajlopez/TddOnTheRocks/tree/master/SpockGame"&gt;https://github.com/ajlopez/TddOnTheRocks/tree/master/SpockGame&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;La historia, casi por tests:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/ajlopez/TddOnTheRocks/commits/master/SpockGame"&gt;https://github.com/ajlopez/TddOnTheRocks/commits/master/SpockGame&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/tddkata0103.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;Vean el primer test/commit: todav&amp;iacute;a no compilaba. Luego, comenz&amp;oacute; a compilar pero con estado rojo. Luego, lo pas&amp;eacute; a verde y as&amp;iacute;.&lt;/p&gt;
&lt;p&gt;Tambi&amp;eacute;n decid&amp;iacute; ter dos tests por cada combinaci&amp;oacute;n de arriba: una que prueba que Scissors cut Paper, y otra que prueba Paper is cut by Scissors&lt;/p&gt;
&lt;p&gt;El dise&amp;ntilde;o inicial fue basado en:&lt;/p&gt;
&lt;p&gt;- Tener una instancia de Game (la alternativa era tener la clase, sin instancia)&lt;/p&gt;
&lt;p&gt;- Tener una enumeraci&amp;oacute;n para las opciones de juego (Play.Scissors, etc&amp;hellip;)&lt;/p&gt;
&lt;p&gt;- Tener una enumeraci&amp;oacute;n para el resultado (PlayResult.Tie, PlayResult.FirstPlayer&amp;hellip;)&lt;/p&gt;
&lt;p&gt;En vez de tener resultado de juego, podr&amp;iacute;a haber puesto un m&amp;eacute;todo que comparara dos opciones de juego, y devolviera cu&amp;aacute;l es la que gana. Incluso hoy podr&amp;iacute;a poner este m&amp;eacute;todo como refactorizaci&amp;oacute;n. &lt;/p&gt;
&lt;p&gt;Vean la &amp;uacute;ltima refactorizaci&amp;oacute;n: podr&amp;iacute;a haber dejado el c&amp;oacute;digo de implementaci&amp;oacute;n tal como estaba, con &lt;a href="https://github.com/ajlopez/TddOnTheRocks/blob/8bbf7cdf7978a067574c4aaed250a2cb29c852f7/SpockGame/SpockGame/Game.cs"&gt;if para decidir cu&amp;aacute;ndo gana el primer jugador&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/tddkata0101.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;Por esta &lt;a href="https://github.com/ajlopez/TddOnTheRocks/blob/723f9dc6c8755ab7f56a4160cf9ca6f3dabe7ec0/SpockGame/SpockGame/Game.cs"&gt;otra forma&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/tddkata0102.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;sugerida por el art&amp;iacute;culo de la Wikipedia:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;One way to remember the rules is to remember the standard &amp;quot;rock-paper-scissors&amp;quot; ordering, where each gesture defeats the one before it, and is defeated by the one after. But then add the two novel gestures near the word they approximately rhyme with:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Rock &lt;/li&gt;
&lt;li&gt;Spock &lt;/li&gt;
&lt;li&gt;Paper &lt;/li&gt;
&lt;li&gt;Lizard &lt;/li&gt;
&lt;li&gt;Scissors&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In this expanded list, each gesture is defeated by the following &lt;i&gt;two&lt;/i&gt; options, and defeats the preceding two.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Nos leemos!&lt;/p&gt;
&lt;p&gt;Angel &amp;ldquo;Java&amp;rdquo; Lopez   &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1826997" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+Agil/default.aspx">Desarrollo Agil</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/TDD/default.aspx">TDD</category></item><item><title>Mass Lenguaje de Programación (1) Orígenes</title><link>http://msmvps.com/blogs/lopez/archive/2013/04/08/mass-lenguaje-de-programaci-243-n-1-or-237-genes.aspx</link><pubDate>Mon, 08 Apr 2013 10:43:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1826814</guid><dc:creator>lopez</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1826814</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2013/04/08/mass-lenguaje-de-programaci-243-n-1-or-237-genes.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2013/04/27/mass-lenguaje-de-programaci-243-n-2-primeras-expresiones.aspx"&gt;Siguiente Post&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Durante estos d&amp;iacute;as, estuve trabajando en la implementaci&amp;oacute;n de un lenguaje interpretado, sobre C#, llamado Mass (dedicado al bueno de &lt;a href="http://twitter.com/martinsalias"&gt;@MArtinSaliaS&lt;/a&gt;):&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/ajlopez/Mass"&gt;https://github.com/ajlopez/Mass&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/mass0101.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;La soluci&amp;oacute;n actual se compone de tres proyectos: una librer&amp;iacute;a de clases, sus tests, y un programa de consola, mass.exe, para lanzar programas Mass&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/mass0102.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;Pueden lanzar un programa escrito en un archivo hello.ms con&lt;/p&gt;
&lt;pre style="background-color:black;width:600px;color:white;"&gt;mass hello.ms&lt;/pre&gt;
&lt;p&gt;El cl&amp;aacute;sico Hello world es entonces&lt;/p&gt;
&lt;pre style="background-color:black;width:600px;color:white;"&gt;println&lt;span style="color:cyan;"&gt;(&lt;/span&gt;&lt;span style="color:lightgreen;"&gt;&amp;quot;Hello, world&amp;quot;&lt;/span&gt;&lt;span style="color:cyan;"&gt;)&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Un ejemplo con clases y objetos&lt;/p&gt;
&lt;pre style="background-color:black;width:600px;color:white;"&gt;&lt;span style="color:orange;"&gt;class&lt;/span&gt; Person
	&lt;span style="color:orange;"&gt;define&lt;/span&gt; initialize&lt;span style="color:cyan;"&gt;(&lt;/span&gt;firstname&lt;span style="color:cyan;"&gt;,&lt;/span&gt; lastname&lt;span style="color:cyan;"&gt;)&lt;/span&gt;
		self.firstname = firstname
		self.lastname = lastname
	&lt;span style="color:orange;"&gt;end&lt;/span&gt;
	
	&lt;span style="color:orange;"&gt;define&lt;/span&gt; getName&lt;span style="color:cyan;"&gt;()&lt;/span&gt;
		&lt;span style="color:orange;"&gt;return&lt;/span&gt; self.lastname + &lt;span style="color:lightgreen;"&gt;&amp;quot;, &amp;quot;&lt;/span&gt; + self.firstname
	&lt;span style="color:orange;"&gt;end&lt;/span&gt;
&lt;span style="color:orange;"&gt;end&lt;/span&gt;

adam = new Person&lt;span style="color:cyan;"&gt;(&lt;/span&gt;&lt;span style="color:lightgreen;"&gt;&amp;quot;Adam&amp;quot;&lt;/span&gt;&lt;span style="color:cyan;"&gt;,&lt;/span&gt; &lt;span style="color:lightgreen;"&gt;&amp;quot;TheFirst&amp;quot;&lt;/span&gt;&lt;span style="color:cyan;"&gt;)&lt;/span&gt;

println&lt;span style="color:cyan;"&gt;(&lt;/span&gt;adam.getName&lt;span style="color:cyan;"&gt;())&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Un ejemplo con acceso a tipos y objectos .NET:&lt;/p&gt;
&lt;pre style="background-color:black;width:600px;color:white;"&gt;dirinfo = new System.IO.DirectoryInfo&lt;span style="color:cyan;"&gt;(&lt;/span&gt;&lt;span style="color:lightgreen;"&gt;&amp;quot;.&amp;quot;&lt;/span&gt;&lt;span style="color:cyan;"&gt;)&lt;/span&gt;

&lt;span style="color:orange;"&gt;for&lt;/span&gt; fileinfo in dirinfo.GetFiles&lt;span style="color:cyan;"&gt;()&lt;/span&gt;
	println&lt;span style="color:cyan;"&gt;(&lt;/span&gt;fileinfo.Name&lt;span style="color:cyan;"&gt;)&lt;/span&gt;
&lt;span style="color:orange;"&gt;end&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;La idea es (como en AjSharp y otras implementaciones) tener un lenguaje din&amp;aacute;mico montado sobre un lenguaje/librer&amp;iacute;a de clases. Y poder acceder a esa librer&amp;iacute;a de clases desde el nuevo lenguaje. Me llev&amp;oacute; a escribir Mass de la forma en que lo hice, el haber trabajado antes en:&lt;/p&gt;
&lt;p&gt;- Implementar Python en C# (ver &lt;a href="https://github.com/ajlopez/PythonSharp"&gt;PythonSharp&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;- Implementar Ruby en C# (ver &lt;a href="https://github.com/ajlopez/RubySharp"&gt;RubySharp&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;- El ya mencionado AjSharp (ver &lt;a href="https://github.com/ajlopez/AjSharp"&gt;repo&lt;/a&gt; y &lt;a href="http://msmvps.com/blogs/lopez/archive/tags/AjSharp/default.aspx"&gt;posts&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;Pero esta vez quer&amp;iacute;a implementar algo que tuviera sintaxis y sem&amp;aacute;ntica simple. Ya estuve pensando en eso de &amp;ldquo;simple&amp;rdquo; para implementar un compilador de lenguaje simple a JavaScript &lt;a href="http://msmvps.com/blogs/lopez/archive/2013/01/03/simplescript-1-primeras-ideas.aspx"&gt;ver SimpleScript&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Entonces con Mass me propuse evitar:&lt;/p&gt;
&lt;p&gt;- M&amp;uacute;ltiples comandos en la misma l&amp;iacute;nea (descart&amp;eacute; el &amp;lsquo;;&amp;rsquo; de Ruby)&lt;/p&gt;
&lt;p&gt;- Sintaxis basada en espacios en blanco, indentaci&amp;oacute;n (descartado Python)&lt;/p&gt;
&lt;p&gt;- Llamadas a funciones con simplemente el nombre: se necesita expl&amp;iacute;citamente los par&amp;eacute;ntesis (descartado el Ruby cl&amp;aacute;sico)&lt;/p&gt;
&lt;p&gt;- Que las clases/valores de base (por ejemplo, enteros, strings, arreglos, etc&amp;hellip;) tuvieran multitud de m&amp;eacute;todos (tienen los dados por la librer&amp;iacute;a de clases de implementaci&amp;oacute;n, en este caso .NET) (descartado Ruby, que tiene casi tantos m&amp;eacute;todos nativos como PHP)&lt;/p&gt;
&lt;p&gt;Y quise tener:&lt;/p&gt;
&lt;p&gt;- Valores funcionales, como ciudadanos de primera clase, como en JavaScript. Vean que al tener que invocar una funci&amp;oacute;n con par&amp;eacute;ntesis, si o si, entonces la variable func tiene el valor funcional, y func() es la invocaci&amp;oacute;n expl&amp;iacute;cita&lt;/p&gt;
&lt;p&gt;- Objectos din&amp;aacute;micos: cada objeto puede extenderse en cualquier momento, con nuevas variables de instancia, funciones propias del objeto, como JavaScript&lt;/p&gt;
&lt;p&gt;- Sintaxis basada en l&amp;iacute;neas: cada comando va en una l&amp;iacute;nea distinta&lt;/p&gt;
&lt;p&gt;- Sintaxis basada en palabras claves: para los comandos compuestos se usa &amp;lsquo;end&amp;rsquo; para terminar un bloque&lt;/p&gt;
&lt;p&gt;- En lo posible, una sola forma de hacer algo, en vez de m&amp;uacute;ltiples maneras&lt;/p&gt;
&lt;p&gt;- Palabras claves completas, &amp;lsquo;define&amp;rsquo; en vez de &amp;lsquo;def&amp;rsquo;&lt;/p&gt;
&lt;p&gt;- Clases con herencia simple (aunque la esencia de Mass bien puede expresarse sin clases, y usar librer&amp;iacute;as de clases ya escritas en .NET)&lt;/p&gt;
&lt;p&gt;- Modificaci&amp;oacute;n expl&amp;iacute;cita de variables fuera del alcance local (para explicar en pr&amp;oacute;ximos posts)&lt;/p&gt;
&lt;p&gt;- Alcance de variables por archivo, como en JavaScript/NodeJs/CommonJS&lt;/p&gt;
&lt;p&gt;- M&amp;oacute;dulos por archivo, con un require que permite buscar en directorios autom&amp;aacute;ticamente, como en NodeJs/CommonJS&lt;/p&gt;
&lt;p&gt;- Empaquetamiento, manejo de dependencias e instalaci&amp;oacute;n de esos m&amp;oacute;dulos usando algo ya dado, como NPM, el manejador de paquetes de Node.js&lt;/p&gt;
&lt;p&gt;En pr&amp;oacute;ximos posts, m&amp;aacute;s detalles de implementaci&amp;oacute;n, ideas que guiaron el dise&amp;ntilde;o, ejemplos. Pero ya pueden ver el c&amp;oacute;digo, y los ejemplos que est&amp;aacute;n en los tests (s&amp;iacute;, est&amp;aacute; todo construido paso a paso usando TDD).&lt;/p&gt;
&lt;p&gt;Nos leemos!&lt;/p&gt;
&lt;p&gt;Angel &amp;ldquo;Java&amp;rdquo; Lopez 
  &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt; 
  &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1826814" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Lenguajes+de+Programaci_26002300_243_3B00_n/default.aspx">Lenguajes de Programaci&amp;#243;n</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/TDD/default.aspx">TDD</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Proyectos+de+C_26002300_243_3B00_digo+Abierto/default.aspx">Proyectos de C&amp;#243;digo Abierto</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Mass/default.aspx">Mass</category></item><item><title>Escribiendo una Aplicación usando TDD (Part 6) Modificando Vistas</title><link>http://msmvps.com/blogs/lopez/archive/2013/04/07/escribiendo-una-aplicaci-243-n-usando-tdd-part-6-modificando-vistas.aspx</link><pubDate>Sun, 07 Apr 2013 11:33:39 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1826752</guid><dc:creator>lopez</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1826752</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2013/04/07/escribiendo-una-aplicaci-243-n-usando-tdd-part-6-modificando-vistas.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2011/06/27/writing_2D00_an_2D00_application_2D00_using_2D00_tdd_2D00_part_2D00_5_2D00_adding_2D00_views.aspx"&gt;Anterior Post&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;El post de hoy va a mostrar que, al haber usado MVC (Model-View-Controller) podemos modificar nuestras vistas, sin necesidad de tocar el código. Ni siquiera tenemos que recompilar, en muchos casos.&lt;/p&gt;  &lt;p&gt;Primero, una novedad: he pasado el ejemplo, paso a paso, a ASP.NET MVC 4, usando Visual Studio 2010. Y también lo pasé a mi cuenta de GitHub&lt;/p&gt;  &lt;p&gt;&lt;a href="https://github.com/ajlopez/TddAppAspNetMvc"&gt;https://github.com/ajlopez/TddAppAspNetMvc&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/apptdd0501.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;Vean que cada versión (cada entrega por post) está señalada por tags. La de este post es la 0.0.5. Siempre pueden ver en&lt;/p&gt;  &lt;p&gt;&lt;a href="https://github.com/ajlopez/TddAppAspNetMvc/commits/master"&gt;https://github.com/ajlopez/TddAppAspNetMvc/commits/master&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/apptdd0504.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;Una de las cosas nuevas que me dió esta versión de ASP.NET MVC es el soporte de Razor, ahora las vistas están escritas con Razor. Como en el anterior post, use los “wizard” de creación de vistas del propio Visual Studio, y luego las modifiqué un poco (apenas algun texto).&lt;/p&gt;  &lt;p&gt;En el paso de este post, lo que hice fue agregar &lt;a href="http://twitter.github.io/bootstrap/"&gt;Twitter Bootstrap&lt;/a&gt;:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/apptdd0503.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;Agregué estilos y javascript que necesita Bootstrap, y armé un _viewstart.chtml que le indica a Razor que todas las vistas usan un _Layout.cshtml&lt;/p&gt;  &lt;p&gt;Vean cómo se ve ahora la página de Subjects:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/apptdd0502.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;Notablemente, no toqué nada de código ni de tests. Esto muestra que hasta se puede trabajar en paralelo, o en distintos tiempos: primero se arma el código de los controladores y acciones con tests. Luego, al mismo tiempo o en algun momento, se agregan y mejoran las vistas.&lt;/p&gt;  &lt;p&gt;Próximos posts: agregar libros, aparición de primeros servicios, modelo de negocio, etc.&lt;/p&gt;  &lt;p&gt;Nos leemos!&lt;/p&gt;  &lt;p&gt;Angel “Java” Lopez   &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1826752" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+de+Software/default.aspx">Desarrollo de Software</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+Agil/default.aspx">Desarrollo Agil</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/TDD/default.aspx">TDD</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/ASP.NET+MVC/default.aspx">ASP.NET MVC</category></item><item><title>Resoluciones del Nuevo Mes: Abril 2013</title><link>http://msmvps.com/blogs/lopez/archive/2013/04/03/new_2D00_months_2D00_resolutions_2D00_april_2D00_2013.aspx</link><pubDate>Wed, 03 Apr 2013 10:09:29 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1826466</guid><dc:creator>lopez</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1826466</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2013/04/03/new_2D00_months_2D00_resolutions_2D00_april_2D00_2013.aspx#comments</comments><description>&lt;p&gt;Un nuevo mes comienza. Paso a revisar &lt;a href="http://msmvps.com/blogs/lopez/archive/2013/03/04/new_2D00_months_2D00_resolutions_2D00_march_2D00_2013.aspx"&gt;mis resoluciones de Marzo&lt;/a&gt;:&lt;/p&gt;  &lt;p&gt;- Comenzar ClojSharp &lt;strong&gt;&lt;font color="#008000"&gt;[completo]&lt;/font&gt;&lt;/strong&gt; &lt;a href="https://github.com/ajlopez/ClojSharp"&gt;ver repo&lt;/a&gt;     &lt;br /&gt;- Comenzar NodeAima [pendiente]     &lt;br /&gt;- Actualizar AjGenesisRuby [pendiente]     &lt;br /&gt;- Comenzar RubySharp &lt;strong&gt;&lt;font color="#008000"&gt;[completo]&lt;/font&gt;&lt;/strong&gt; &lt;a href="https://github.com/ajlopez/RubySharp"&gt;ver repo&lt;/a&gt;     &lt;br /&gt;- Actualizar SimpleGo &lt;strong&gt;&lt;font color="#008000"&gt;[completo]&lt;/font&gt;&lt;/strong&gt; &lt;a href="https://github.com/ajlopez/SimpleGo"&gt;ver repo&lt;/a&gt;     &lt;br /&gt;- Actualizar SimpleChess [pendiente]     &lt;br /&gt;- Actualizar Inmob &lt;strong&gt;&lt;font color="#008000"&gt;[completo]&lt;/font&gt;&lt;/strong&gt; &lt;a href="https://github.com/ajlopez/Inmob"&gt;ver repo&lt;/a&gt;     &lt;br /&gt;- Actualizar AjConsorSite &lt;strong&gt;&lt;font color="#008000"&gt;[completo]&lt;/font&gt;&lt;/strong&gt; &lt;a href="https://github.com/ajlopez/AjConsorSite"&gt;ver repo&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;En lguar de trabajar en AjGenesisRuby, estuve ocupado en&lt;/p&gt;  &lt;p&gt;- Actualizar y publicar AjLispRuby como gema &lt;strong&gt;&lt;font color="#008000"&gt;[completo]&lt;/font&gt;&lt;/strong&gt; &lt;a href="https://github.com/ajlopez/AjLispRuby"&gt;ver repo&lt;/a&gt;     &lt;br /&gt;- Migrar y actualizar Todocontenidos a GitHub &lt;strong&gt;&lt;font color="#008000"&gt;[completo]&lt;/font&gt;&lt;/strong&gt; &lt;a href="https://github.com/ajlopez/Todocontenidos"&gt;ver repo&lt;/a&gt;     &lt;br /&gt;- Publicar versión actual de AjGenesis, y migrarlo a GitHub &lt;strong&gt;&lt;font color="#008000"&gt;[completo]&lt;/font&gt;&lt;/strong&gt; &lt;a href="http://ajgenesis.codeplex.com/releases/view/103215"&gt;ver downloads&lt;/a&gt;, &lt;a href="https://github.com/ajlopez/AjGenesis"&gt;ver repo&lt;/a&gt;, &lt;a href="http://msmvps.com/blogs/lopez/archive/2013/03/19/ajgenesis_2D00_code_2D00_generation_2D00_news_2D00_and_2D00_ideas.aspx"&gt;ver post&lt;/a&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Adicionalmente a ClojSharp y RubySharp, escribí un nuevo lenguaje interpretado sobre C#&lt;/p&gt;  &lt;p&gt;- Comenzar Mass &lt;strong&gt;&lt;font color="#008000"&gt;[completo]&lt;/font&gt;&lt;/strong&gt; &lt;a href="https://github.com/ajlopez/Mass"&gt;ver repo&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;y también&lt;/p&gt;  &lt;p&gt;- Dar una charla sobre TDD &lt;strong&gt;&lt;font color="#008000"&gt;[completo]&lt;/font&gt;&lt;/strong&gt; &lt;a href="http://msmvps.com/blogs/lopez/archive/2013/03/27/introducci-243-n-a-tdd-con-visual-studio.aspx"&gt;ver post&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Para este Abril, se viene:&lt;/p&gt;  &lt;p&gt;- Actualizar Mass    &lt;br /&gt;- Comenzar NodeAima     &lt;br /&gt;- Dar un curso de un día sobre Node.js     &lt;br /&gt;- Actualizar AjGenesis     &lt;br /&gt;- Actualizar AjGenesisRuby     &lt;br /&gt;- Actualizar SimpleGo     &lt;br /&gt;- Actualizar RubySharp     &lt;br /&gt;- Actualizar ClojSharp&lt;/p&gt;  &lt;p&gt;Bien, más trabajo divertido y con TDD ;-)&lt;/p&gt;  &lt;p&gt;Nos leemos!&lt;/p&gt;  &lt;p&gt;Angel “Java” Lopez    &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;     &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1826466" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Javascript/default.aspx">Javascript</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Proyectos+de+C_26002300_243_3B00_digo+Abierto/default.aspx">Proyectos de C&amp;#243;digo Abierto</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/NodeJs/default.aspx">NodeJs</category></item><item><title>Introducción a TDD con Visual Studio</title><link>http://msmvps.com/blogs/lopez/archive/2013/03/27/introducci-243-n-a-tdd-con-visual-studio.aspx</link><pubDate>Wed, 27 Mar 2013 10:03:55 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1825919</guid><dc:creator>lopez</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1825919</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2013/03/27/introducci-243-n-a-tdd-con-visual-studio.aspx#comments</comments><description>&lt;p&gt;Gracias a la gente del MUG Argentina (&lt;a href="http://www.mug.org.ar"&gt;http://www.mug.org.ar&lt;/a&gt;), dí una charla de dos horas sobre cómo es TDD, con un ejemplo en Visual Studio.&lt;/p&gt;  &lt;p&gt;Desarrollamos algunos tests, cumpliendo con el ciclo rojo, verde, refactor, sobre una Factura con Productos y Cantidades. Pueden ver el código en:&lt;/p&gt;  &lt;p&gt;&lt;a title="https://github.com/ajlopez/TddOnTheRocks/tree/master/Ventas" href="https://github.com/ajlopez/TddOnTheRocks/tree/master/Ventas"&gt;https://github.com/ajlopez/TddOnTheRocks/tree/master/Ventas&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Los commits, con la evolución paso a paso, están en&lt;/p&gt;  &lt;p&gt;&lt;a title="https://github.com/ajlopez/TddOnTheRocks/commits/master" href="https://github.com/ajlopez/TddOnTheRocks/commits/master"&gt;https://github.com/ajlopez/TddOnTheRocks/commits/master&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/tddgithub01.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;Mencioné algunos posts en la charla. Son &lt;a href="http://msmvps.com/blogs/lopez/archive/tags/TDD/default.aspx"&gt;mis posts sobre TDD&lt;/a&gt;, pero destaqué:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2013/03/18/escribiendo-un-int-233-rprete-en-net-parte-10.aspx"&gt;Escribiendo un intérprete en .NET (Parte 10)&lt;/a&gt; donde van a ver un caso distinto y más extenso&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2013/03/08/tdd-y-dise-241-o-de-implementaci-243-n-1.aspx"&gt;TDD y Diseño de Implementación (1)&lt;/a&gt; donde voy a escribir sobre cómo queda simple el diseño de implementación usando TDD y la cabeza&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2013/02/20/tdd-como-compilador.aspx"&gt;TDD como Compilador&lt;/a&gt; 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&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2013/02/18/tdd-y-base-de-datos.aspx"&gt;TDD y Base de Datos&lt;/a&gt; sobre alternativas de qué hacer cuando tenemos bases de datos en nuestros tests&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2013/01/31/tdd-y-baby-steps.aspx"&gt;TDD y Baby Steps&lt;/a&gt; sobre ¿cómo comerse un elefante? Pedacito a pedacito&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2013/01/22/tdd-y-el-juego-del-go.aspx"&gt;TDD y el juego del Go&lt;/a&gt; sobre “el sistema está en buena forma” a cada momento, listo para abrazar el cambio y los próximos casos de uso.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2012/08/09/tdd_2D00_unit_2D00_tests_2D00_and_2D00_mocks.aspx"&gt;TDD, Test Unitarios y Mocks&lt;/a&gt; sobre usar mocks solamente cuando es necesario.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2012/07/04/tdd-y-casos-de-uso.aspx%20"&gt;TDD y Casos de Uso&lt;/a&gt; sobre cómo ir acompañando la implementación de casos de uso con TDD. Lean el post de “Uncle Bob” &lt;a href="http://blog.8thlight.com/uncle-bob/2012/05/15/NODB.html"&gt;No DB&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2011/06/27/writing_2D00_an_2D00_application_2D00_using_2D00_tdd_2D00_part_2D00_5_2D00_adding_2D00_views.aspx"&gt;Escribiendo una Aplicación usando TDD (parte 5)&lt;/a&gt;&amp;#160; sobre algunos pasos que se pueden dar con ASP.NET MVC&lt;/p&gt;  &lt;p&gt;Para los que quieran ver cómo desarrollo partiendo de los controllers, en vez que desde el dominio de negocio, ver&lt;/p&gt;  &lt;p&gt;&lt;a href="http://altnethispano.org/wiki/van-2012-06-23-desarrollando-una-aplicacion-con-tdd-desde-0.ashx"&gt;Desarrollando una aplicación con TDD desde 0&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;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!&lt;/p&gt;  &lt;p&gt;Para practicar, coleccioné algunos enlaces en:&lt;/p&gt;  &lt;p&gt;&lt;a title="http://delicious.com/ajlopez/tdd+codekata" href="http://delicious.com/ajlopez/tdd+codekata"&gt;http://delicious.com/ajlopez/tdd+codekata&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Para aprender más:&lt;/p&gt;  &lt;p&gt;&lt;a title="https://delicious.com/ajlopez/tdd+tutorial" href="https://delicious.com/ajlopez/tdd+tutorial"&gt;https://delicious.com/ajlopez/tdd+tutorial&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Para ejemplos en video:&lt;/p&gt;  &lt;p&gt;&lt;a title="https://delicious.com/ajlopez/tdd+video" href="https://delicious.com/ajlopez/tdd+video"&gt;https://delicious.com/ajlopez/tdd+video&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Nos leemos!&lt;/p&gt;  &lt;p&gt;Angel “Java” Lopez   &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1825919" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+Agil/default.aspx">Desarrollo Agil</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/TDD/default.aspx">TDD</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Programaci_F300_n/default.aspx">Programación</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Argentina/default.aspx">Argentina</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Buenos+Aires/default.aspx">Buenos Aires</category></item><item><title>Entrevista y Podcast</title><link>http://msmvps.com/blogs/lopez/archive/2013/03/23/entrevista-y-podcast.aspx</link><pubDate>Sat, 23 Mar 2013 10:47:32 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1825715</guid><dc:creator>lopez</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1825715</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2013/03/23/entrevista-y-podcast.aspx#comments</comments><description>&lt;p&gt;Hoy paso a comentar dos entregables que se publicaron: una entrevista, y una charla como podcast.&lt;/p&gt;  &lt;p&gt;El año pasado, el bueno de &lt;a href="https://twitter.com/santiagobasulto"&gt;@santiagobasulto&lt;/a&gt; (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.&lt;/p&gt;  &lt;p&gt;Santiago la pasó en limpio, la pueden leer en:&lt;/p&gt;  &lt;p&gt;&lt;a title="http://charliedontcode.com/entrevistas/2012/08/12/entrevista-angel-java-lopez.html" href="http://charliedontcode.com/entrevistas/2012/08/12/entrevista-angel-java-lopez.html"&gt;http://charliedontcode.com/entrevistas/2012/08/12/entrevista-angel-java-lopez.html&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Algo más de contexto, lo escribí hace algo más de cuatro años:&lt;/p&gt;  &lt;p&gt;&lt;a title="http://msmvps.com/blogs/lopez/archive/2008/12/31/treinta-a-241-os-en-desarrollo-de-software.aspx" href="http://msmvps.com/blogs/lopez/archive/2008/12/31/treinta-a-241-os-en-desarrollo-de-software.aspx"&gt;http://msmvps.com/blogs/lopez/archive/2008/12/31/treinta-a-241-os-en-desarrollo-de-software.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Visiten el blog de Santiago:&lt;/p&gt;  &lt;p&gt;&lt;a title="http://charliedontcode.com/" href="http://charliedontcode.com/"&gt;http://charliedontcode.com/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Muy buena la escena de cine de donde toma el nombre (ya me imagino a &lt;a href="https://twitter.com/santiagobasulto"&gt;@santiagobasulto&lt;/a&gt; cruzándose con Robert Duvall, acá en Buenos Aires, supongo que en otro bar histórico, La Biela ;-).&lt;/p&gt;  &lt;p&gt;Y también tuve una charla, esta vez a distancia, con los buenos &lt;a href="http://twitter.com/roundcrisis"&gt;@roundcrisis&lt;/a&gt; &lt;a href="http://twitter.com/dvilchez"&gt;@dvilchez&lt;/a&gt;, publicada hoy como podcast:&lt;/p&gt;  &lt;p&gt;&lt;a title="http://www.32minutos.net/?p=106" href="http://www.32minutos.net/?p=106"&gt;http://www.32minutos.net/?p=106&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;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 ;-). &lt;/p&gt;  &lt;p&gt;Vean que han producido varios podcast en:&lt;/p&gt;  &lt;p&gt;&lt;a title="http://www.32minutos.net/" href="http://www.32minutos.net/"&gt;http://www.32minutos.net/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;como el de &lt;a href="http://www.32minutos.net/?p=85"&gt;Programación Funcional&lt;/a&gt; con el bueno de &lt;a href="http://twitter.com/martinsalias"&gt;@martinsalias&lt;/a&gt;, o el de &lt;a href="http://www.32minutos.net/?p=32"&gt;Node.js&lt;/a&gt; con &lt;a href="http://twitter.com/woloski"&gt;@woloski&lt;/a&gt;, &lt;a href="http://twitter.com/jfroma"&gt;@jfroma&lt;/a&gt; y &lt;a href="http://twitter.com/theprogrammer"&gt;@theprogrammer&lt;/a&gt;. 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.&lt;/p&gt;  &lt;p&gt;Les agradezco a los tres haberme permitido conversar y expresar algunas ideas, que pueden servir o no. &lt;/p&gt;  &lt;p&gt;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.&lt;/p&gt;  &lt;p&gt;Nos leemos!&lt;/p&gt;  &lt;p&gt;Angel “Java” Lopez   &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1825715" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+de+Software/default.aspx">Desarrollo de Software</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Historia+de+la+Computaci_26002300_243_3B00_n/default.aspx">Historia de la Computaci&amp;#243;n</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+Agil/default.aspx">Desarrollo Agil</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/TDD/default.aspx">TDD</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Programaci_F300_n/default.aspx">Programación</category></item></channel></rss>