<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Bosque Viejo</title>
	<atom:link href="http://bosqueviejo.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://bosqueviejo.net</link>
	<description>Sitio web sobre programación, software libre, redes, servidores, ofimática... y todo lo relacionado con la informática que nos rodea</description>
	<lastBuildDate>Tue, 14 Feb 2012 14:33:57 +0000</lastBuildDate>
	<language>es</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>En busca de la excelencia del código</title>
		<link>http://bosqueviejo.net/2012/02/14/en-busca-de-la-excelencia-del-codigo/</link>
		<comments>http://bosqueviejo.net/2012/02/14/en-busca-de-la-excelencia-del-codigo/#comments</comments>
		<pubDate>Tue, 14 Feb 2012 14:33:57 +0000</pubDate>
		<dc:creator>bombadil</dc:creator>
				<category><![CDATA[Libros]]></category>
		<category><![CDATA[desarrollo ágil]]></category>
		<category><![CDATA[excelencia del código]]></category>
		<category><![CDATA[programación]]></category>
		<category><![CDATA[raúl herranz]]></category>
		<category><![CDATA[scrum manager]]></category>

		<guid isPermaLink="false">http://bosqueviejo.net/?p=1236</guid>
		<description><![CDATA[ Así se titula el primer libro de Raúl Herranz, uno de los profesores acreditados de Scrum Manager. El documento es libre y gratuito y puede descargarse de la siguiente dirección:
Scrum Manager &#8211; En busca de la excelencia del CódigoRaúl HerranzRev. 1.0
El texto es conciso y no muy extenso, por lo que se hace amena su lectura. Lo más importante, es que expone una serie de criterios para definir lo que se considera la excelencia del código, así como prácticas y técnicas para hacer que se consiga. El libro nos da un repaso a temas tan interesantes como la automatización de tareas, con lecciones tan importantes como la colectivización del código; pasando por las revisiones de código, la programación por parejas y revisiones por pares; las pruebas: unitarias, de integración, de sistema, de implantación, de aceptación e incluso regresión; y por último, pero no por ello menos importante, la refactorización, esa tarea siempre olvidada y que nos ahorra a la larga mucha deuda técnica.
Me gusta el formato del documento y su narrativa. Lo que quizá cambiaría es que está muy focalizado en sus ejemplos a entornos de desarrollo Java. Los pondría más genéricos y/o orientados a diferentes lenguajes y entornos [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://bosqueviejo.net/wp-content/uploads/excelencia_codigo-150x150.png" alt="" title="excelencia_codigo" width="150" height="150" class="alignleft size-thumbnail wp-image-1237" /> Así se titula el primer libro de <a href="http://www.linkedin.com/in/raulherranz">Raúl Herranz</a>, uno de los profesores acreditados de <a href="http://www.scrummanager.net/oks/">Scrum Manager</a>. El documento es libre y gratuito y puede descargarse de la siguiente dirección:</p>
<p><a href="http://www.scrummanager.net/files/scrum_manager_excelencia_del_codigo.pdf">Scrum Manager &#8211; En busca de la excelencia del Código</a><br /><strong>Raúl Herranz</strong><br />Rev. 1.0</p>
<p>El texto es conciso y no muy extenso, por lo que se hace amena su lectura. Lo más importante, es que expone una serie de criterios para definir lo que se considera <em>la excelencia del código</em>, así como prácticas y técnicas para hacer que se consiga. El libro nos da un repaso a temas tan interesantes como la automatización de tareas, con lecciones tan importantes como la colectivización del código; pasando por las revisiones de código, la programación por parejas y revisiones por pares; las pruebas: unitarias, de integración, de sistema, de implantación, de aceptación e incluso regresión; y por último, pero no por ello menos importante, la refactorización, esa tarea siempre olvidada y que nos ahorra a la larga mucha deuda técnica.</p>
<p>Me gusta el formato del documento y su narrativa. Lo que quizá cambiaría es que está muy focalizado en sus ejemplos a entornos de desarrollo Java. Los pondría más genéricos y/o orientados a diferentes lenguajes y entornos de desarrollo.</p>
<p>En conclusión, un buen documento que nos permite hacer repaso de las técnicas que ya aplicamos y las que aún no hacemos para poder mejorar nuestro quehacer diario con buenas prácticas, buena metodología y buenos consejos. Gracias Raúl por este material, y sobretodo por poder disponer de él de forma libre y gratuita.</p>
]]></content:encoded>
			<wfw:commentRss>http://bosqueviejo.net/2012/02/14/en-busca-de-la-excelencia-del-codigo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Montículos</title>
		<link>http://bosqueviejo.net/2012/02/12/monticulos/</link>
		<comments>http://bosqueviejo.net/2012/02/12/monticulos/#comments</comments>
		<pubDate>Sun, 12 Feb 2012 13:56:48 +0000</pubDate>
		<dc:creator>bombadil</dc:creator>
				<category><![CDATA[programación]]></category>
		<category><![CDATA[heap]]></category>
		<category><![CDATA[heapsort]]></category>
		<category><![CDATA[montículos]]></category>
		<category><![CDATA[priorityqueue]]></category>
		<category><![CDATA[robert w floyd]]></category>
		<category><![CDATA[uned]]></category>

		<guid isPermaLink="false">http://bosqueviejo.net/?p=1223</guid>
		<description><![CDATA[ Pues sí, otra vez de exámenes, otra vez estudiando, y llego a un apartado, en el que lo que decía el libro me sorprende y, al implementarlo, me confirmo. La teoría o lo que viene en los libros no es 100% fiable, en caso de teorías matemáticas, físicas, &#8230; o de computación, hay que comprobar lo que nos indican los libros, porque podemos encontrarnos con una errata.
Teniendo en cuenta que lo que indica el libro es un pseudocódigo, es peor aún, puesto que quien lo escribe está seguro de hacerlo bien, y no dudo que incluso lo haya comprobado, pero claro, nos encontramos con que, como no es un lenguaje concreto, pueda ser una interpretación de una implementación, para la cual, se ha podido perder algo de sustancia por el camino, o cometer un error tipográfico.
Pero al grano. Montículos.
¿Qué es un montículo?
Un montículo es un árbol binario balanceado que cumple con la premisa de que: ningún padre tiene un hijo mayor (montículo de máximos) o menor (montículo de mínimos) a él. Una definición corta y concreta, ¿no?
Esta estructura de datos fue propuesta por Robert W. Floyd (premio Turing en 1978) para resolver el problema de la ordenación de elementos [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://bosqueviejo.net/wp-content/uploads/floyd-150x150.png" alt="" title="floyd" width="150" height="150" class="alignleft size-thumbnail wp-image-1224" /> Pues sí, otra vez de exámenes, otra vez estudiando, y llego a un apartado, en el que lo que decía el libro me sorprende y, al implementarlo, me confirmo. La teoría o lo que viene en los libros no es 100% fiable, en caso de teorías matemáticas, físicas, &#8230; o de computación, hay que comprobar lo que nos indican los libros, porque podemos encontrarnos con una errata.</p>
<p>Teniendo en cuenta que lo que indica el libro es un pseudocódigo, es peor aún, puesto que quien lo escribe está seguro de hacerlo bien, y no dudo que incluso lo haya comprobado, pero claro, nos encontramos con que, como no es un lenguaje concreto, pueda ser una interpretación de una implementación, para la cual, se ha podido perder algo de sustancia por el camino, o cometer un error tipográfico.</p>
<p>Pero al grano. Montículos.</p>
<h3>¿Qué es un montículo?</h3>
<p>Un montículo es un árbol binario balanceado que cumple con la premisa de que: <em>ningún padre tiene un hijo mayor (montículo de máximos) o menor (montículo de mínimos) a él</em>. Una definición corta y concreta, ¿no?</p>
<p>Esta estructura de datos fue propuesta por <a href="http://es.wikipedia.org/wiki/Robert_Floyd">Robert W. Floyd</a> (premio Turing en 1978) para resolver el problema de la ordenación de elementos dentro de un vector, el famoso <a href="http://es.wikipedia.org/wiki/Heapsort"><em>heapsort</em></a> (u ordenación por montículo).</p>
<p>En la asignatura de <em>Programación y Estructuras de Datos Avanzadas</em> (en la carrera de Grado en Ingenería Informática de la UNED), se propone al inicio de la asignatura, como conocimiento de las estructuras de datos, el montículo.</p>
<p><a href="http://bosqueviejo.net/wp-content/uploads/monticulo.png"><img src="http://bosqueviejo.net/wp-content/uploads/monticulo-300x274.png" alt="" title="monticulo" width="300" height="274" class="aligncenter size-medium wp-image-1226" /></a></p>
<p>El montículo, aunque conceptualmente se dibuja en forma de árbol, está implementado sobre un vector. Ya que es balanceado y binario, un nodo solo puede contener dos hijos. La formula para acceder a cada hijo, dado el índice del padre (i), sería:</p>
<pre>
hijo_izquierdo = 2i
hijo_derecho = 2i+1
</pre>
<p>El acceso al padre se realizaría con una división entera: <tt>i / 2</tt>.</p>
<h3>¿Para qué sirve un montículo?</h3>
<p>El montículo se emplea en lenguajes de alto y medio nivel, muchas veces sin darnos cuenta. En Java, por ejemplo, se implementa a través de la clase <a href="http://docs.oracle.com/javase/6/docs/api/java/util/PriorityQueue.html">PriorityQueue</a>, la cual permite, a través de un comparador, implementar la ordenación interna del montículo. En otros lenguajes puede aparecer igualmente como cola de prioridad (PriorityQueue) o como montículo (Heap).</p>
<p>El montículo en sí permite:</p>
<ul>
<li>Ordenar elementos de un vector de forma fácil y óptima, pudiendo implementar un comparador a medida.</li>
<li>Búsquedas el máximos, mínimos, o cualquier otro factor a tener en cuenta en la selección de búsqueda de elementos.</li>
<li>En problemas específicos de grafos como el recubrimiento mínimo de Prim o el camino más corto de Dijkstra.</li>
</ul>
<h3>Implementación del algoritmo</h3>
<p>Me ha costado un poco decidir el lenguaje en el que implementarlo, finalmente, he optado por Ruby, ya que su código queda bastante pseudocodificado, pero igualmente habría quedado igual de bien en Python. El código sería:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> MonticuloMaximos
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Vale, esto es lo básico, la definición de la clase. Ahora vamos a ir creando los métodos:</p>
<ul>
<li><strong>inicializador</strong> (o constructor): inicializa el vector interno, de modo que en el momento de crear el montículo, este estará vacío:

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">    <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        <span style="color:#0066ff; font-weight:bold;">@vector</span> = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

</li>
<li><strong>vacio?</strong>: esta es una de las cosas que más me gusta de Ruby, que puedes poner en un método el símbolo de interrogación, con lo que queda bastante pseudocodificado lo que hace el método en sí. Pregunta si el montículo está vacío, y la respuesta será lógica: sí o no (veradero o falso):

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">    <span style="color:#9966CC; font-weight:bold;">def</span> vacio?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        <span style="color:#006600; font-weight:bold;">&#40;</span>@vector.<span style="color:#9900CC;">length</span> == <span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

</li>
<li><strong>flotar</strong>: aquí ya comenzamos con las acciones básicas de un montículo. La acción de <em>flotar</em>, se emplea cuando se agrega un elemento nuevo a la estructura. Lo más simple, dado que el montículo se implementa en un vector, es agregar al final del vector el elemento y <em>flotarlo</em>, hasta que su peso nos diga que está en el lugar indóneo, esto hace que el coste del algoritmo sea lineal, y por lo cual, óptimo:

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">    <span style="color:#9966CC; font-weight:bold;">def</span> flotar<span style="color:#006600; font-weight:bold;">&#40;</span>i<span style="color:#006600; font-weight:bold;">&#41;</span>
        padre = i <span style="color:#006600; font-weight:bold;">/</span> <span style="color:#006666;">2</span>
        <span style="color:#9966CC; font-weight:bold;">while</span> <span style="color:#006600; font-weight:bold;">&#40;</span>i<span style="color:#006600; font-weight:bold;">&gt;</span><span style="color:#006666;">1</span> <span style="color:#9966CC; font-weight:bold;">and</span> <span style="color:#0066ff; font-weight:bold;">@vector</span><span style="color:#006600; font-weight:bold;">&#91;</span>padre<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&lt;</span>@vector<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
            <span style="color:#0066ff; font-weight:bold;">@vector</span><span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span>, <span style="color:#0066ff; font-weight:bold;">@vector</span><span style="color:#006600; font-weight:bold;">&#91;</span>padre<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#0066ff; font-weight:bold;">@vector</span><span style="color:#006600; font-weight:bold;">&#91;</span>padre<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span>, <span style="color:#0066ff; font-weight:bold;">@vector</span><span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span>
            i = i <span style="color:#006600; font-weight:bold;">/</span> <span style="color:#006666;">2</span>
            padre = i <span style="color:#006600; font-weight:bold;">/</span> <span style="color:#006666;">2</span>
        <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

</li>
<li><strong>hundir</strong>: sería la contrapartida a flotar. En este caso, lo que se hace es que, si eliminamos la <em>cima del montículo</em>, la acción rápida, sería mover el último elemento del vector al principio, cambiar el dimensionamiento del vector y realizar este algoritmo para llevar (o hundir) al elemento a su posición correcta. Igualmente, el algoritmo es lineal:

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">    <span style="color:#9966CC; font-weight:bold;">def</span> hundir<span style="color:#006600; font-weight:bold;">&#40;</span>i<span style="color:#006600; font-weight:bold;">&#41;</span>
        <span style="color:#9966CC; font-weight:bold;">begin</span>
            hi = <span style="color:#006666;">2</span> <span style="color:#006600; font-weight:bold;">*</span> i
            hd = <span style="color:#006666;">2</span> <span style="color:#006600; font-weight:bold;">*</span> i <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">1</span>
            <span style="color:#CC0066; font-weight:bold;">p</span> = i
            <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span>hd <span style="color:#006600; font-weight:bold;">&lt;</span>= <span style="color:#0066ff; font-weight:bold;">@vector</span>.<span style="color:#9900CC;">length</span> <span style="color:#9966CC; font-weight:bold;">and</span> <span style="color:#0066ff; font-weight:bold;">@vector</span><span style="color:#006600; font-weight:bold;">&#91;</span>hd<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">&gt;</span> <span style="color:#0066ff; font-weight:bold;">@vector</span><span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
                i = hd
            <span style="color:#9966CC; font-weight:bold;">end</span>
            <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span>hi <span style="color:#006600; font-weight:bold;">&lt;</span>= <span style="color:#0066ff; font-weight:bold;">@vector</span>.<span style="color:#9900CC;">length</span> <span style="color:#9966CC; font-weight:bold;">and</span> <span style="color:#0066ff; font-weight:bold;">@vector</span><span style="color:#006600; font-weight:bold;">&#91;</span>hi<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">&gt;</span> <span style="color:#0066ff; font-weight:bold;">@vector</span><span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
                i = hi
            <span style="color:#9966CC; font-weight:bold;">end</span>
            <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC0066; font-weight:bold;">p</span> != i<span style="color:#006600; font-weight:bold;">&#41;</span>
                <span style="color:#0066ff; font-weight:bold;">@vector</span><span style="color:#006600; font-weight:bold;">&#91;</span>p<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span>, <span style="color:#0066ff; font-weight:bold;">@vector</span><span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#0066ff; font-weight:bold;">@vector</span><span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span>, <span style="color:#0066ff; font-weight:bold;">@vector</span><span style="color:#006600; font-weight:bold;">&#91;</span>p<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span>
            <span style="color:#9966CC; font-weight:bold;">end</span>
        <span style="color:#9966CC; font-weight:bold;">end</span> <span style="color:#9966CC; font-weight:bold;">until</span> <span style="color:#CC0066; font-weight:bold;">p</span> == i
    <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

</li>
<li><strong>insertar</strong>: en este método, insertamos (como bien dijimos en flotar) un elemento en la estructura, por lo que, hacemos eso mismo, agregamos el elemento y lo flotamos:

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">    <span style="color:#9966CC; font-weight:bold;">def</span> insertar<span style="color:#006600; font-weight:bold;">&#40;</span> e <span style="color:#006600; font-weight:bold;">&#41;</span>
        <span style="color:#0066ff; font-weight:bold;">@vector</span>.<span style="color:#9900CC;">push</span><span style="color:#006600; font-weight:bold;">&#40;</span>e<span style="color:#006600; font-weight:bold;">&#41;</span>
        flotar<span style="color:#006600; font-weight:bold;">&#40;</span>@vector.<span style="color:#9900CC;">length</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

</li>
<li><strong>primero</strong>: nos da el primer elemento del montículo (la <em>cima</em>), pero sin eliminarlo de la estructura. Por lo que el algoritmo es:

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">    <span style="color:#9966CC; font-weight:bold;">def</span> primero<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        <span style="color:#0066ff; font-weight:bold;">@vector</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

</li>
<li><strong>cima</strong>: igual que el anterior, pero eliminando el elemento de la cima. Para ello, como se comentó en <em>hundir</em>, se toma el último elemento, se inserta en la cima (que queda vacía) y se <em>hunde</em> hacia su posición correcta. El algoritmo sería:

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">    <span style="color:#9966CC; font-weight:bold;">def</span> cima<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        e = <span style="color:#0066ff; font-weight:bold;">@vector</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span>
        <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#0066ff; font-weight:bold;">@vector</span>.<span style="color:#9900CC;">length</span> <span style="color:#006600; font-weight:bold;">&gt;</span> <span style="color:#006666;">1</span>
            <span style="color:#0066ff; font-weight:bold;">@vector</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#0066ff; font-weight:bold;">@vector</span>.<span style="color:#9900CC;">pop</span>
            hundir<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        <span style="color:#9966CC; font-weight:bold;">else</span>
            <span style="color:#0066ff; font-weight:bold;">@vector</span> = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
        <span style="color:#9966CC; font-weight:bold;">end</span>
        e
    <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

</li>
<li>Como ayuda o soporte vamos a crear dos métodos más, uno genérico a Ruby (y presente en otros lenguajes como Java, PHP y Python, pero con distinto nombre) que permite tener una representación en formato texto (o cadena, o <em>string</em>) del montículo: <strong>to_s</strong>; y otro método que nos dará los elementos del montículo en un vector ordenado (eliminándolos del montículo, claro): <strong>ordenado</strong>; la implementación de ambos:

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">    <span style="color:#9966CC; font-weight:bold;">def</span> to_s<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        <span style="color:#996600;">&quot;[ &quot;</span> <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#0066ff; font-weight:bold;">@vector</span>.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;, &quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#996600;">&quot; ]&quot;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">def</span> ordenado<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        a = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
        a.<span style="color:#9900CC;">push</span> cima <span style="color:#9966CC; font-weight:bold;">while</span> <span style="color:#9966CC; font-weight:bold;">not</span> vacio?
        a
    <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

</li>
</ul>
<p>Una vez visto todo el código, podemos hacer una prueba como la siguiente, en la que insertaremos unos datos aleatorios y obtendremos el resultado de su almacenamiento en forma de montículo, y el resultado en un vector ordenado:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">a = <span style="color:#006600; font-weight:bold;">&#91;</span> <span style="color:#006666;">6</span>, <span style="color:#006666;">4</span>, <span style="color:#006666;">3</span>, <span style="color:#006666;">1</span>, <span style="color:#006666;">5</span>, <span style="color:#006666;">2</span>, <span style="color:#006666;">4</span> <span style="color:#006600; font-weight:bold;">&#93;</span>
&nbsp;
m = MonticuloMaximos.<span style="color:#9900CC;">new</span>
a.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>e<span style="color:#006600; font-weight:bold;">|</span>
    m.<span style="color:#9900CC;">insertar</span><span style="color:#006600; font-weight:bold;">&#40;</span>e<span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#CC0066; font-weight:bold;">puts</span> m
&nbsp;
<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;[ &quot;</span> <span style="color:#006600; font-weight:bold;">+</span> m.<span style="color:#9900CC;">ordenado</span>.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;, &quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#996600;">&quot; ]&quot;</span></pre></div></div>

<p>El resultado es el siguiente:</p>
<pre>
[ 6, 5, 4, 1, 4, 2, 3 ]
[ 6, 5, 4, 4, 3, 2, 1 ]
</pre>
<p><strong>NOTA</strong>: Como se podrá ver en la implementación, este código estaba preparado para vectores que enumerasen sus elementos en base a 1..N, y sin embargo, todos los lenguajes (a excepción de Pascal, Modula-2, y otros similares) numeran los vectores de 0..N-1, por lo que en cada acceso al atributo <tt>@vector</tt> se ha tenido que decrementar en 1 el número, para pasar de la notación 1..N a 0..N-1.</p>
<h3>Conclusiones</h3>
<p>El montículo es un gran elemento que se sigue empleando por su simpleza y óptima respuesta, ya que en lugar de emplear estructura de árbol, grafos o listas, emplea un simple vector, por lo que cada acción a realizar sobre él resulta con un coste bastante reducido. Así mismo, como había dicho al principio, esté presente en todos los lenguajes, ya sea con el nombre de <em>heap</em>, o <em>PriorityQueue</em>, con la capacidad de poder implementar su comparador (para máximos, mínimos o a medida), por lo que no hay excusa para no emplearlo cuando la situación lo requiera.</p>
]]></content:encoded>
			<wfw:commentRss>http://bosqueviejo.net/2012/02/12/monticulos/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Erlang y OTP en acción</title>
		<link>http://bosqueviejo.net/2012/01/22/erlang-y-otp-en-accion/</link>
		<comments>http://bosqueviejo.net/2012/01/22/erlang-y-otp-en-accion/#comments</comments>
		<pubDate>Sun, 22 Jan 2012 01:02:42 +0000</pubDate>
		<dc:creator>bombadil</dc:creator>
				<category><![CDATA[Libros]]></category>
		<category><![CDATA[eric merritt]]></category>
		<category><![CDATA[erlang]]></category>
		<category><![CDATA[manning]]></category>
		<category><![CDATA[martin logan]]></category>
		<category><![CDATA[otp]]></category>
		<category><![CDATA[richard carlsson]]></category>

		<guid isPermaLink="false">http://bosqueviejo.net/?p=1215</guid>
		<description><![CDATA[ El pasado lunes estaba camino del dentista cuando, dejando el coche, topé con la librería Cocodrilo Libros. Entré y pregunté por libros de Erlang, y como ya sabía, me mostraron el de O&#8217;Reilly de Francesco Cesarini y el de Pragmatic Programmers de Joe Armstrong&#8230; pero además, una editorial de la que aún no había leído ningún libro, Manning, tenía un libro con el título Erlang and OTP in action, la curiosidad me pudo y lo compré.
Con este título nos encontramos un libro bastante curioso sobre esta tecnología, y digo tecnología, porque no solo cubre el lenguaje de programación funcional Erlang, sino también el framework de desarrollo OTP. El libro se estructura de forma que la introducción al lenguaje es efímera pero clara, y nos plantean, casi desde el principio, la creación de un proyecto de caché, al que van agregando los elementos de OTP, hasta culminar en un proyecto completo, funcional, y que contiene, desde la práctica, todos y cada uno de los elementos que podemos encontrar en el framework OTP.
Da un recorrido por las herramientas de Erlang, de monitorización, de depuración y los profilers, así como Mnesia (la base de datos que trae consigo Erlang) y los mecanismos [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://bosqueviejo.net/wp-content/uploads/logan_cover150-150x150.jpg" alt="" title="logan_cover150" width="150" height="150" class="alignleft size-thumbnail wp-image-1216" /> El pasado lunes estaba camino del dentista cuando, dejando el coche, topé con la librería <a href="http://www.cocodrilolibros.com/">Cocodrilo Libros</a>. Entré y pregunté por libros de Erlang, y como ya sabía, me mostraron el de O&#8217;Reilly de Francesco Cesarini y el de Pragmatic Programmers de Joe Armstrong&#8230; pero además, una editorial de la que aún no había leído ningún libro, Manning, tenía un libro con el título <em>Erlang and OTP in action</em>, la curiosidad me pudo y lo compré.</p>
<p>Con este título nos encontramos un libro bastante curioso sobre esta tecnología, y digo tecnología, porque no solo cubre el lenguaje de programación funcional Erlang, sino también el framework de desarrollo OTP. El libro se estructura de forma que la introducción al lenguaje es efímera pero clara, y nos plantean, casi desde el principio, la creación de un proyecto de caché, al que van agregando los elementos de OTP, hasta culminar en un proyecto completo, funcional, y que contiene, desde la práctica, todos y cada uno de los elementos que podemos encontrar en el framework OTP.</p>
<p>Da un recorrido por las herramientas de Erlang, de monitorización, de depuración y los profilers, así como Mnesia (la base de datos que trae consigo Erlang) y los mecanismos para crear, publicar y actualizar en caliente aplicaciones en Erlang.</p>
<p>Sus autores, entusiastas de Erlang, trabajan en el proyecto <a href="http://erlware.com/">Erlware</a>, además de mantener el libro. Estos son Martin Logan, Eric Merritt y Richard Carlsson. El prólogo está escrito por Ulf Wiger, CTO de Erlang Solutions.</p>
<p>Comentar, simplemente, que el libro me ha gustado mucho por su carácter directo. Muestra un proyecto en proceso de creación con código completo y explicando, no solo la historia de cada uno de los elementos y el porqué funcionan y se comportan como se comportan, sino también mostrando la utilidad práctica y para el proyecto de cada elemento, siendo como ejemplo de uso de los elementos de que dispone Erlang/OTP.</p>
<p>Su redacción es amena y para nada pesada y, aún siendo una temática muy densa, se desarrolla con ejemplos, código y gráficos a lo largo de unas 370 páginas, aproximadamente, quedando explicado todo de forma muy concisa y clara. El autor se centra sobretodo en OTP y el desarrollo de soluciones reales más que en la sintaxis y propiedades del lenguaje, con lo que consigue que el texto sea más pragmático y menos académico que el propio libro de Joe Armstrong.</p>
<p>Recomiendo su lectura para todo aquél que desee aprender Erlang/OTP con una curva de aprendizaje más suavizada.</p>
]]></content:encoded>
			<wfw:commentRss>http://bosqueviejo.net/2012/01/22/erlang-y-otp-en-accion/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Una clase/objeto/proceso, Una responsabilidad</title>
		<link>http://bosqueviejo.net/2012/01/10/una-claseobjetoproceso-una-responsabilidad/</link>
		<comments>http://bosqueviejo.net/2012/01/10/una-claseobjetoproceso-una-responsabilidad/#comments</comments>
		<pubDate>Tue, 10 Jan 2012 14:41:21 +0000</pubDate>
		<dc:creator>bombadil</dc:creator>
				<category><![CDATA[Desarrollo de Software]]></category>
		<category><![CDATA[carlos ble]]></category>
		<category><![CDATA[programación concurrente]]></category>
		<category><![CDATA[programación orientada a objetos]]></category>
		<category><![CDATA[tdd]]></category>

		<guid isPermaLink="false">http://bosqueviejo.net/?p=1201</guid>
		<description><![CDATA[ Una clase, una responsabilidad, fue uno de los textos que se me quedó grabado tras la lectura del libro Diseño Ágil con TDD de Carlos Blé.
Analizar esa simple expresión nos lleva a una regla importantísima que nos permite diseñar programas orientados a objetos y orientados a concurrencia, que sean muy óptimos y fácilmente trazables. Nos lleva a la vía en la que realizar TDD se hace obvio, y la deuda técnica desaparezca, facilitando refactorizaciones, encontrar fallos y desarrollar software con elementos pequeños, y combinando estos elementos (tal y como reza la filosofía unix) de modo que se pueda construir algo mayor, a alto nivel, sin perder el control granular de la programación a bajo y medio nivel.
Programación Orientada a Objetos
Imaginemos que tenemos que crear un programa en el que se administra un almacén. Este almacén tiene objetos que pertenecen a varias categorías, y se tiene que mantener un peticionario de las tiendas que solicitan una reposición de ciertos productos. Si lo pensamos entorno a base de datos, diagramas de Entidad/Relación (E/R), obtenemos las entidades: productos, categorías, tiendas, solicitudes; con sus respectivas relaciones.
Usando programación orientada a objetos, obtendremos que ese diagrama de clases se puede especificar muy fácilmente a través [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://bosqueviejo.net/wp-content/uploads/programacion-orientada-a-objetos-150x150.jpg" alt="" title="programacion-orientada-a-objetos" width="150" height="150" class="alignleft size-thumbnail wp-image-1202" /> <em>Una clase, una responsabilidad</em>, fue uno de los textos que se me quedó grabado tras la lectura del libro <a href="/2010/01/12/tdd-libro-en-castellano/">Diseño Ágil con TDD</a> de <a href="http://www.carlosble.com/">Carlos Blé</a>.<span id="more-1201"></span></p>
<p>Analizar esa simple expresión nos lleva a una regla importantísima que nos permite diseñar programas orientados a objetos y orientados a concurrencia, que sean muy óptimos y fácilmente trazables. Nos lleva a la vía en la que realizar TDD se hace obvio, y la deuda técnica desaparezca, facilitando refactorizaciones, encontrar fallos y desarrollar software con elementos pequeños, y combinando estos elementos (tal y como reza la <a href="/2008/09/22/filosofia-unix/">filosofía unix</a>) de modo que se pueda construir algo mayor, a alto nivel, sin perder el control granular de la programación a bajo y medio nivel.</p>
<h3>Programación Orientada a Objetos</h3>
<p>Imaginemos que tenemos que crear un programa en el que se administra un almacén. Este almacén tiene objetos que pertenecen a varias categorías, y se tiene que mantener un peticionario de las tiendas que solicitan una reposición de ciertos productos. Si lo pensamos entorno a base de datos, diagramas de Entidad/Relación (E/R), obtenemos las entidades: productos, categorías, tiendas, solicitudes; con sus respectivas relaciones.</p>
<p>Usando programación orientada a objetos, obtendremos que ese diagrama de clases se puede especificar muy fácilmente a través de la creación de las diferentes clases. Podemos usar algún método de persistencia, y tendremos nuestros elementos, con funcionalidad agregada dentro de cada uno de las clases, por ejemplo, en solicitudes: solicitaProducto, asociaTienda, &#8230;. ya depende de cómo lo queramos (o podamos) montar.</p>
<p>Ahora, si una clase como <em>productos</em>, de pronto agrega más funcionalidad, como por ejemplo <em>fabricaProducto</em>, <em>compruebaDisponibilidad</em>, &#8230; podemos ver que el producto ya tiene varias responsabilidades, es decir, tendremos la propia responsabilidad de mantener los datos del producto, comprobar su caducidad, etc. a responsabilidades como <em>fabricaProducto</em> que debería de estar en una clase de tipo <em>fábrica</em>, o <em>compruebaDisponibilidad</em>, que debería de estar más bien en una clase de tipo <em>almacén</em>.</p>
<p>Si no respetamos esta norma, el contrato entre objetos se convierte en un auténtico caos, que puede derivar en ejecuciones difíciles de trazar y con resultados inesperados.</p>
<h3>Programación Orientada a Concurrencia</h3>
<p>En este caso, nos encontramos que definimos código que se ejecutará como un proceso aislado, estos códigos pueden ser, al igual que en el ejemplo anterior: productos, categorías, tiendas y solicitudes. La unidad de persistencia igualmente se puede conseguir de cualquier forma que se desee (fichero o base de datos).</p>
<p>En lugar de instanciar objetos, procedemos a crear procesos. Cada proceso al ejecutarse tiene su propio espacio de memoria, y de cada código específico se pueden generar tantos procesos como se necesiten. La llamada a los métodos, tal y como se llama en programación orientada a objetos: paso de mensajes; se consigue así mismo, realizando una petición o enviando un mensaje al proceso. Por lo que, por ejemplo, a un proceso de tipo solicitudes, podemos pedirle <em>solicitarProducto</em>, <em>asociaTienda</em>, &#8230; o cualquier otra función que tenga montada el sistema.</p>
<p>Al igual que el caso anterior, la responsabilidad de un proceso debe de ser única. Si no se cumpliese la norma, podríamos encontrarnos con interbloqueos al intentar llamar o solicitar dos cosas al mismo proceso por bucles (o lazos) generados sin darnos cuenta.</p>
<h3>Conclusiones</h3>
<p>Las metodologías nos ayudan a desarrollar de una forma más organizada nuestros programas. Desarrollar software con ayuda de patrones y normas como esta, hacen que el software sea más claro y fácil de trazar, así como de ampliar y mantener. Además, estos son estándares en la industria del software, con lo que, cualquiera que conozca los patrones y normas específicas, puede entender el código y sumarse al desarrollo y ampliación del mismo sin problemas.</p>
]]></content:encoded>
			<wfw:commentRss>http://bosqueviejo.net/2012/01/10/una-claseobjetoproceso-una-responsabilidad/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Redirigiendo tráfico</title>
		<link>http://bosqueviejo.net/2012/01/06/redirigiendo-trafico/</link>
		<comments>http://bosqueviejo.net/2012/01/06/redirigiendo-trafico/#comments</comments>
		<pubDate>Thu, 05 Jan 2012 23:40:15 +0000</pubDate>
		<dc:creator>bombadil</dc:creator>
				<category><![CDATA[redes]]></category>
		<category><![CDATA[administración de sistemas]]></category>
		<category><![CDATA[iptables]]></category>
		<category><![CDATA[routing]]></category>

		<guid isPermaLink="false">http://bosqueviejo.net/?p=1190</guid>
		<description><![CDATA[ He estado revisando para cambiar el servidor a otro nuevo, con una versión limpia y actualizada de Debian (la nueva versión Squeeze), por lo que, toca migrarlo todo.
Esto puede constituir un pequeño desastre para todos los servicios que tengo montados, ya que hay que copiar todos los datos al nuevo servidor, tirar el servicio antes para que los datos no cambien, y levantar los servicios en el nuevo, asegurándose de que todo funcione&#8230; vale, por ahí, ya sé que van a ser un par de horas&#8230; pero el DNS&#8230; con su propia caché y demás, eso sí puede ser un gran problema.
Por ese motivo me puse a buscar y, a modo de post-it, me lo dejo aquí escrito para futuro, y por si alguien lo necesita también. Básicamente es: cómo redirigir el tráfico de un servidor a otro, empleando iptables.
Redirigiendo&#8230;
Vale, estoy en el antiguo servidor, tengo email y web. Los puertos por los que llega la comunicación, todos TCP, y posibilidad de SSL, pero en eso no hay mayor problema. En esencia tengo que cuidarme de las peticiones a los puertos: 80 (http), 443 (https), 25 (smtp), 465 (ssmtp), 110 (pop3), 995 (pop3s), 143 (imap) y 993 (imaps).
Buscando, vi [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://bosqueviejo.net/wp-content/uploads/redes-150x150.jpg" alt="" title="redes" width="150" height="150" class="alignleft size-thumbnail wp-image-1194" /> He estado revisando para cambiar el servidor a otro nuevo, con una versión limpia y actualizada de Debian (la nueva versión <a href="http://bosqueviejo.net/2011/02/14/debian-squeeze-liberada/">Squeeze</a>), por lo que, toca migrarlo todo.</p>
<p>Esto puede constituir un pequeño desastre para todos los servicios que tengo montados, ya que hay que copiar todos los datos al nuevo servidor, tirar el servicio antes para que los datos no cambien, y levantar los servicios en el nuevo, asegurándose de que todo funcione&#8230; vale, por ahí, ya sé que van a ser un par de horas&#8230; pero el DNS&#8230; con su propia caché y demás, eso sí puede ser un gran problema.</p>
<p>Por ese motivo me puse a buscar y, a modo de post-it, me lo dejo aquí escrito para futuro, y por si alguien lo necesita también. Básicamente es: <strong>cómo redirigir el tráfico de un servidor a otro</strong>, empleando iptables.</p>
<h3>Redirigiendo&#8230;</h3>
<p>Vale, estoy en el antiguo servidor, tengo email y web. Los puertos por los que llega la comunicación, todos TCP, y posibilidad de SSL, pero en eso no hay mayor problema. En esencia tengo que cuidarme de las peticiones a los puertos: 80 (http), 443 (https), 25 (smtp), 465 (ssmtp), 110 (pop3), 995 (pop3s), 143 (imap) y 993 (imaps).</p>
<p>Buscando, vi <a href="http://www.simplehelp.net/2009/04/15/how-to-redirect-traffic-to-another-machine-in-linux/">esta web sobre como redireccionar tráfico</a>, por lo que, escribí:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">echo 1 &gt;/proc/sys/net/ipv4/ip_forward
export IP=XXX.XXX.XXX.XXX
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination $IP
iptables -t nat -A POSTROUTING -p tcp -d $IP --dport 80 -j MASQUERADE</pre></div></div>

<p><strong>NOTA</strong>: como es lógico, hay que cambiar XXX.XXX.XXX.XXX por la IP del servidor al que se quieren redireccionar las peticiones al puerto 80.</p>
<p>Lo que hacen estos comandos es:</p>
<ol>
<li>Indica al kernel que puede hacer <em>forward</em> de los paquetes que pasen por su interfaz de red.</li>
<li>Indica al sistema que los paquetes entrantes al puerto 80 sean dirigidos a la $IP indicada.</li>
<li>Indica al sistema que los paquetes que deban de salir, se <em>emascaren</em> modificando su IP de origen por la propia.</li>
</ol>
<p>Con esto conseguimos que la comunicación hacia el puerto 80 pase sin problemas al otro servidor. Lo único, es que se <em>desvirtúan</em> las estadísticas, ya que para el servidor web, todas las peticiones son del servidor que redirecciona las peticiones, pero si es un recurso temporal (como es mi caso), no tiene mucha o mayor importancia <img src='http://bosqueviejo.net/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<h3>¿Cómo funciona el enrutado?</h3>
<p>Encontré también <a href="http://billauer.co.il/ipmasq-html.html">otra página</a> donde se explica bastante bien (aunque algo esquemática) la forma en que funciona el enrutado de paquetes empleando <tt>iptables</tt>, el gráfico:</p>
<p><a href="http://bosqueviejo.net/wp-content/uploads/ipmasq-html1x.gif"><img src="http://bosqueviejo.net/wp-content/uploads/ipmasq-html1x-300x243.gif" alt="" title="ipmasq-html1x" width="300" height="243" class="aligncenter size-medium wp-image-1195" /></a></p>
<p>Como puede verse, el paquete pasa por la cadena de reglas PREROUTING al entrar, es procesado y, cuando se detecta que es para otra máquina, se pasa a FORWARD y después a POSTROUTING, donde se pueden agregar reglas de modificación antes de que el paquete sea entregado a su destino.</p>
<p>Recomiendo echar un vistazo al enlace dado para ampliar más sobre el tema.</p>
<h3>Conclusiones</h3>
<p>Nada es perfecto al 100%, por ejemplo, esto mismo lo probé con XMPP, y no funciona correctamente, ya que la comunicación de s2s del protocolo espera que los mensajes lleguen del dominio (e IP) al que se solicita información, mientras que, estos mensajes, en su mayoría, al estar direccionados al dominio, no es la misma IP. No obstante, como medida temporal y sobretodo para HTTP, el apaño lo da.</p>
]]></content:encoded>
			<wfw:commentRss>http://bosqueviejo.net/2012/01/06/redirigiendo-trafico/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>NodeJS: el servidor JavaScript</title>
		<link>http://bosqueviejo.net/2012/01/03/nodejs-el-servidor-javascript/</link>
		<comments>http://bosqueviejo.net/2012/01/03/nodejs-el-servidor-javascript/#comments</comments>
		<pubDate>Tue, 03 Jan 2012 18:26:14 +0000</pubDate>
		<dc:creator>bombadil</dc:creator>
				<category><![CDATA[Desarrollo de Software]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[node.js]]></category>
		<category><![CDATA[programación orientada a eventos]]></category>
		<category><![CDATA[ryan dahl]]></category>

		<guid isPermaLink="false">http://bosqueviejo.net/?p=1158</guid>
		<description><![CDATA[ El servidor Node.js vió la luz de manos de Ryan Dahl en 2009, la motivación, según la entrevista que BostInno le realizó en enero de 2011, es la arquitectura de E/S orientada a eventos.
Según Dahl: estuve involucrado, de vez en cuando, escribiendo códigos pequeños orientados a eventos. Me gustó el diseño de los servidores orientados a eventos porque sentía que eran más fáciles de comprender: el estado es mantenido en alguna estructura y puedes girar y girar modificando el estado. No había un bucle infinito haciendo bloqueos de lectura o aceptaciones desde los sockets. Me veía capaz de hacer servidores de muy baja latencia usando solo E/S sin bloqueos.
La estructura
Node.js es un intérprete JavaScript mono-hilo, lo cual indica que, la ejecución de un programa, es individual, no se puede diseccionar y, por lo tanto, no comparte información con otros hilos (ya que no los hay), ni con otros procesos, a menos que sea por paso de mensajes de comunicación entre ellos.
El sistema se basa, por sus librerías creadas a tal efecto, en la programación orientada a eventos. Si se quiere crear un servidor que escuche de un determinado puerto, por ejemplo, un servidor web, podemos emplear el siguiente código:

var [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://bosqueviejo.net/wp-content/uploads/nodejs-150x150.jpg" alt="" title="nodejs" width="150" height="150" class="alignleft size-thumbnail wp-image-1182" /> El servidor Node.js vió la luz de manos de Ryan Dahl en 2009, la motivación, según la <a href="http://bostinno.com/2011/01/31/node-js-interview-4-questions-with-creator-ryan-dahl/">entrevista que BostInno</a> le realizó en enero de 2011, es la arquitectura de E/S orientada a eventos.</p>
<p>Según <strong>Dahl</strong>: <em>estuve involucrado, de vez en cuando, escribiendo códigos pequeños orientados a eventos. Me gustó el diseño de los servidores orientados a eventos porque sentía que eran más fáciles de comprender: el estado es mantenido en alguna estructura y puedes girar y girar modificando el estado. No había un bucle infinito haciendo bloqueos de lectura o aceptaciones desde los sockets. Me veía capaz de hacer servidores de muy baja latencia usando solo E/S sin bloqueos.</em></p>
<h3>La estructura</h3>
<p>Node.js es un intérprete JavaScript mono-hilo, lo cual indica que, la ejecución de un programa, es individual, no se puede diseccionar y, por lo tanto, no comparte información con otros hilos (ya que no los hay), ni con otros procesos, a menos que sea por paso de mensajes de comunicación entre ellos.</p>
<p>El sistema se basa, por sus librerías creadas a tal efecto, en la programación orientada a eventos. Si se quiere crear un servidor que escuche de un determinado puerto, por ejemplo, un servidor web, podemos emplear el siguiente código:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> http <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'http'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
http.<span style="color: #660066;">createServer</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>req<span style="color: #339933;">,</span> res<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  res.<span style="color: #660066;">writeHead</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">200</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span><span style="color: #3366CC;">'Content-Type'</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">'text/plain'</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  res.<span style="color: #660066;">end</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Hello World<span style="color: #000099; font-weight: bold;">\n</span>'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">listen</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1337</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;127.0.0.1&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Server running at http://127.0.0.1:1337/'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Si lo lanzamos con el comando: <tt>node http.js</tt>; veremos que se ejecuta y al lanzar un navegador a la URL que indica el sistema, en el navegador podemos ver el texto <em>Hello World</em>. Podemos ver igualmente que si agregamos una espera al proceso, tal que así:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> http <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'http'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
http.<span style="color: #660066;">createServer</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>req<span style="color: #339933;">,</span> res<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #003366; font-weight: bold;">var</span> now <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">getTime</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">getTime</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&lt;</span> now <span style="color: #339933;">+</span> <span style="color: #CC0000;">5000</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// nothing</span>
  <span style="color: #009900;">&#125;</span>
  res.<span style="color: #660066;">writeHead</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">200</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span><span style="color: #3366CC;">'Content-Type'</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">'text/plain'</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  res.<span style="color: #660066;">end</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Hello World<span style="color: #000099; font-weight: bold;">\n</span>'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">listen</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1337</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;127.0.0.1&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Server running at http://127.0.0.1:1337/'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>El sistema espera 5 segundos antes de dar el mensaje, por lo que si abrimos varias lengüetas, pestañas o ventanas del navegador, nos daremos cuenta de que las peticiones se realizan de forma secuencial, esperando 5 segundos cada petición, cuando la anterior termina.</p>
<h3>Librerías específicas</h3>
<p>Dahl seleccionó ECMAScript (ya que V8 se basa en este y no en JavaScript&#8230; aunque realmente ECMAScript sea una estandarización de JavaScript), porque está poco desarrollado en base a librerías. ECMAScript se ha empleado siempre de forma embebida y sobretodo en navegadores, por lo que las librerías de funciones y objetos siempre han sido portadas por los navegadores y fuera de ese contexto, no tienen gran utilidad.</p>
<p>La librería del sistema <em>http</em> es una de las muchas que podemos encontrar en Node.js, hay otras como File, JSON, LDAP, sql, MD5, &#8230; todas ellas con la capacidad de instalarse de forma muy simple:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">npm install JSON</pre></div></div>

<p>El listado y búsqueda de paquetes se puede realizar a través de la <a href="http://search.npmjs.org/">página oficial de npm</a>. Las librerías que ya vienen instaladas se pueden ver <a href="http://nodejs.org/docs/latest/api/index.html">aquí</a>, junto con su documentación.</p>
<h3>Conclusiones</h3>
<p>Node.js es en sí un intérprete con librerías y una metodología detrás que da que pensar. Como en artículos anteriores, he hablado muchas veces de que JavaScript se ha considerado muchas veces un lenguaje de futuro. Quizás con Node.js, alcanzando un nivel de formalización adecuado, quizás podamos ver ese futuro más férreo y no tan difuso.</p>
<p>Cabe destacar que, entre las extensiones diponibles, se encuentra <em>coffescript</em>, por lo que, también es posible que encontremos diversidad a medida que vaya creciendo el proyecto. De momento, y después de vista la entrevista de hace un año y los progresos que sigue teniendo, se augura un buen futuro a para esta herramienta.</p>
]]></content:encoded>
			<wfw:commentRss>http://bosqueviejo.net/2012/01/03/nodejs-el-servidor-javascript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Las gemas de Ruby</title>
		<link>http://bosqueviejo.net/2012/01/02/las-gemas-de-ruby/</link>
		<comments>http://bosqueviejo.net/2012/01/02/las-gemas-de-ruby/#comments</comments>
		<pubDate>Mon, 02 Jan 2012 17:03:31 +0000</pubDate>
		<dc:creator>bombadil</dc:creator>
				<category><![CDATA[programación]]></category>
		<category><![CDATA[gem]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[rubygems]]></category>

		<guid isPermaLink="false">http://bosqueviejo.net/?p=1165</guid>
		<description><![CDATA[ Tengo a Ruby un poco abandonado, por lo que me he decidido a escribir un poco acerca de él, al igual que hice con Python, para detallar un poco cómo son los paquetes de código (o librerías) de Ruby: las gemas.
Las gemas de Ruby son paquetes de librerías para Ruby que se instalan en el sistema y quedan listas para ser usadas, con un simple require o con mecanismos que aporta el propio sistema de gemas para Ruby.
El gestor de gemas: rubygems
En distribuciones de GNU/Linux, e instalaciones automáticas para Windows, se nos habilita un comando, generalmente, que nos permite agregar librerías y código de un repositorio muy extenso de código listo para usar. Esto es conocido como el gestor de gemas, rubygems, o simplemente gem.
El gestor de gemas es un comando que nos permite listar las gemas instaladas, buscar gemas remotas o localmente (de las instaladas), instalar, actualizar y eliminar gemas. Se puede saber si está instalado simplemente ejecutando:

gem --version

La última versión a día de hoy es la 1.8.12, actualizar el sistema de gemas es tan simple como ejecutar:

gem update --system

Instalar una gema
Por ejemplo, si queremos usar el código siguiente:

require &#34;rubygems&#34;;
require &#34;json&#34;;
&#160;
puts &#91; &#34;hola a todos&#34;, 12, &#34;C/Sin nombre, [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://bosqueviejo.net/wp-content/uploads/rubygems-150x150.jpg" alt="" title="rubygems" width="150" height="150" class="alignleft size-thumbnail wp-image-1166" /> Tengo a Ruby un poco abandonado, por lo que me he decidido a escribir un poco acerca de él, al igual que hice con Python, para detallar un poco cómo son los paquetes de código (o librerías) de Ruby: las gemas.<span id="more-1165"></span></p>
<p>Las gemas de Ruby son paquetes de librerías para Ruby que se instalan en el sistema y quedan listas para ser usadas, con un simple <em>require</em> o con mecanismos que aporta el propio sistema de gemas para Ruby.</p>
<h3>El gestor de gemas: rubygems</h3>
<p>En distribuciones de GNU/Linux, e instalaciones automáticas para Windows, se nos habilita un comando, generalmente, que nos permite agregar librerías y código de un repositorio muy extenso de código listo para usar. Esto es conocido como el gestor de gemas, <em>rubygems</em>, o simplemente <em>gem</em>.</p>
<p>El gestor de gemas es un comando que nos permite listar las gemas instaladas, buscar gemas remotas o localmente (de las instaladas), instalar, actualizar y eliminar gemas. Se puede saber si está instalado simplemente ejecutando:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">gem --version</pre></div></div>

<p>La última versión a día de hoy es la 1.8.12, actualizar el sistema de gemas es tan simple como ejecutar:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">gem update --system</pre></div></div>

<h3>Instalar una gema</h3>
<p>Por ejemplo, si queremos usar el código siguiente:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">&quot;rubygems&quot;</span>;
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">&quot;json&quot;</span>;
&nbsp;
<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#006600; font-weight:bold;">&#91;</span> <span style="color:#996600;">&quot;hola a todos&quot;</span>, <span style="color:#006666;">12</span>, <span style="color:#996600;">&quot;C/Sin nombre, 25&quot;</span> <span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">to_json</span></pre></div></div>

<p>Tendremos que instalar previamente la gema <em>json</em>. Para instalarla, solo tenemos que ejecutar el siguiente comando:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">$ sudo gem install json
[sudo] password for marubio: 
Building native extensions.  This could take a while...
Successfully installed json-1.6.4
1 gem installed
Installing ri documentation for json-1.6.4...
Installing RDoc documentation for json-1.6.4...</pre></div></div>

<p>Como se puede apreciar, se instala la gema y se genera la documentación para <em>ri</em> y <em>rdoc</em>. La generación de la documentación es bastante lenta y si tenemos que instalar muchas gemas, puede ser algo tedioso. Se puede eliminar esta tarea agregando al comando de instalación: <tt>--no-ri --no-rdoc</tt></p>
<p>Ahora, cuando listemos los paquetes instalados podremos ver:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">$ sudo gem list
&nbsp;
*** LOCAL GEMS ***
&nbsp;
json (1.6.4)</pre></div></div>

<p>Nos indica la versión, ya que podríamos tener varias versiones instaladas y conviviendo, y desde el código emplear la que requiramos específicamente. Si queremos instalar una versión específica de un paquete, podemos hacerlo agregando la opción, por ejemplo: <tt>--v=1.6.1</tt></p>
<h3>Buscando una gema</h3>
<p>Si queremos buscar una gema específica del directorio de gemas, podemos hacerlo a través de la propia página web: <a href="http://rubygems.org">RubyGems</a>; o a través del comando:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">$ gem search -r jsonn
&nbsp;
*** REMOTE GEMS ***
&nbsp;
active_record_serialize_json (0.1.2)
activejson (0.1.2)
activeresource_json_patch (0.0.1)
assert_json (0.1.1)
capcode-render-json (0.2.0)
capybara-json (0.1.1)
colorful_json (0.9.1)
csv2json (0.2.0)
cucumber-json (0.0.2)
dm-json-search (0.0.3)
[...]</pre></div></div>

<p>La base de datos de gemas tiene la friolera de más de 32 mil gemas, por lo que, no es de extrañar que ante algo trivial (como JSON) puedan aparecer cientos de gemas. A la hora de buscar deberemos de ser más precisos con los términos a elegir.</p>
<h3>Conclusiones</h3>
<p>Ha sido una introducción muy ligera a este entorno de gestión de paquetes de Ruby, lo sé, pero al menos complementa un poco la entrada de hace algunos meses sobre <a href="/2011/03/07/bundler-despliega-facilmente-rails/">Bundler</a> y da un poco de información sobre los comandos más usuales a la hora de instalar una librería en Ruby, ya sea para código scripting o para Rails.</p>
]]></content:encoded>
			<wfw:commentRss>http://bosqueviejo.net/2012/01/02/las-gemas-de-ruby/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>NewSQL: dos vías para mejorar SQL</title>
		<link>http://bosqueviejo.net/2011/12/20/newsql-dos-vias-para-mejorar-sql/</link>
		<comments>http://bosqueviejo.net/2011/12/20/newsql-dos-vias-para-mejorar-sql/#comments</comments>
		<pubDate>Tue, 20 Dec 2011 14:40:30 +0000</pubDate>
		<dc:creator>bombadil</dc:creator>
				<category><![CDATA[Base de Datos]]></category>
		<category><![CDATA[jdb]]></category>
		<category><![CDATA[newsql]]></category>
		<category><![CDATA[s2]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://bosqueviejo.net/?p=1171</guid>
		<description><![CDATA[ Últimamente hay muchos medios (como SDJournal) que van haciendo eco de una nueva versión, según algunos más fácil, de SQL.
Según vemos en la página oficial del proyecto, NewSQL dispone a día de hoy de dos posibles gramáticas a implementar. Una de ellas está basada en la Java Database (JDB) y otra sería la evolución propia de SQL (SQL II, o S2). Aún no se ha decidido qué versión será la empleada como newSQL, por lo que, podemos decir que es un proyecto a futuro y no hay implementación real de momento.
Implementación JDB
La sintaxis que se desea implementar al estilo JDB tendría esta forma en comparación con el SQL actual:


SQL
NewSQL JDB



CREATE TABLE TEST (
&#160;&#160;ID INT PRIMARY KEY,
&#160;&#160;NAME VARCHAR(255)
)


test = new table(
&#160;&#160;int id,
&#160;&#160;string name,
&#160;&#160;key(id)
)



INSERT INTO TEST VALUES(1, &#8216;Hello&#8217;)
test.add(1, &#8216;Hello&#8217;)


SELECT * FROM TEST
test.get()


SELECT T1.ID, T2.NAME FROM TEST T1, TEST T2 WHERE T.ID = T2.ID
t1 = test; t2 = test; t1.join(t2[t1.id==t2.id]).get(t1.id, t2.name)


UPDATE TEST SET NAME=&#8217;Hi&#8217; WHERE ID=1
test[id==1].set(name=&#8217;Hi&#8217;)


DELETE FROM TEST WHERE ID=1
test[id==1].delete()


DROP TABLE TEST
test.drop()


La sintaxis puede parecer bastante clara y limpia, sobre todo para los que programan con lenguajes del estilo de Java, C++, PHP y de sintaxis derivada. No obstante, si tenemos en cuenta que esto sustituye a SQL, pero no a la [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://bosqueviejo.net/wp-content/uploads/sql-150x150.jpg" alt="" title="sql" width="150" height="150" class="alignleft size-thumbnail wp-image-1172" /> Últimamente hay muchos medios (como <a href="http://en.sdjournal.org/software-developers-journal-511-5/">SDJournal</a>) que van haciendo eco de una nueva versión, según algunos más fácil, de SQL.</p>
<p>Según vemos en la <a href="http://newsql.sourceforge.net/">página oficial</a> del proyecto, NewSQL dispone a día de hoy de dos posibles gramáticas a implementar. Una de ellas está basada en la <em>Java Database</em> (JDB) y otra sería la evolución propia de SQL (SQL II, o S2). Aún no se ha decidido qué versión será la empleada como newSQL, por lo que, podemos decir que es un proyecto a futuro y no hay implementación real de momento.</p>
<h3>Implementación JDB</h3>
<p>La sintaxis que se desea implementar al estilo JDB tendría esta forma en comparación con el SQL actual:</p>
<table>
<tr>
<th>SQL</th>
<th>NewSQL JDB</th>
</tr>
<tr>
<td>
CREATE TABLE TEST (<br />
&nbsp;&nbsp;ID INT PRIMARY KEY,<br />
&nbsp;&nbsp;NAME VARCHAR(255)<br />
)
</td>
<td>
test = new table(<br />
&nbsp;&nbsp;int id,<br />
&nbsp;&nbsp;string name,<br />
&nbsp;&nbsp;key(id)<br />
)
</td>
</tr>
<tr>
<td>INSERT INTO TEST VALUES(1, &#8216;Hello&#8217;)</td>
<td>test.add(1, &#8216;Hello&#8217;)</td>
</tr>
<tr>
<td>SELECT * FROM TEST</td>
<td>test.get()</td>
</tr>
<tr>
<td>SELECT T1.ID, T2.NAME FROM TEST T1, TEST T2 WHERE T.ID = T2.ID</td>
<td>t1 = test; t2 = test; t1.join(t2[t1.id==t2.id]).get(t1.id, t2.name)</td>
</tr>
<tr>
<td>UPDATE TEST SET NAME=&#8217;Hi&#8217; WHERE ID=1</td>
<td>test[id==1].set(name=&#8217;Hi&#8217;)</td>
</tr>
<tr>
<td>DELETE FROM TEST WHERE ID=1</td>
<td>test[id==1].delete()</td>
</tr>
<tr>
<td>DROP TABLE TEST</td>
<td>test.drop()</td>
</tr>
</table>
<p>La sintaxis puede parecer bastante clara y limpia, sobre todo para los que programan con lenguajes del estilo de Java, C++, PHP y de sintaxis derivada. No obstante, si tenemos en cuenta que esto sustituye a SQL, pero no a la forma de enviar las consultas, generar una cadena de texto de este estilo para enviarla al Sistema Gestor de Base de Datos, puede resultar bastante tedioso igualmente.</p>
<p>Hay bastantes dudas sobre, por ejemplo el INSERT, ya que, ahí nos muestran una inserción completa, pero, ¿y si queremos que haya datos por defecto y solo declarar algunos? &#8230; igualmente, en la cadena de búsqueda, da la sensación de haber empleado XPath para seleccionar las tuplas&#8230; ¿cómo se haría si se busca por un criterio en lugar de un ID? &#8230; al final puede quedar algo difícil de entender, realmente.</p>
<h3>SQL II (S2)</h3>
<p>La otra opción, es una versión evolucionada de SQL (o simplificada, según se mire), que tiene la siguiente forma:</p>
<table>
<tr>
<th>SQL</th>
<th>NewSQL JDB</th>
</tr>
<tr>
<td>
CREATE TABLE TEST (<br />
&nbsp;&nbsp;ID INT PRIMARY KEY,<br />
&nbsp;&nbsp;NAME VARCHAR(255)<br />
)
</td>
<td>
create table test (<br />
&nbsp;&nbsp;id int;<br />
&nbsp;&nbsp;name string;<br />
&nbsp;&nbsp;primary key(id)<br />
)
</td>
</tr>
<tr>
<td>INSERT INTO TEST VALUES(1, &#8216;Hello&#8217;)</td>
<td>insert test (1, &#8216;Hello&#8217;)</td>
</tr>
<tr>
<td>SELECT * FROM TEST</td>
<td>select test</td>
</tr>
<tr>
<td>SELECT T1.ID, T2.NAME FROM TEST T1, TEST T2 WHERE T.ID = T2.ID</td>
<td>select t1:test join t2:test on t1.id == t2.id get t1.id, t2.name</td>
</tr>
<tr>
<td>UPDATE TEST SET NAME=&#8217;Hi&#8217; WHERE ID=1</td>
<td>update test set id=1 where name==&#8217;Hi&#8217;</td>
</tr>
<tr>
<td>DELETE FROM TEST WHERE ID=1</td>
<td>delete test where id==1</td>
</tr>
<tr>
<td>DROP TABLE TEST</td>
<td>drop test</td>
</tr>
</table>
<p>Revisándolo, se ve claro que no aporta mucho, realmente, a lo que se usa de hoy en día. Es más, se intenta introducir de forma fija el uso del operador &#8220;==&#8221; en lugar de &#8220;=&#8221;, lo cual resulta extraño e inapropiado, desde mi punto de vista, ya que, en todo caso, cambiaría mejor el &#8220;=&#8221; del UPDATE por un &#8220;&lt;-&#8221;.</p>
<h3>Conclusiones</h3>
<p>Desde mi punto de vista, más que centrarse en cómo escribir &#8220;mejor&#8221; los sistemas SQL, deberían de centrarse en agregar dichas sentencias para que se mezclasen con el código, algo como <a href="http://es.wikipedia.org/wiki/SQLJ">SQLJ</a>, de cara a integración con los lenguajes, y de cara al mejor uso de SQL, hacer estándares del uso de las fechas (que cada sistema los usa a su forma), así como los LIMIT, funciones básicas y tipos de datos, entre otras muchas cosas, para que los SGBD fuesen más compatibles entre ellos.</p>
]]></content:encoded>
			<wfw:commentRss>http://bosqueviejo.net/2011/12/20/newsql-dos-vias-para-mejorar-sql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Selenium: probando aplicaciones web</title>
		<link>http://bosqueviejo.net/2011/12/15/selenium-probando-aplicaciones-web/</link>
		<comments>http://bosqueviejo.net/2011/12/15/selenium-probando-aplicaciones-web/#comments</comments>
		<pubDate>Thu, 15 Dec 2011 18:22:06 +0000</pubDate>
		<dc:creator>bombadil</dc:creator>
				<category><![CDATA[Desarrollo de Software]]></category>
		<category><![CDATA[desarrollo web]]></category>
		<category><![CDATA[grid]]></category>
		<category><![CDATA[junit]]></category>
		<category><![CDATA[pruebas]]></category>
		<category><![CDATA[rspec]]></category>
		<category><![CDATA[selenium]]></category>
		<category><![CDATA[webdriver]]></category>

		<guid isPermaLink="false">http://bosqueviejo.net/?p=1138</guid>
		<description><![CDATA[ Bueno, ya tocaba, después de dedicar varios apartados al desarrollo web, toca dedicarle un pequeño, aunque importante apartado a una herramienta de comprobación (tests) como es Selenium.
Esta herramienta es para poder realizar pruebas de sistema, a nivel completo y desde la propia interfaz de usuario&#8230; o incluso de forma automatizada, desde scripts de tipo JUnit, Rspec, y otros entornos de pruebas unitarias o de sistema automatizados.
La URL para descargar Selenium es: Selenium Downloads; ahí podremos descargar los entornos, entre ellos el mencionado Plugin para Firefox.
El resto del artículo irá dirigido, sobre todo, a revisar Selenium IDE, que es el que se maneja desde el propio plugin de Firefox, y es la parte más visual y rápida para adentrarse en este entorno de pruebas.
Lanzando el IDE
Una vez se tiene instalado el plugin (no lo comento, puesto que es una instalación básica y guiada, por lo que considero no debe de surgir mayor problema), pasaremos a lanzar el IDE. Este se encuentra en el menú Herramientas (o Tools), bajo la opción Selenium IDE, tal y como se ve a continuación:

Tras esto, se abre una ventana, la del IDE de Selenium, y si os fijáis en la parte derecha de la barra [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://bosqueviejo.net/wp-content/uploads/selenium-150x150.jpg" alt="" title="selenium" width="150" height="150" class="alignleft size-thumbnail wp-image-1140" /> Bueno, ya tocaba, después de dedicar varios apartados al desarrollo web, toca dedicarle un pequeño, aunque importante apartado a una herramienta de comprobación (tests) como es <a href="http://seleniumhq.org/">Selenium</a>.<span id="more-1138"></span></p>
<p>Esta herramienta es para poder realizar pruebas de sistema, a nivel completo y desde la propia interfaz de usuario&#8230; o incluso de forma automatizada, desde scripts de tipo JUnit, Rspec, y otros entornos de pruebas unitarias o de sistema automatizados.</p>
<p>La URL para descargar Selenium es: <a href="http://seleniumhq.org/download/">Selenium Downloads</a>; ahí podremos descargar los entornos, entre ellos el mencionado <a href="http://release.seleniumhq.org/selenium-ide/1.4.1/selenium-ide-1.4.1.xpi">Plugin para Firefox</a>.</p>
<p>El resto del artículo irá dirigido, sobre todo, a revisar Selenium IDE, que es el que se maneja desde el propio plugin de Firefox, y es la parte más visual y rápida para adentrarse en este entorno de pruebas.</p>
<h3>Lanzando el IDE</h3>
<p>Una vez se tiene instalado el plugin (no lo comento, puesto que es una instalación básica y guiada, por lo que considero no debe de surgir mayor problema), pasaremos a lanzar el IDE. Este se encuentra en el menú <em>Herramientas</em> (o <em>Tools</em>), bajo la opción <em>Selenium IDE</em>, tal y como se ve a continuación:</p>
<p><a href="http://bosqueviejo.net/wp-content/uploads/selenium_ide_firefox_opcion.png"><img src="http://bosqueviejo.net/wp-content/uploads/selenium_ide_firefox_opcion-300x228.png" alt="" title="selenium_ide_firefox_opcion" width="300" height="228" class="aligncenter size-medium wp-image-1148" /></a></p>
<p>Tras esto, se abre una ventana, la del IDE de Selenium, y si os fijáis en la parte derecha de la barra de herramientas, el botón de grabación, ya está presionado, con lo que, si hacéis algún clic, escribís algo en algún formulario de cualquier página que esté abierta en el navegador, se almacenará a modo de comando en el IDE de Selenium dicha opción:</p>
<p><a href="http://bosqueviejo.net/wp-content/uploads/selenium_ide_ventana.png"><img src="http://bosqueviejo.net/wp-content/uploads/selenium_ide_ventana-300x205.png" alt="" title="selenium_ide_ventana" width="300" height="205" class="aligncenter size-medium wp-image-1149" /></a></p>
<p>En el momento que volvamos a presionar el botón de grabación, o se seleccione la opción <em>Actions</em> &#8211;> <em>Record</em>, se detendrá la grabación y con las opciones de ejecución: <em>Play entire test suite</em>, o <em>Play current test case</em>; se puede reproducir lo grabado, ya sea de forma completa o solamente la línea seleccionada, respectivamente.</p>
<h3>Automatizando</h3>
<p>Está claro que, podríamos tener Chrome, Firefox, Internet Explorer, Opera, &#8230; todos los navegadores posibles para comprobar que el funcionamiento de nuestra aplicación es el que debe de ser&#8230; pero resultaría bastante tedioso el tener que lanzar cada navegador (e incluso en cada infraestructura: Windows, Linux, MacOS X, Android, &#8230;), por lo que Selenium también nos da otras herramientas.</p>
<p>En principio, desde el entorno, cada <em>test suite</em> puede ser exportada como prueba a: C#, Ruby con Test::Unit o Rspec, JUnit o Python; existiendo también otros exportadores aparte para otros lenguajes, como <a href=https://addons.mozilla.org/es-ES/firefox/addon/selenium-ide-php-formatters/"">PHP</a> u otras librerías que permiten escribir el código de tipo Selenium en lenguajes como <a href="https://github.com/charpi/erl_selenium/wiki">Erlang</a>.</p>
<h3>Webdriver</h3>
<p>Nada más entrar en la web, además del entorno IDE del que ya he comentado algo, encontramos que hay dos opciones elementos más disponibles: Remote Control y Webdriver; actualmente, Remote Control ha sido desestimado y en su lugar se emplea Webdriver, por lo que nos centraremos en Webdriver.</p>
<p>A través de la <a href="http://seleniumhq.org/docs/03_webdriver.html">documentación oficial</a>, podemos ver que WebDriver es un framework que se puede emplear en nuestros proyectos de Java, C#, Python, Ruby, PHP o Perl (que son los oficialmente soportados, también está disponible en <a href="https://github.com/charpi/erl_selenium/wiki">este enlace Erlang</a>, y hay otros desarrollados por la comunidad.</p>
<h3>Grid</h3>
<p>Grid es la parte servidora, es decir, un <em>hub</em> o <em>rejilla</em> donde se pueden agrupar servidores de este mismo tipo, de modo que las pruebas se les puedan encargar a ellos. La propia web dedicada a ello de <a href="http://selenium-grid.seleniumhq.org/how_it_works.html">Selenium Grid, How it works</a>, nos muestra como funciona la idea:</p>
<p><a href="http://bosqueviejo.net/wp-content/uploads/selenium_grid.png"><img src="http://bosqueviejo.net/wp-content/uploads/selenium_grid-300x212.png" alt="" title="selenium_grid" width="300" height="212" class="aligncenter size-medium wp-image-1154" /></a></p>
<p>Básicamente, consta de que, cada WebDriver pueda ser manejado de forma remota a través de un Grid. De este modo podemos tener varias arquitecturas como Windows, Linux, MacOS X, &#8230; y varios navegadores como Firefox, IE, Chrome, Safari, &#8230; en nuestra rejilla, y encargar las pruebas para que se realicen en general a todas las plataformas, al mismo tiempo.</p>
<h3>Conclusiones</h3>
<p>Es un buen entorno para pruebas, y realmente no resulta nada tedioso el desarrollar las pruebas directamente en el IDE, modificarlas y ajustarlas, verificarlas y exportarlas finalmente para la rejilla de pruebas.</p>
]]></content:encoded>
			<wfw:commentRss>http://bosqueviejo.net/2011/12/15/selenium-probando-aplicaciones-web/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Zotonic: CMS en Erlang</title>
		<link>http://bosqueviejo.net/2011/12/05/zotonic-cms-en-erlang/</link>
		<comments>http://bosqueviejo.net/2011/12/05/zotonic-cms-en-erlang/#comments</comments>
		<pubDate>Mon, 05 Dec 2011 00:25:59 +0000</pubDate>
		<dc:creator>bombadil</dc:creator>
				<category><![CDATA[web]]></category>
		<category><![CDATA[cms]]></category>
		<category><![CDATA[desarrollo web]]></category>
		<category><![CDATA[dtl]]></category>
		<category><![CDATA[erlang]]></category>
		<category><![CDATA[zotonic]]></category>

		<guid isPermaLink="false">http://bosqueviejo.net/?p=873</guid>
		<description><![CDATA[ En mi búsqueda de material (software sobre todo) realizado en Erlang para poder aprender mucho más sobre este lenguaje, sus virtudes, carencias y potencias, he topado con otra muy buena pieza de software: Zotonic, un CMS hecho en Erlang.
¿Qué es un CMS exactamente?
Un CMS es un sistema de administración de contenido (Content Management System), básicamente. Zotonic se centra en esto mismo, administrar el contenido de la web que está sirviendo. A diferencia de otros CMS realizados en otros lenguajes, Zotonic tiene la ventaja de ejecutarse en una máquina que permite la ejecución de software fuera de la petición.
Por ejemplo, en otros lenguajes como Ruby, Python, Perl o PHP, cuando una petición HTTP llega al sistema establece el contexto de ejecución (sesión, cookies, datos de la solicitud, etc.) y tras su respuesta, el contexto es liberado (o volcado a la memoria secundaria), con lo que, es imposible mantener una ejecución paralela que dispare el sistema.
Es más, hay herramientas como delayed::job (en Ruby) o DJJob (en PHP), precisamente para paliar un poco esto.
Sin embargo, Zotonic, tiene como ventaja el hecho de que puede disparar la ejecución de un proceso no dependiente de la solicitud que almacene su resultado en una cola [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://bosqueviejo.net/wp-content/uploads/zotonic-150x150.png" alt="" title="zotonic" width="150" height="150" class="alignleft size-thumbnail wp-image-874" /> En mi búsqueda de material (software sobre todo) realizado en Erlang para poder aprender mucho más sobre este lenguaje, sus virtudes, carencias y potencias, he topado con otra muy buena pieza de software: <a href="http://zotonic.com/">Zotonic</a>, un CMS hecho en Erlang.</p>
<h3>¿Qué es un CMS exactamente?</h3>
<p>Un CMS es un sistema de administración de contenido (Content Management System), básicamente. Zotonic se centra en esto mismo, administrar el contenido de la web que está sirviendo. A diferencia de otros CMS realizados en otros lenguajes, Zotonic tiene la ventaja de ejecutarse en una máquina que permite la ejecución de software fuera de la petición.</p>
<p>Por ejemplo, en otros lenguajes como Ruby, Python, Perl o PHP, cuando una petición HTTP llega al sistema establece el contexto de ejecución (sesión, cookies, datos de la solicitud, etc.) y tras su respuesta, el contexto es liberado (o volcado a la memoria secundaria), con lo que, es imposible mantener una ejecución paralela que dispare el sistema.</p>
<p>Es más, hay herramientas como <a href="/2011/12/01/djjob-trabajos-en-background-para-php/">delayed::job</a> (en Ruby) o <a href="/2011/12/01/djjob-trabajos-en-background-para-php/">DJJob</a> (en PHP), precisamente para paliar un poco esto.</p>
<p>Sin embargo, Zotonic, tiene como ventaja el hecho de que puede disparar la ejecución de un proceso no dependiente de la solicitud que almacene su resultado en una cola de mensajes que sea descargada por el sistema AJAX de la vista para mostrarlos en el momento que sea necesario. Esto le da a Zotonic una sensación de rapidez y paralelismo que pocos entornos web tienen hoy en día.</p>
<h3>¿Qué ofrece Zotonic?</h3>
<p>En principio, Zotonic se puede instalar en una máquina o en varias (en clúster) manteniendo una única interfaz de administración y pudiendo balancear entre todas el acceso, de forma fácil y transparente. Además, cada clúster puede administrar varios dominios:</p>
<p><img alt="Ejemplo de gestión de dominios con Zotonic." src="http://zotonic.com/image/2011/8/19/screen_shot_2010_09_07_at_22_36_42-1.png%28450x%29%28lossless%29%2885760C0FD444E8EC70DB3C1035F5EE44%29.png" title="Gestión de dominios" class="alignnone" width="450" height="272" /></p>
<p>Su interfaz es muy parecida a WordPress, y permite igualmente escribir páginas y entradas de modo que se puedan emplear como páginas del propio sitio web. Su editor se ve así:</p>
<p><img alt="Editor de contenido de Zotonic." src="http://zotonic.com/image/2009/11/16/adminedpage.png%28450x%29%28lossless%29%28B56F26782624E16F3BD5B8F236896BA8%29.png" title="Editor de contenido" class="alignnone" width="450" height="292" /></p>
<p>Como base de datos emplea PostgreSQL, y la forma de programar las plantillas es mediante el estándar de Django Template Library (DTL), lo cual facilita la creación de las vistas enormemente. Se puede revisar <a href="http://zotonic.com/documentation">la documentación</a> que, aunque el tema de las plantillas las trata poco (realmente es porque su simpleza no requiere de mayor información) es una sección de la web bastante extensa conteniendo temas como: SSL, Modelo de Datos, información sobre Erlang, PostgreSQL, conexión Ajax con Zotonic, mensajes Growl, etc.</p>
<p>Una lista bastante extensa y detallada de las características puede verse <a href="http://zotonic.com/features">aquí</a> (en inglés).</p>
<h3>Instalando Zotonic</h3>
<p>Se puede descargar en cualquier ruta de nuestro equipo, realmente, con el comando:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">git clone git://github.com/zotonic/zotonic.git</pre></div></div>

<p>Esto nos deja un entorno limpio con el que podemos hacer nuestra primera instalación. Por ejemplo, si ponemos en nuestro fichero <tt>/etc/hosts</tt> al lado de <tt>localhost</tt> la palabra <tt>miblog</tt>, podremos escribir lo siguiente:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">make
bin/zotonic -s blog miblog
./start.sh</pre></div></div>

<p>Ahora, solo tendremos que ir a un navegador, si ponemos la URL <a href="http://localhost:8000">http://localhost:8000</a>, veremos la interfaz de los dominios que tenemos en ejecución. Solo dispondremos, en estos momentos de <em>miblog</em>, por lo que, como lo hemos puesto en nuestro fichero de <tt>hosts</tt>, podemos seguir ese enlace y ver la web de nuestro sitio.</p>
<p>Si accedemos por la URL <a href="http://miblog:8000/admin/">http://miblog:8000/admin/</a>, nos preguntará por el login de acceso y contraseña. Este será, en principio (deberemos de cambiarlo): admin / admin; tras esto, se nos presentan todas las opciones disponibles de Zotonic&#8230; ¡y en castellano!</p>
<p>Todo queda bastante claro y muy fácil de manejar, a excepción de las plantillas, las cuales solo se pueden modificar a través de la edición de los ficheros en el directorio donde se haya creado el dominio. En este caso, como hemos creado el dominio <tt>miblog</tt>, la ruta será: <tt>priv/sites/miblog/templates</tt>.</p>
<h3>Conclusiones</h3>
<p>Zotonic se ha convertido en poco tiempo en un CMS con amplias características y muy usado en el mundo del web, aunque no tanto como otros que llevan más tiempo como por ejemplo Zope, Drupal o Joomla, pero poco a poco, gracias a sus características propias de alta disponibilidad, redundancia y escalabilidad, de seguro comenzará a ser cada vez más popular.</p>
]]></content:encoded>
			<wfw:commentRss>http://bosqueviejo.net/2011/12/05/zotonic-cms-en-erlang/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

