<?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 : Lenguajes de Programaci&amp;#243;n, C&amp;#243;digo Abierto</title><link>http://msmvps.com/blogs/lopez/archive/tags/Lenguajes+de+Programaci_26002300_243_3B00_n/C_26002300_243_3B00_digo+Abierto/default.aspx</link><description>Tags: Lenguajes de Programaci&amp;#243;n, C&amp;#243;digo Abierto</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP2 (Build: 40407.4157)</generator><item><title>AjSharp: objetos y clases dinámicas</title><link>http://msmvps.com/blogs/lopez/archive/2009/12/27/ajsharp_2D00_dynamic_2D00_classes_2D00_and_2D00_objects.aspx</link><pubDate>Sun, 27 Dec 2009 14:42:41 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1747853</guid><dc:creator>lopez</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1747853</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2009/12/27/ajsharp_2D00_dynamic_2D00_classes_2D00_and_2D00_objects.aspx#comments</comments><description>&lt;p&gt;Estoy escribiendo un intérprete no tipado con sintaxis tipo C#, que bauticé AjSharp. Hace un tiempo escribí sobre este proyecto de código abierto en:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://ajlopez.wordpress.com/2009/09/21/ajsharp-programming-language-a-c-like-dynamic-language/" target="_blank"&gt;AjSharp Programming Language a C#-like Dynamic Language&lt;/a&gt;     &lt;br /&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2009/09/22/ajsharp-un-lenguaje-din-225-mico-en-c.aspx" target="_blank"&gt;AjSharp: un lenguaje dinámico en C#&lt;/a&gt;     &lt;br /&gt;    &lt;br /&gt;Pueden bajarse la versión actual desde &lt;a title="http://code.google.com/p/ajcodekatas" href="http://code.google.com/p/ajcodekatas"&gt;http://code.google.com/p/ajcodekatas&lt;/a&gt; en trunk/AjLanguage (AjLanguage define el árbol de ejecución del intérprete, AjSharp tiene un parser, un lenguaje definido para construir ese árbol; la idea es colocar otros parsers sobre AjLanguage, por ejemplo, AjBasic).&lt;/p&gt;  &lt;p&gt;Ayer sábado, agregué una nueva característica, la definición de un objecto. Ya de antes, AjSharp soporta la definición de una clase dinámica:&lt;/p&gt;  &lt;pre&gt;&lt;pre style="font-size:12px;margin:0px;width:100%;font-family:consolas,courier,monospace;background-color:#ffffff;"&gt;&lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; Person
&lt;strike&gt;&lt;strike&gt;&lt;/strike&gt;&lt;/strike&gt;{
  var Name;
  var Age;
  
  function AddYears(years) 
  {
    &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.Age = &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.Age + years;
  }
}
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Pueden crear un objecto usando:&lt;/p&gt;

&lt;pre&gt;&lt;pre style="font-size:12px;margin:0px;width:100%;font-family:consolas,courier,monospace;background-color:#ffffff;"&gt;adam = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Person();
adam.AddYears(800);
adam.Name = &amp;quot;&lt;span style="color:#8b0000;"&gt;Adam&lt;/span&gt;&amp;quot;;
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;El objeto creado es dinámico: se le pueden agregar variables de instancias y métodos, en cualquier momento:&lt;/p&gt;

&lt;pre&gt;&lt;pre style="font-size:12px;margin:0px;width:100%;font-family:consolas,courier,monospace;background-color:#ffffff;"&gt;adam.LastName = &amp;quot;&lt;span style="color:#8b0000;"&gt;unknown&lt;/span&gt;&amp;quot;;
adam.EyeColor = &amp;quot;&lt;span style="color:#8b0000;"&gt;brown&lt;/span&gt;&amp;quot;;
adam.SayHello = function() { PrintLine(&amp;quot;&lt;span style="color:#8b0000;"&gt;Hello&lt;/span&gt;&amp;quot;); };
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Pueden crear objetos, con esta notación, inicializando su estado:&lt;/p&gt;

&lt;pre&gt;&lt;pre style="font-size:12px;margin:0px;width:100%;font-family:consolas,courier,monospace;background-color:#ffffff;"&gt;adam = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Person() { FirstName = “Adam”, LastName = “Genesis”, Age = 800 };&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Y hasta pueden definir un objeto sin tener una clase asociada:&lt;/p&gt;

&lt;pre&gt;&lt;pre style="font-size:12px;margin:0px;width:100%;font-family:consolas,courier,monospace;background-color:#ffffff;"&gt;dynobj = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; { Name = “Adam”, Age = 800 };&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Esto es equivalente a hacerlo más “programáticamente” así:&lt;/p&gt;

&lt;pre&gt;&lt;pre style="font-size:12px;margin:0px;width:100%;font-family:consolas,courier,monospace;background-color:#ffffff;"&gt;dynobj = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; DynamicObject();
dynobj.FirstName = “Adam”;
dynobj.LastName = &amp;quot;&lt;span style="color:#8b0000;"&gt;Genesis”;
&lt;/span&gt;dynobj.Age = 800;
dynobj.FullName = function() { &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; FirstName + “ “ + LastName; }&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Esto estaba implementado desde hace meses. Ayer agregué la notación:&lt;/p&gt;

&lt;pre&gt;&lt;pre style="font-size:12px;margin:0px;width:100%;font-family:consolas,courier,monospace;background-color:#ffffff;"&gt;&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; Adam
{
  var Name = &amp;quot;&lt;span style="color:#8b0000;"&gt;Adam&lt;/span&gt;&amp;quot;;
  var Age = 700;
  
  function AddYears(years) 
  {
    &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.Age = &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.Age + years;
  }
}
Adam.AddYears(100);
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;donde se puede definir un objecto único, dándole estructura, conducta y nombre.&lt;/p&gt;

&lt;p&gt;La idea de AjLanguage es que pueda acceder a todas las clases y objetos del framework subyacente (en este caso, .NET, pero está pensado para ser reescribible sobre Java, si fuera necesario, claro, cambiando cualquier referencia a tipos nativos):&lt;/p&gt;

&lt;pre&gt;&lt;pre style="font-size:12px;margin:0px;width:100%;font-family:consolas,courier,monospace;background-color:#ffffff;"&gt;ds = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; System.Data.DataSet();
dinfo = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; System.IO.DirectoryInfo(“.”);
&lt;span style="color:#0000ff;"&gt;foreach&lt;/span&gt; (fi &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; dinfo.GetFiles())
{
    PrintLine(fi.FullName);
}&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Desde ayer, seguí implementando constructores. Tengo pensado definir visibilidades privadas y públicas (por ejemplo, las variables y métodos de instancia que comiencen con minúscula, hacerlas automáticamente privadas). También agregar propotipos, como en Javascript, lo que permitiría implementar cosas similares a los métodos de extensión de .NET.&lt;/p&gt;

&lt;p&gt;Pero si van hoy al trunk, encontrarán que estuve implementando canales, como en en lenguaje Go de Google.&lt;/p&gt;

&lt;pre&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,courier,monospace;background-color:#ffffff;"&gt;channel = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Channel();
go &lt;span style="color:#0000ff;"&gt;for&lt;/span&gt; (k=1; k&amp;lt;=5; k++) channel &amp;lt;- k;
&lt;span style="color:#0000ff;"&gt;for&lt;/span&gt; (j=1; j&amp;lt;=5; j++)
	result = result + &amp;lt;-channel;
&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Pero eso dará para otro post más detallado. Con esa característica quiero explorar temas como &lt;a href="http://en.wikipedia.org/wiki/Reactive_programming" target="_blank"&gt;programación reactiva&lt;/a&gt;, agentes, actores, shared transactional memory, ver:&lt;/p&gt;

&lt;p&gt;&lt;a title="http://clojure.org/Agents" href="http://clojure.org/Agents"&gt;http://clojure.org/Agents&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a title="http://en.wikipedia.org/wiki/Actor_model" href="http://en.wikipedia.org/wiki/Actor_model"&gt;http://en.wikipedia.org/wiki/Actor_model&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a title="http://en.wikipedia.org/wiki/Axum_%28programming_language%29" href="http://en.wikipedia.org/wiki/Axum_%28programming_language%29"&gt;http://en.wikipedia.org/wiki/Axum_%28programming_language%29&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Por ejemplo, sería interesante que los canales comunicaran no sólo dos códigos en paralelos, sino máquinas diferentes. Y definir esas máquinas en tiempo de deployment, sin cambiar el código del programa. Podría reescribir los ejemplos de &lt;a href="http://ajlopez.wordpress.com/2008/06/15/distributed-agents-using-dssvpl/"&gt;Distributed Agents using DSS/VPL &lt;/a&gt;o&amp;#160; &lt;a href="http://ajlopez.wordpress.com/2008/04/10/genetic-algorithms-with-ajagents-and-concurrency-and-coordination-runtime-ccr/"&gt;Genetic Algorithms with AjAgents and Concurrency and Coordination Runtime (CCR)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Como verán, me estoy divirtiendo!&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=1747853" 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_26002300_243_3B00_digo+Abierto/default.aspx">C&amp;#243;digo Abierto</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/AjSharp/default.aspx">AjSharp</category></item><item><title>TDD and Code Kata: Writing a Lexer for AjRuby</title><link>http://msmvps.com/blogs/lopez/archive/2009/03/12/tdd_2D00_and_2D00_code_2D00_kata_2D00_writing_2D00_a_2D00_lexer_2D00_for_2D00_ajruby.aspx</link><pubDate>Thu, 12 Mar 2009 05:11:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1677718</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=1677718</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2009/03/12/tdd_2D00_and_2D00_code_2D00_kata_2D00_writing_2D00_a_2D00_lexer_2D00_for_2D00_ajruby.aspx#comments</comments><description>&lt;p&gt;Muchas veces, escribo programas tipo code kata, para entrenarme en algún tema de desarrollo de software. En estos últimos meses, escribí varios mini intérpretes, usando TDD, code coverage, y C#. La semana pasada, estuve trabajando en el lanzamiento de otro pet project, AjRuby. El punto de inicio: el analizador léxico, el lexer.&lt;/p&gt;  &lt;p&gt;Un lexer es un programa que analiza el código fuente de un programa, y retorna sus tokens, las “palabras” que componen el programa. En el caso de AjRuby, escribí un lexer que sigue la gramática de Ruby. No está completo aún, pero funciona.&lt;/p&gt;  &lt;p&gt;Pueden ver el progreso del proyecto, en el repositorio de Google Code:&lt;/p&gt;  &lt;p&gt;&lt;a title="http://code.google.com/p/ajcodekatas/source/browse#svn/trunk/AjRuby" href="http://code.google.com/p/ajcodekatas/source/browse#svn/trunk/AjRuby"&gt;http://code.google.com/p/ajcodekatas/source/browse#svn/trunk/AjRuby&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;La solución tiene un proyecto de librería de clases, y otro de tests:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/ajruby02.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;Hay una clase Token, que representa cada token:&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:3556dfda-95db-4216-8c88-ba67a9266e51" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;   &lt;pre style="background-color:white;"&gt;&lt;div&gt;&lt;span style="color:#000000;"&gt;    &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; Token
    {
        &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt; Value { &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;get&lt;/span&gt;&lt;span style="color:#000000;"&gt;; &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;set&lt;/span&gt;&lt;span style="color:#000000;"&gt;; }

        &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; TokenType TokenType { &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;get&lt;/span&gt;&lt;span style="color:#000000;"&gt;; &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;set&lt;/span&gt;&lt;span style="color:#000000;"&gt;; }
    }
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;El TokenType es una enumeración:&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:b030a353-46ec-4f15-be42-fe729deaca08" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;
  &lt;pre style="background-color:white;"&gt;&lt;div&gt;&lt;span style="color:#000000;"&gt;    &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;enum&lt;/span&gt;&lt;span style="color:#000000;"&gt; TokenType
    {
        Name,
        Integer,
        Real,
        Boolean,
        String,
        Operator,
        Separator
    }
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Hay una clase LexerTest.cs, conteniendo tests como:&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:3acb3099-f7eb-417e-b132-9927cd84a1f9" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;
  &lt;pre style="background-color:white;"&gt;&lt;div&gt;&lt;span style="color:#000000;"&gt;        [TestMethod]
        &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;void&lt;/span&gt;&lt;span style="color:#000000;"&gt; ShouldProcessName()
        {
            Lexer lexer &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; Lexer(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;name&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;);

            Token token;

            token &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; lexer.NextToken();

            Assert.IsNotNull(token);
            Assert.AreEqual(TokenType.Name, token.TokenType);
            Assert.AreEqual(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;name&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, token.Value);

            token &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; lexer.NextToken();

            Assert.IsNull(token);
        }
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Hay un test para cada tipo de token a ser procesado. Otro ejemplo:&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:9b11e40f-18a3-4bce-9d93-6d349df8b74d" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;
  &lt;pre style="background-color:white;"&gt;&lt;div&gt;&lt;span style="color:#000000;"&gt;        [TestMethod]
        &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;void&lt;/span&gt;&lt;span style="color:#000000;"&gt; ShouldProcessNameWithInitialUnderscore()
        {
            Lexer lexer &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; Lexer(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;_name&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;);

            Token token;

            token &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; lexer.NextToken();

            Assert.IsNotNull(token);
            Assert.AreEqual(TokenType.Name, token.TokenType);
            Assert.AreEqual(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;_name&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, token.Value);

            token &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; lexer.NextToken();

            Assert.IsNull(token);
        }
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Escribí los tests usando ideas TDD: escribir el test, compilar con error, arreglar los problemas de compilación, ejecutar los tests en rojo, arreglarlos, conseguir el verde para los tests. No estuve haciendo tanto refactoring. El código merece algún refactor, pero por ahora, estoy tratando de conseguir un lexer que trabaje. Los tests quedaron en verde:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/ajruby01.png" alt="" /&gt; &lt;/p&gt;

&lt;p&gt;Mi objetivo es tener más del 80% de code coverage, en cualquier momento del desarrollo del proyecto:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/ajruby03.png" alt="" /&gt; &lt;/p&gt;

&lt;p&gt;Es bueno escribir algo sólo por diversión y aprendizaje. Para mí, es parte de la mejora continua que todo desarrollador de software debe perseguir.&lt;/p&gt;

&lt;p&gt;Nos leemos!&lt;/p&gt;

&lt;p&gt;Angel &amp;quot;Java&amp;quot; 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=1677718" 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_26002300_243_3B00_digo+Abierto/default.aspx">C&amp;#243;digo Abierto</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></item></channel></rss>