<?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>ivanmosquera.net &#187; software</title>
	<atom:link href="http://ivanmosquera.net/index.php/category/software/feed/" rel="self" type="application/rss+xml" />
	<link>http://ivanmosquera.net</link>
	<description> Just another computing weblog</description>
	<lastBuildDate>Mon, 26 Jul 2010 18:54:58 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>es</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Ikuspro es libre.</title>
		<link>http://ivanmosquera.net/index.php/2010/07/26/ikuspro-es-libre/</link>
		<comments>http://ivanmosquera.net/index.php/2010/07/26/ikuspro-es-libre/#comments</comments>
		<pubDate>Mon, 26 Jul 2010 18:52:06 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[desarrollo]]></category>
		<category><![CDATA[proyectos]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[antlr]]></category>
		<category><![CDATA[c]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[swing]]></category>

		<guid isPermaLink="false">http://ivanmosquera.net/?p=257</guid>
		<description><![CDATA[
Ikuspro es el proyecto de fín de carrera que hice en su día en el que aprendí un montón de cosas sin las cuales no se me habría ocurrido empezar el proyecto PFA.
En su día ya comenté un poco de qué iba el tema . Tras eso la cosa terminó en que el proyecto obtuvo [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><a href="http://ivanmosquera.net/wp-content/uploads/2010/07/logoIkusprogrande.png"><img class="aligncenter size-full wp-image-259" title="logoIkusprogrande" src="http://ivanmosquera.net/wp-content/uploads/2010/07/logoIkusprogrande.png" alt="" width="376" height="131" /></a></p>
<p>Ikuspro es el proyecto de fín de carrera que hice en su día en el que aprendí un montón de cosas sin las cuales no se me habría ocurrido empezar el proyecto <a href="http://phpforandroid.net">PFA</a>.</p>
<p>En su día ya comenté un poco <a href="http://ivanmosquera.net/index.php/2009/10/02/ikuspro-en-beta/">de qué iba el tema</a> . Tras eso la cosa terminó en que el proyecto obtuvo matrícula de honor.</p>
<p>A rasgos generales aprendí lo siguiente y por tanto ahora que está liberado puede que sirva a alguien para indagar en estos aspectos:</p>
<ul>
<li>Implementación de un framework MVC para Swing usando genericidad.</li>
<li>Diseño de interfaces gráficas Swing con soporte para persistencia.</li>
<li>Buenas prácticas Swing: integración con los OS más utilizados, no recarga del hilo de eventos usando workers etc&#8230;</li>
<li>Programación concurrente en Java, diseño productor-consumidor.</li>
<li>Separación de una aplicación en dos partes comunicadas mediante sincronización de hilos.</li>
<li>Implementación con <a href="http://antlr.org">ANTLR</a> de un intérprete de un subconjunto de ANSI-C que se comunica con el GUI mediante mensajes XML.</li>
<li>Comunicación entre procesos mediante un API XML.</li>
<li>Dibujado en Canvas con Java2D e integración del mismo con el GUI.</li>
</ul>
<p>Lo cierto es que fue bastante divertido. Me consta que en EUITI tienen pensado utilizarlo en laboratorios y la idea es que otros alumnos extiendan Ikuspro con nuevas funcionalidades e incluso con nuevos intérpretes.</p>
<p>Gracias a Mikel Villamañe por confiar en mí para implementar la idea.</p>
<p>A continuación el material que usé en la defensa, un pantallazo y el enlace al repositorio en mi github.</p>
<div id="__ss_4756310" style="width: 425px;"><strong><a title="Presentacion pfc" href="http://www.slideshare.net/ivmos/presentacion-pfc">Presentacion pfc</a></strong><object id="__sse4756310" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="355" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowScriptAccess" value="always" /><param name="src" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=presentacionpfc-100714170042-phpapp02&amp;stripped_title=presentacion-pfc" /><param name="name" value="__sse4756310" /><param name="allowfullscreen" value="true" /><embed id="__sse4756310" type="application/x-shockwave-flash" width="425" height="355" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=presentacionpfc-100714170042-phpapp02&amp;stripped_title=presentacion-pfc" name="__sse4756310" allowscriptaccess="always" allowfullscreen="true"></embed></object><img class="alignleft" title="Pantallazo ikuspro" src="http://ivanmosquera.net/wp-content/uploads/2009/10/ikuspro.png" alt="" width="698" height="570" /></p>
<div style="padding: 5px 0 12px;">View more <a href="http://www.slideshare.net/">presentations</a> from <a href="http://www.slideshare.net/ivmos">ivmos</a>.</div>
<div style="padding: 5px 0 12px;">Repositorio en GITHUB: ﻿﻿<a href="http://github.com/ivmos/Ikuspro">http://github.com/ivmos/Ikuspro</a></div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://ivanmosquera.net/index.php/2010/07/26/ikuspro-es-libre/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Doctest en PHP</title>
		<link>http://ivanmosquera.net/index.php/2010/03/18/doctest-en-php/</link>
		<comments>http://ivanmosquera.net/index.php/2010/03/18/doctest-en-php/#comments</comments>
		<pubDate>Thu, 18 Mar 2010 21:03:55 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[desarrollo]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[doctest]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://ivanmosquera.net/?p=137</guid>
		<description><![CDATA[Doctest es un módulo de Python que permite incluir tests en los comentarios (en los llamados docstring para ser exactos). Pues bien, existe una implementación para PHP en PEAR.

Para desarrollos rápidos (o ágiles que se dice últimamente), Doctest representa una buena forma de escribir tests debido a que utilizar otras herramientas típicas como PHPUnit o [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_146" class="wp-caption aligncenter" style="width: 310px"><img title="ykPzBWTSLc70G4FqoIoG.0" src="http://ivanmosquera.net/wp-content/uploads/2010/03/ykPzBWTSLc70G4FqoIoG.0.jpg" alt="dna" width="300" height="225" /><p class="wp-caption-text">Dana prefiere Haskell</p></div>
<p>Doctest es un módulo de Python que permite incluir tests en los comentarios (en los llamados docstring para ser exactos). Pues bien, existe una implementación para PHP en PEAR.<br />
<span id="more-137"></span></p>
<p>Para desarrollos rápidos (o ágiles que se dice últimamente), Doctest representa una buena forma de escribir tests debido a que utilizar otras herramientas típicas como PHPUnit o Simpletest requiere una metodología de primero escribir los tests y luego implementar, que está muy bien pero la curva de aprendizaje no es despreciable y tiene más sentido en proyectos de cierto recorrido. En realidad los doctest no se suelen considerar una alternativa a los tests unitarios sino una opción más centrada en la documentación y más sencilla aunque menos potente.</p>
<p>Instalamos la herramienta vía PEAR:</p>

<div class="wp-terminal">user@computer:$ pear install -f Testing_DocTest<br/></div>

<p>A continuación un ejemplo de un doctest en php.</p>
<p>El doctest se incluye entre unas etiquetas <strong>&lt;code&gt;</strong>. La salida esperada para que el test sea satisfactorio se escribe tras <strong>&#8220;// expects:&#8221;</strong>.</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">&lt;?php</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">/**</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* &lt;code&gt;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="coMULTI">&nbsp;* mostrarNumeros(3);</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;*</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* // expects:</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* //0</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* //11</span></div>
</li>
<li class="li2">
<div class="de2"><span class="coMULTI">&nbsp;* //222</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* //3333</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* &lt;/code&gt;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* &nbsp;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;**/</span></div>
</li>
<li class="li2">
<div class="de2"><span class="kw2">function</span> mostrarNumeros<span class="br0">&#40;</span><span class="re0">$num</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw1">for</span><span class="br0">&#40;</span><span class="re0">$i</span>=<span class="nu0">0</span>;<span class="re0">$i</span>&lt;=<span class="re0">$num</span>;<span class="re0">$i</span>++<span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="kw1">for</span><span class="br0">&#40;</span><span class="re0">$j</span>=<span class="nu0">0</span>;<span class="re0">$j</span>&lt;=<span class="re0">$i</span>;<span class="re0">$j</span>++<span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="re0">$i</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; <a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="st0">&quot;<span class="es0">\n</span>&quot;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p>Para ejecutar los tests :</p>

<div class="wp-terminal">user@computer:$ phpdt numeros.php.<br/></div>

<p>Dará como resultado:</p>

<div class="wp-terminal">user@computer:$ Processing /tmp/numeros.php<br/>[PASS]  function mostrarNumeros<br/><br/>Total time    : 0.0253 sec.<br/>Passed tests  : 1<br/>Skipped tests : 0<br/>Failed tests  : 0<br/></div>

<p>El doctest se suele incluir en la misma cabecera de comentario de phpdoc pero lo he omitido para que quede más claro lo necesario estrictamente para Doctest.</p>
<p>Doctest por defecto sólo considerará que el test ha sido satisfactorio si la salida del script es exactamente la misma que la salida que hemos escrito como esperada pero ¿y si queremos un comportamiento algo más flexible ?</p>
<p>Para ello podemos usar flags que alteren el comportamiento:</p>
<ul>
<li>NORMALIZE_WHITESPACE: se ignoran los espacios en blanco.</li>
<li>CASE_INSENSITIVE:  ignorar mayúsculas/minúsculas</li>
<li>SKIP: ignorar el test</li>
<li>ELLIPSIS: permitir utilizar el comodín [...]. Útil para los casos en que parte de la salida es variable</li>
</ul>
<p>A continuación un ejemplo que usa un flag de ELLIPSIS. También sirve para ver que podemos incluir varios tests en la misma cabecera.</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">&lt;?php</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">/** </span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* &lt;code&gt;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="coMULTI">&nbsp;* // Usamos ELLIPSIS porque hay una parte de la salida que no podemos predecir</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;*</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* // flags: ELLIPSIS</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* echo testString();</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* // expects:</span></div>
</li>
<li class="li2">
<div class="de2"><span class="coMULTI">&nbsp;* // Lo siguiente no se puede predecir [...].</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;*</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* &lt;/code&gt;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;*</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* &lt;code&gt;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="coMULTI">&nbsp;* // Este es el mismo test pero lo hacemos para ver que podemos dividir la salida con \</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;*</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* // flags: ELLIPSIS</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* echo testString();</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* // expects:</span></div>
</li>
<li class="li2">
<div class="de2"><span class="coMULTI">&nbsp;* // Lo siguiente \</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* // no se puede \</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* // predecir [...].</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;*</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* &lt;/code&gt;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="coMULTI">&nbsp;*</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;*/</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">function</span> testString<span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">return</span> <a href="http://www.php.net/sprintf"><span class="kw3">sprintf</span></a><span class="br0">&#40;</span><span class="st0">&#8216;Lo siguiente no se puede predecir %s&#8217;</span>, <a href="http://www.php.net/microtime"><span class="kw3">microtime</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p>Si la salida esperada para un test es demasiado grande podemos utilizar &#8220;expects-file:&#8221; en lugar de &#8220;expects :&#8221;. El ejemplo de mostrarNumeros quedaría así con expects-file:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">&lt;?php</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">/**</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* &lt;code&gt;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="coMULTI">&nbsp;* mostrarNumeros(3);</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;*</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* // expects-file: mostrarNumeros.txt</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;*</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* &lt;/code&gt;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="coMULTI">&nbsp;* </span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;**/</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">function</span> mostrarNumeros<span class="br0">&#40;</span><span class="re0">$num</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw1">for</span><span class="br0">&#40;</span><span class="re0">$i</span>=<span class="nu0">0</span>;<span class="re0">$i</span>&lt;=<span class="re0">$num</span>;<span class="re0">$i</span>++<span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="kw1">for</span><span class="br0">&#40;</span><span class="re0">$j</span>=<span class="nu0">0</span>;<span class="re0">$j</span>&lt;=<span class="re0">$i</span>;<span class="re0">$j</span>++<span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="re0">$i</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="st0">&quot;<span class="es0">\n</span>&quot;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p>En el fichero mostrarNumeros.txt incluiremos la salida en bruto, es decir, sin comentar.</p>
<p>Existe también la posibilidad de incluir todo el test en un fichero externo:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;* &lt;code&gt;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;* <span class="co1">// test-file: tests/test1.doctest</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;* &lt;/code&gt;</div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
</ol>
</div>
<p>Por último, existe la posibilidad de insertar cierto código a interpretar antes que todo lo demás. Esto es útil para establecer variables de entorno o para simular una petición HTTP.</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">/** &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* This is a file level test.</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;*</span></div>
</li>
<li class="li2">
<div class="de2"><span class="coMULTI">&nbsp;* &lt;code&gt;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* // setup:</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* // $_ENV['OSTYPE'] = &#8216;linux&#8217;;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* echo OS_TYPE;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* // expects:</span></div>
</li>
<li class="li2">
<div class="de2"><span class="coMULTI">&nbsp;* // linux</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* &lt;/code&gt;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;*/</span></div>
</li>
<li class="li1">
<div class="de1"><a href="http://www.php.net/define"><span class="kw3">define</span></a><span class="br0">&#40;</span><span class="st0">&#8216;OS_TYPE&#8217;</span>, <span class="re0">$_ENV</span><span class="br0">&#91;</span><span class="st0">&#8216;OSTYPE&#8217;</span><span class="br0">&#93;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
</ol>
</div>
<p>Como conclusión, los doctest son una pequeña joya de Python que por suerte ha sido portada también a PHP. Permite incrustar los pequeños scripts que probablemente ya haces para probar tus clases y te obliga a ver tus clases desde el punto de vista del usuario de las mismas, de modo que te ayudará a pensar en si la encapsulación es correcta, en si tiene demasiadas dependencias, en si hace demasiadas cosas etc.. Sirve como complemento a los tests unitarios pero también como iniciación a la escritura de tests.</p>
<p>Se suele decir que el código fácil de testear es propio de un software bien diseñado.</p>
<p>Enlaces:</p>
<p><a href="http://code.google.com/p/testing-doctest/">http://code.google.com/p/testing-doctest/</a><br />
<a href="http://pear.php.net/package/Testing_DocTest">http://pear.php.net/package/Testing_DocTest</a><br />
<a href="http://en.wikipedia.org/wiki/Doctest">http://en.wikipedia.org/wiki/Doctest</a><br />
Para ver más ejemplos de uso, lo mejor es ver el fichero de pruebas de Testing-DocTest, disponible en el repositorio:<br />
<a href="http://svn.php.net/repository/pear/packages/Testing_DocTest/trunk/tests/test1.php">http://svn.php.net/repository/pear/packages/Testing_DocTest/trunk/tests/test1.php</a></p>
]]></content:encoded>
			<wfw:commentRss>http://ivanmosquera.net/index.php/2010/03/18/doctest-en-php/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Las referencias en PHP: qué son y el porqué de no usarlas</title>
		<link>http://ivanmosquera.net/index.php/2010/02/13/las-referencias-en-php-que-son-y-porque-no-usarlas/</link>
		<comments>http://ivanmosquera.net/index.php/2010/02/13/las-referencias-en-php-que-son-y-porque-no-usarlas/#comments</comments>
		<pubDate>Sat, 13 Feb 2010 17:17:45 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[software]]></category>
		<category><![CDATA[c]]></category>
		<category><![CDATA[interpretes]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://ivanmosquera.net/?p=101</guid>
		<description><![CDATA[Según un estudio reciente, PHP es actualmente el tercer lenguaje de programación más popular.  Puede sorprender teniendo en cuenta los buenos comentarios que han recibido durante años lenguajes como Ruby y que se daba por seguro el retroceso de PHP.  Yo creo que esto es debido a que la gente que está detrás de [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_108" class="wp-caption aligncenter" style="width: 434px"><img class="size-full wp-image-108" title="elephant-php" src="http://ivanmosquera.net/wp-content/uploads/2010/02/elephant-php.png" alt="elefante" width="424" height="318" /><p class="wp-caption-text">elefante</p></div>
<p>Según un <a href="http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html">estudio reciente</a>, PHP es actualmente el tercer lenguaje de programación más popular.  Puede sorprender teniendo en cuenta los buenos comentarios que han recibido durante años lenguajes como Ruby y que se daba por seguro el retroceso de PHP.  Yo creo que esto es debido a que la gente que está detrás de PHP ha sabido adaptarse a las nuevas tendencias y responder a tiempo. Dos ejemplos muy significativos:</p>
<ul>
<li>PHP5</li>
<li>Zend Framework (y otros)</li>
</ul>
<p><span id="more-101"></span><br />
La comunidad &#8220;phpera&#8221; lejos de quedarse parada ante el adelantamiento por la derecha que parecía que les iba a hacer Ruby/Python/etc han mejorado el lenguaje increíblemente hasta el punto que el diseño OO de PHP tiene poco que envidiar a Java. Me imagino a los desarrolladores allá por el 2003 diciéndo <em>&#8220;Dicen que PHP4 no es enterprise-ready, que su OO da asco, vale, tienen razón.&#8221;</em>. Y de ahí salió PHP5, miras la lista de cambios entre PHP4 y PHP5, y resulta increíble que sólo les separe un número de versión.  Algo parecido se puede decir de &#8220;Zend Framework&#8221;: <em>&#8220;Ruby on Rails mola mucho, un killer app, hagamos algo parecido&#8221;</em>. Y acabó surgiendo Zend Framework, un excelente framework MVC con &#8220;total&#8221; cobertura de test unitarios y completamente modular. Además, surgieron muchos otros framework que rivalizan con ZF, el &#8220;oficial&#8221;, creando una competencia absolutamente sana. Se trata de ejemplos como CakePHP, Symfony o CodeIgniter. El último episodio donde se ha demostrado este pragmatismo de los phperos ha sido dejar Zend_Entity y pasar a adoptar el ORM supuestamente de la competencia : Doctrine. Esto contrasta con la gente de Perl que ha dedicado la mayor parte de sus esfuerzos a crear una máquina virtual, académicamente muy interesante pero en la práctica ¿Hay nuevos usuarios de Perl existiendo PHP, Python y Ruby?.</p>
<p>Vale, a estas alturas te estarás preguntando a qué viene el título de esta entrada. Pues bien, todo esto de la actitud pragmática, los grandes avances etc. está muy bien pero existe un problema en PHP si bien en mi opinión es un mal menor: se trata de mantener la compatibilidad hacia atrás. No sólo un mal menor sino además un mal necesario que permite que los desarrolladores vayan adaptándose a los nuevos cambios progresivamente. La opción contraria podría resultar crítica para muchos usuarios, hay pocos casos donde ha sido necesario ese caso extremo, me viene a la cabeza VisualBasic 6 y poco más.</p>
<p>PHP es un lenguaje que empezó con objetivos mucho más modestos, seguramente <a href="http://es.wikipedia.org/wiki/Rasmus_Lerdorf">Rasmus Lerdof</a> ni en sus sueños más húmedos se imaginó que su herramienta evolucionaría hasta soportar sitios de la escala de Facebook. La política en PHP ha sido ir corrigiendo cosas y manteniendo compatibilidad hacia atrás avisando al desarrollador de las malas prácticas mediante warnings. En esta entrada hablaré de porqué no se debe utilizar a día de hoy referencias en PHP.</p>
<h3>¿Qué son las referencias? &#8220;&amp;&#8221;</h3>
<p>Las referencias de PHP se parecen en esencia a las referencias (que no punteros) de C++. Son algo parecido a los enlaces duros de UNIX. Se han utilizado mucho en PHP debido a que en PHP4 el diseño OO era bastante distinto.  En POO se trabaja con referencias de objetos en lugar de con los datos directamente debido a que la idea es mandar mensajes a los objetos y que ellos mismos sean los encargados de modificar su propio estado, y para eso basta la referencia del objeto para mandarle mensajes, difícilmente vas a necesitar acceder al objeto en sí mismo.<br />
En PHP4, la implementación OO hacía que fuera necesario utilizar el operador referencia para hacer POO ya que de lo contrario estabas copiando objetos.  También hay que tener en cuenta que hasta hace relativamente poco no se programaba OO en PHP por lo que se asumía que al igual que en C, si quieres trabajar con una estructura de datos muy grande, lo suyo es pasarlo por referencia y así evitar la copia. Esto me lleva a explicar un hecho poco conocido de PHP.</p>
<h3>copy-on-write</h3>
<p>La práctica de usar paso por referencia por motivos de optimización es equivocada <em>actualmente </em>debido a que PHP hace copy-on-write. Esto consiste en que PHP cuando se pasa por valor (casi siempre), no hace una copia de la variable desde el principio sino que trabajará en realidad con la referencia y hará una copia sólo en el momento en que detecte que vas a intentar modificar. Es decir, tú como programador feliz, estás en el ámbito de la función y con un parámetro por valor, y parece que estás trabajando desde el principio con una copia con lo cual si la estructura de datos es muy grande te puedes ver tentado a pasar por referencia pero es un error debido a que PHP internamente no hace la copia hasta que sea realmente necesario. Vale, pero puedes estar pensando: ¡ pero es que precisamente mi función va a modificar esa estructura y mucho así que se va a hacer esa costosa copia! Bien, el problema subyacente es que no se está pensando suficientemente a lo OO sino más bien proceduralmente.  En PHP5 el modelo de objetos está rediseñado de modo que los objetos se trabajan con referencias como en Java, por lo que deja de ser necesario utilizar el operador referencia para hacer POO. Esto supone que el operador &#8216;=&#8217; en la práctica es como si copiara sólo para los tipos primitivos mientras que para los objetos copia la referencia. Esta suele ser la típica explicación pero en realidad es errónea, lo cierto es que esta misma mala explicación también se suele dar en Java como simplificación. Lo que ocurre en realidad es que en PHP5 no trabajas con el objeto directamente, trabajas con su referencia, de modo que cuando pasas el objeto por valor, como mucho estarás provocando (copy-on-write) la copia de la referencia pero no del objeto. Si quieres una copia física del objeto lo que necesitarás es clonar el objeto (clone). Puedes utilizar el operador de referencia con objetos también pero resulta innecesario.</p>
<p>Vamos a ver más en profundidad cómo trabaja el intérprete de PHP las variables.</p>

<div class="wp-terminal">user@computer:$ apt-get source php5-cli.<br/></div>

<p>La estructura de datos que almacena una variable en PHP se llama &#8220;zval_struct&#8221; (zval entre amigos).  Un &#8220;zval&#8221; tiene los siguientes campos:</p>
<ul>
<li>tipo (el tipo de la variable)</li>
<li>valor (el valor de la variable)</li>
<li>is_ref (flag que indica si la variable es una referencia &amp;)</li>
<li>refcount (contador del número de símbolos que apuntan a este zval)</li>
</ul>
<p>La estructura está definida en zend.h:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw4">struct</span> _zval_struct <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">/* Variable information */</span></div>
</li>
<li class="li1">
<div class="de1">zvalue_value value; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="coMULTI">/* value */</span></div>
</li>
<li class="li1">
<div class="de1">zend_uint refcount;</div>
</li>
<li class="li2">
<div class="de2">zend_uchar type; &nbsp; &nbsp; &nbsp; &nbsp;<span class="coMULTI">/* active type */</span></div>
</li>
<li class="li1">
<div class="de1">zend_uchar is_ref;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span>;</div>
</li>
</ol>
</div>
<p>Un zvalue_value puede ser muchas cosas. Ahí reside la magia del tipado de php. Tenemos en la misma estructura de datos las distintas posibilidades, tanto tipos primitivos como objetos, en <a href="http://ivanmosquera.net/index.php/2009/10/02/ikuspro-en-beta/">Ikuspro</a> realicé una implementación similar sólo que la genericidad de Java facilita mucho las cosas. Los objetos no se almacenan en esta estructura sino que únicamente se guarda el puntero (en PHP-5).</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw4">typedef</span> <span class="kw4">union</span> _zvalue_value <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">long</span> lval; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="coMULTI">/* long value */</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">double</span> dval; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="coMULTI">/* double value */</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">struct</span> <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">char</span> *val;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">int</span> len;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span> str;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; HashTable *ht; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="coMULTI">/* hash table value */</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; zend_object_value obj;</div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span> zvalue_value;</div>
</li>
</ol>
</div>
<p>En PHP4 probablemente el diseño era distinto de manera que en el valor iba directamente el objeto de manera que era necesario usar continuamente el operador referencia para hacer programación orientada a objetos correctamente.</p>
<p>Un zend_object_value es lo siguiente (zend_types.h):</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw4">typedef</span> <span class="kw4">struct</span> _zend_object_value <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; zend_object_handle handle;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; zend_object_handlers *handlers;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span> zend_object_value;</div>
</li>
</ol>
</div>
<p>El handle es un ID único de entre ese tipo concreto de objetos (no global). El tipo del objeto y su funcionalidad está en esta otra estructura que es encuentra en una tabla. Desde zend_object_value vemos que se apunta con handlers en la entrada adecuada.</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw4">typedef</span> <span class="kw4">struct</span> _zend_object_handlers <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; zend_object_add_ref_t &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;add_ref;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; zend_object_del_ref_t &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;del_ref;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; zend_object_delete_obj_t &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; delete_obj;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; zend_object_clone_obj_t &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;clone_obj;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; zend_object_read_property_t &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;read_property;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; zend_object_write_property_ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;write_property;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; zend_object_get_property_ptr_t &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; get_property_ptr;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; zend_object_get_property_zval_ptr_t &nbsp; &nbsp; &nbsp;get_property_zval_ptr;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; zend_object_get_t &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;get;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; zend_object_set_t &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;set;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; zend_object_has_property_t &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; has_property;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; zend_object_unset_property_t &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; unset_property;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; zend_object_get_properties_t &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; get_properties;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; zend_object_get_method_t &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; get_method;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; zend_object_call_method_t &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;call_method;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; zend_object_get_constructor_t &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;get_constructor;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; zend_object_get_class_entry_t &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;get_class_entry;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; zend_object_get_class_name_t &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; get_class_name;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; zend_object_compare_t &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;compare_objects;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span> zend_object_handlers;</div>
</li>
</ol>
</div>
<p>Los símbolos (nombres de variables) que apuntan a un zval se guardan en una tabla de símbolos. Normalmente solemos hablar de variables locales, variables globales, ámbitos de variables&#8230; Bien, de lo que se trata es que tenemos una tabla de símbolos por ámbito y en PHP el ámbito está unido a las funciones o métodos. En C por ejemplo, es diferente y los ámbitos van unidos a los bloques directamente de modo que tenemos tablas de símbolos por bloques.  Por ejemplo en PHP tenemos:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="re0">$a</span> = <span class="st0">&quot;hola/&quot;</span>;</div>
</li>
<li class="li1">
<div class="de1"><a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="re0">$a</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$a</span> = <span class="st0">&quot;jaja/&quot;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="re0">$a</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="re0">$a</span>;</div>
</li>
</ol>
</div>
<p>El resultado será &#8220;hola/jaja/jaja/&#8221;</p>
<p>En C:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="co2">#include </span></div>
</li>
<li class="li1">
<div class="de1">main<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw4">char</span> *a = <span class="st0">&quot;hola/&quot;</span>;</div>
</li>
<li class="li2">
<div class="de2"><a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span class="kw3">printf</span></a><span class="br0">&#40;</span><span class="st0">&quot;%s&quot;</span>,a<span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw4">char</span> *a = <span class="st0">&quot;jaja/&quot;</span>;</div>
</li>
<li class="li1">
<div class="de1"><a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span class="kw3">printf</span></a><span class="br0">&#40;</span><span class="st0">&quot;%s&quot;</span>,a<span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span class="kw3">printf</span></a><span class="br0">&#40;</span><span class="st0">&quot;%s&quot;</span>,a<span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p>El resultado es &#8220;hola/jaja/hola/&#8221;.</p>
<p>Si te parece un detalle de importancia echa un vistazo a este código:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">&lt;?</span></div>
</li>
<li class="li1">
<div class="de1"><span class="re0">$a</span> = <span class="st0">&quot;Hola&quot;</span>;</div>
</li>
<li class="li1">
<div class="de1"><a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="re0">$a</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$a</span> == <span class="st0">&quot;Hola&quot;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$b</span> = <span class="st0">&quot;Adios&quot;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="re0">$b</span>;</div>
</li>
</ol>
</div>
<p>Este código en C no tiene sentido.</p>
<p>Podemos ver los zval con xdebug_debug_zval</p>

<div class="wp-terminal">user@computer:$ apt-get install php5-xdebug<br/></div>

<p>Veamos un ejemplo:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">&lt;?</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="re0">$a</span> = <span class="st0">&quot;Hola&quot;</span>;</div>
</li>
<li class="li2">
<div class="de2">xdebug_debug_zval<span class="br0">&#40;</span><span class="st0">&#8216;a&#8217;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="re0">$b</span> = <span class="nu0">2</span>;</div>
</li>
<li class="li1">
<div class="de1">xdebug_debug_zval<span class="br0">&#40;</span><span class="st0">&#8216;b&#8217;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="re0">$obj</span> = <span class="kw2">new</span> stdClass<span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="re0">$obj</span>-&gt;<span class="me1">atrib1</span> = <span class="st0">&quot;foo&quot;</span>;</div>
</li>
<li class="li2">
<div class="de2"><span class="re0">$obj</span>-&gt;<span class="me1">atrib2</span> = <span class="st0">&quot;bar&quot;</span>;</div>
</li>
<li class="li1">
<div class="de1">xdebug_debug_zval<span class="br0">&#40;</span><span class="st0">&#8216;obj&#8217;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="re0">$obj2</span> = <span class="re0">$obj</span>;</div>
</li>
<li class="li1">
<div class="de1">xdebug_debug_zval<span class="br0">&#40;</span><span class="st0">&#8216;obj2&#8242;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="re0">$obj3</span> = &amp;<span class="re0">$obj</span>;</div>
</li>
<li class="li2">
<div class="de2">xdebug_debug_zval<span class="br0">&#40;</span><span class="st0">&#8216;obj3&#8242;</span><span class="br0">&#41;</span>;</div>
</li>
</ol>
</div>
<p>El resultado es:</p>
<pre>a: (refcount=1, is_ref=0)='Hola'
b: (refcount=1, is_ref=0)=2
obj: (refcount=1, is_ref=0)=class stdClass { public $atrib1 = (refcount=1, is_ref=0)='foo'; public $atrib2 = (refcount=1, is_ref=0)='bar' }
obj2: (refcount=2, is_ref=0)=class stdClass { public $atrib1 = (refcount=1, is_ref=0)='foo'; public $atrib2 = (refcount=1, is_ref=0)='bar' }
obj3: (refcount=2, is_ref=1)=class stdClass { public $atrib1 = (refcount=1, is_ref=0)='foo'; public $atrib2 = (refcount=1, is_ref=0)='bar' }</pre>
<p>Como puedes ver el único con is_ref=1 es la variable referencia. Un zval se elmina cuando refcount pasa a ser cero y esas referencias van desaparenciendo a medida que se van resolviendo los ámbitos. Es decir, si hemos creado un zval dentro de una función (localmente) tendremos en principio símbolos pertenecientes a la tabla de símbolos de esa función. Al terminar la función ese zval pasará a tener 0 de refcount y por tanto se podrá liberar. Se suele decir que la función unset() de php destruye objetos pero creo que eso no es cierto.  Un ejempo:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="re0">$orig</span> = <span class="nu0">4</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="re0">$a</span> = <span class="re0">$orig</span>;</div>
</li>
<li class="li1">
<div class="de1">xdebug_debug_zval<span class="br0">&#40;</span><span class="st0">&#8216;a&#8217;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2"><span class="re0">$b</span> = &amp;amp;<span class="re0">$a</span>;</div>
</li>
<li class="li1">
<div class="de1">xdebug_debug_zval<span class="br0">&#40;</span><span class="st0">&#8216;a&#8217;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><a href="http://www.php.net/unset"><span class="kw3">unset</span></a><span class="br0">&#40;</span><span class="re0">$a</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">xdebug_debug_zval<span class="br0">&#40;</span><span class="st0">&#8216;b&#8217;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="re0">$b</span> .<span class="st0">&quot;<span class="es0">\n</span>&quot;</span>;</div>
</li>
<li class="li2">
<div class="de2"><span class="re0">$obj</span> = <span class="kw2">new</span> stdClass;</div>
</li>
<li class="li1">
<div class="de1"><span class="re0">$obj</span>-&gt;<span class="me1">foo</span> = <span class="st0">&quot;bar&quot;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="re0">$obj2</span> = &amp;amp;<span class="re0">$obj</span>;</div>
</li>
<li class="li1">
<div class="de1">xdebug_debug_zval<span class="br0">&#40;</span><span class="st0">&#8216;obj&#8217;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><a href="http://www.php.net/unset"><span class="kw3">unset</span></a><span class="br0">&#40;</span><span class="re0">$obj</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">xdebug_debug_zval<span class="br0">&#40;</span><span class="st0">&#8216;obj2&#8242;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="re0">$obj2</span>-&gt;<span class="me1">foo</span> .<span class="st0">&quot;<span class="es0">\n</span>&quot;</span>;</div>
</li>
</ol>
</div>
<p>El resultado es:</p>
<pre>a: (refcount=2, is_ref=0)=4
a: (refcount=2, is_ref=1)=4
b: (refcount=1, is_ref=0)=4
4
obj: (refcount=2, is_ref=1)=class stdClass { public $foo = (refcount=1, is_ref=0)='bar' }
obj2: (refcount=1, is_ref=0)=class stdClass { public $foo = (refcount=1, is_ref=0)='bar' }
bar</pre>
<p>Como podemos ver lo que hace unset en realidad es disminuir el número del contador.  Por último un ejemplo en el que pasamos la referencia de un objeto con lo cual hacemos que deje de apuntar a un objeto y pase a ser un string (tipo primitivo):</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">&lt;?</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">function</span> lafuncion<span class="br0">&#40;</span>stdClass &amp;<span class="re0">$obj</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$obj</span> = <span class="st0">&quot;Sorpresa&quot;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="re0">$a</span> = <span class="kw2">new</span> stdClass<span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="re0">$a</span>-&gt;<span class="me1">foo</span> = <span class="st0">&quot;bar&quot;</span>;</div>
</li>
<li class="li2">
<div class="de2">xdebug_debug_zval<span class="br0">&#40;</span><span class="st0">&#8216;a&#8217;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">lafuncion<span class="br0">&#40;</span>&amp;<span class="re0">$a</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">xdebug_debug_zval<span class="br0">&#40;</span><span class="st0">&#8216;a&#8217;</span><span class="br0">&#41;</span>;</div>
</li>
</ol>
</div>
<p>El resultado es:</p>
<pre>
a: (refcount=1, is_ref=0)=class stdClass { public $foo = (refcount=1, is_ref=0)='bar' }
a: (refcount=1, is_ref=0)='Sorpresa'</pre>
<p>Como conclusión: no merece la pena trabajar con el operador referencia si estamos haciendo POO, lo único que vamos a conseguir es liar el código y provocar bugs, los punteros y referencias no están al nivel de abstracción que solemos manejar en nuestra vida diaria mientras que los objetos, atributos y métodos sí. Desgraciadamente existe mucho código &#8220;legacy&#8221; que hace uso intensivo de pasos por referencia, incluyendo algunas funciones de ordenación de PHP. Una opción para convertir esas funciones es sustituir los parámetros por referencia por un objeto stdClass que los encapsule pasado por valor.</p>
<p>Links:</p>
<p>Para escribir este post me he basado en el código citado del intérprete de PHP y en los siguientes enlaces. Si crees que he cometido algún error pon un comentario, estaré encantado en aprender:</p>
<p>http://php.net/manual/en/features.gc.refcounting-basics.php</p>
<p>http://schlueters.de/blog/archives/125-Do-not-use-PHP-references.html</p>
<p>http://blog.libssh2.org/index.php?/archives/51-Youre-being-lied-to..html</pre>
]]></content:encoded>
			<wfw:commentRss>http://ivanmosquera.net/index.php/2010/02/13/las-referencias-en-php-que-son-y-porque-no-usarlas/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Desarrollo para Plataforma Flash en Linux: Minibuilder</title>
		<link>http://ivanmosquera.net/index.php/2009/12/26/desarrollo-para-plataforma-flash-en-linux-minibuilder/</link>
		<comments>http://ivanmosquera.net/index.php/2009/12/26/desarrollo-para-plataforma-flash-en-linux-minibuilder/#comments</comments>
		<pubDate>Sat, 26 Dec 2009 16:53:18 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[software]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[flex]]></category>
		<category><![CDATA[linux]]></category>

		<guid isPermaLink="false">http://ivanmosquera.net/?p=75</guid>
		<description><![CDATA[Desde hace un tiempo Adobe ya no desarrolla Flash/Flex Builder para Linux. Una alternativa libre prometedora que he encontrado es Minibuilder. Se trata de un editor que utiliza la tecnología Adobe Air.

flash platform
Veamos a continuación los pasos necesarios para desarrollar en Linux para plataforma Flash con esta herramienta:

1. Instalamos Adobe AIR : (Fuente:  http://www.sizlopedia.com/2008/04/06/how-to-install-adobe-air-on-ubuntu/ )

user@computer:$ [...]]]></description>
			<content:encoded><![CDATA[<p>Desde hace un tiempo Adobe ya no desarrolla Flash/Flex Builder para Linux. Una alternativa libre prometedora que he encontrado es Minibuilder. Se trata de un editor que utiliza la tecnología Adobe Air.<br />
<img src="http://ivanmosquera.net/wp-content/uploads/2009/12/flash-platform-signature.jpg" alt="flash platform" /></p>
<p>flash platform</p>
<p>Veamos a continuación los pasos necesarios para desarrollar en Linux para plataforma Flash con esta herramienta:<br />
<span id="more-75"></span></p>
<p>1. <strong>Instalamos Adobe AIR</strong> : (Fuente:  <a href="http://www.sizlopedia.com/2008/04/06/how-to-install-adobe-air-on-ubuntu/">http://www.sizlopedia.com/2008/04/06/how-to-install-adobe-air-on-ubuntu/</a> )</p>

<div class="wp-terminal">user@computer:$ wget http://airdownload.adobe.com/air/lin/download/1.5/AdobeAIRInstaller.bin<br/></div>


<div class="wp-terminal">user@computer:$ chmod +x AdobeAIRInstaller.bin<br/></div>


<div class="wp-terminal">user@computer:$ ./AdobeAIRInstaller.bin<br/></div>

<p>Si aún habiendo instalado las dependencias tiene problemas para hacer funcionar Adobe AIR con 64 bits, con un error como el siguiente: <em>Error loading the runtime (libnss3.so: wrong ELF class: ELFCLASS64)</em><br />
Los pasos que le pueden faltar son:<br />
<code><br />
$ cd /usr/lib32/<br />
$sudo ln -s /emul/ia32-linux/usr/lib/libnss3.so .<br />
$sudo ln -s /emul/ia32-linux/usr/lib/libssl3.so .<br />
$sudo ln -s /emul/ia32-linux/usr/lib/libsmime3.so .<br />
$sudo ln -s /emul/ia32-linux/usr/lib/libnspr4.so .<br />
$sudo ln -s /emul/ia32-linux/usr/lib/libnssutil3.so.1d .<br />
$sudo ln -s /emul/ia32-linux/usr/lib/libplc4.so.0d .<br />
$sudo ln -s /emul/ia32-linux/usr/lib/libplds4.so .<br />
$sudo ln -s /emul/ia32-linux/usr/lib/libplds4.so.0d libplds4.so.0d<br />
</code></p>
<p>2. <strong>Instalar Java</strong></p>

<div class="wp-terminal">user@computer:$ apt-get install sun-java-jre<br/></div>

<p>3. <strong>Instalar Flex</strong> 3.5 ( URL : <a href="http://opensource.adobe.com/wiki/display/flexsdk/Download+Flex+3">http://opensource.adobe.com/wiki/display/flexsdk/Download+Flex+3</a> )</p>
<p>Descomprimir en algún sitio</p>
<p>4. <strong>Descargar minibuilder</strong>: (URL :  <a href="http://minibuilder.googlecode.com/files/AirMiniBuilder-1.0-alpha-3.air">http://minibuilder.googlecode.com/files/AirMiniBuilder-1.0-alpha-3.air</a> )</p>

<div class="wp-terminal">user@computer:$ Adobe\ AIR\ Application\ Installer /$RUTA_ABSOLUTA/AirMiniBuilder-1.0-alpha-3.air<br/></div>

<p>5. Tras la instalación de minibuilder, éste <strong>se iniciará</strong>. Veremos que nos pide <strong>ejecutar</strong> un tal <strong>MBCompiler</strong>, la ruta al script figurará en la última línea de la ventana.<br />
En mi caso : <em>/opt/AirMiniBuilder/share/MBCompiler/start</em><br />
Supongo que Minibuilder no hace ese trabajo por nosotros debido a algún tipo de limitación del sandbox de Air.</p>
<p>Teniendo ejecutado MBCompiler podemos hacer click en &#8220;Check again&#8221; y desaparecerá la advertencia.<br />
También tenemos que especificar la ruta  a flex en el cuadro &#8220;SDK Path&#8221;.</p>
<p>Y ya está. Ya podemos empezar a utilizar de Minibuilder. Empezaremos con un pequeño proyecto para el Flash Player.</p>
<p>Utilizamos la pestaña &#8220;<em>Create New Project</em>&#8220;:</p>
<div id="attachment_78" class="wp-caption aligncenter" style="width: 597px"><img class="size-full wp-image-78" title="Minibuilder" src="http://ivanmosquera.net/wp-content/uploads/2009/12/1.png" alt="Minibuilder" width="587" height="567" /><p class="wp-caption-text">Minibuilder</p></div>
<p>Elegimos:<br />
Project target : &#8220;<em>Flash Player AS3</em>&#8221;</p>
<p>Vemos que soporta dos frameworks : Flex y <a href="http://aswing.org">AsWing</a>. Nosotros por ahora sólo usaremos Flex.<br />
Activamos &#8220;<em>Add (some) Flex support</em>&#8221;</p>
<p>Como project name lo que queramos, en mi caso &#8220;hola mundo&#8221;.</p>
<p>Ese texto inicial que veremos se trata de MXML, un lenguaje de marcado que facilita el uso del framework Flex.</p>
<div id="attachment_79" class="wp-caption aligncenter" style="width: 778px"><img class="size-full wp-image-79" title="Editor Minibuilder" src="http://ivanmosquera.net/wp-content/uploads/2009/12/2.png" alt="Editor Minibuilder" width="768" height="515" /><p class="wp-caption-text">Editor Minibuilder</p></div>
<p>Hacemos click en &#8220;Compile and Quickrun&#8221;. Veremos que tarda su tiempo en compilar el SWF, años luz de la rapidez de MTASC o Haxe.<br />
No veremos nada cuando no debería ser así. Sospecho que puede ser porque mi distribución Linux utiliza SWFDEC por defecto en lugar del player de flash Adobe. El swf lo podemos encontrar en la carpeta bin-debug, con lo cual podremos ejecutarlo manualmente.</p>
<p>Veremos que aparecen unos botones (&#8220;AAA&#8221;,&#8221;BBB&#8221;&#8230;) es debido a que se está utilizando la clase &#8220;Application.as&#8221; predefinida por Minibuilder que incluye esos botones en tabs.</p>
<p>Ahora ya es cuestión de aprender Flex. Como pistas para alguien que venga de MTASC decir que las clases Flash que se solían utilizar anteriormente, en la documentación están en el API de Flash Player.</p>
<p>Así que para jugar por un lado tenemos los controles del framework Flex: <a href="http://livedocs.adobe.com/flex/3/html/help.html?content=controls_01.html">http://livedocs.adobe.com/flex/3/html/help.html?content=controls_01.html</a> y por otro lado tenemos el API de Flash Player, el cual ya nos resultará familiar al haberlo utilizado con <a href="http://mtasc.org">MTASC</a> , <a href="http://haxe.org">Haxe</a> o Flash Studio:</p>
<p><a href="http://livedocs.adobe.com/flex/3/html/help.html?content=Part3_Flash_Player_APIs_1.html">http://livedocs.adobe.com/flex/3/html/help.html?content=Part3_Flash_Player_APIs_1.html</a></p>
<p>Podemos utilizar ambas cosas sin problemas. En el siguiente ejemplo, se utiliza NetStream y Netconnection en lugar del control VideoDisplay de Flex, pero eso no quita para que los botones a utilizar puedan ser controles Flex:</p>
<p><a href="http://blog.flexexamples.com/2008/03/01/displaying-a-video-in-flex-using-the-netconnection-netstream-and-video-classes/">http://blog.flexexamples.com/2008/03/01/displaying-a-video-in-flex-using-the-netconnection-netstream-and-video-classes/</a></p>
<p>Vemos que en ese ejemplo el código Actionscript se encuentra incrustado en el MXML. No tiene porqué ser así y de hecho yo no creo que sea una buena práctica. El ejemplo de Minibuilder utiliza una clase independiente para el código (Application.as). De todos modos, ya hablaremos en otro post sobre buenas prácticas, patrones y otras librerías.</p>
<p>Entonces como conclusión. ¿Qué ofrece Minibuilder en cuanto a facilitar el desarrollo para plataforma Flash?</p>
<p>Resaltado y autocompletado AS3, así como compilación amigable de SWF incluyendo gestión de los namespaces.</p>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 2319px; width: 1px; height: 1px;">
<pre class="code">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;!-- http://blog.flexexamples.com/2008/03/01/displaying-a-video-in-flex-using-the-netconnection-netstream-and-video-classes/ --&gt;
&lt;mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
        layout="vertical"
        verticalAlign="middle"
        backgroundColor="white"
        creationComplete="init();"&gt;

    &lt;mx:Script&gt;
        &lt;![CDATA[
            import mx.utils.ObjectUtil;

            private var nc:NetConnection;
            private var ns:NetStream;
            private var video:Video;
            private var meta:Object;

            private function init():void {
                var nsClient:Object = {};
                nsClient.onMetaData = ns_onMetaData;
                nsClient.onCuePoint = ns_onCuePoint;

                nc = new NetConnection();
                nc.connect(null);

                ns = new NetStream(nc);
                ns.play("http://www.helpexamples.com/flash/video/cuepoints.flv");
                ns.client = nsClient;

                video = new Video();
                video.attachNetStream(ns);
                uic.addChild(video);
            }

            private function ns_onMetaData(item:Object):void {
                trace("meta");
                meta = item;
                // Resize Video object to same size as meta data.
                video.width = item.width;
                video.height = item.height;
                // Resize UIComponent to same size as Video object.
                uic.width = video.width;
                uic.height = video.height;
                panel.title = "framerate: " + item.framerate;
                panel.visible = true;
                trace(ObjectUtil.toString(item));
            }

            private function ns_onCuePoint(item:Object):void {
                trace("cue");
            }
        ]]&gt;
    &lt;/mx:Script&gt;

    &lt;mx:Panel id="panel" visible="false"&gt;
        &lt;mx:UIComponent id="uic" /&gt;
        &lt;mx:ControlBar&gt;
            &lt;mx:Button label="Play/Pause" click="ns.togglePause();" /&gt;
            &lt;mx:Button label="Rewind" click="ns.seek(0); ns.pause();" /&gt;
        &lt;/mx:ControlBar&gt;
    &lt;/mx:Panel&gt;

&lt;/mx:Application&gt;</pre>
</div>
]]></content:encoded>
			<wfw:commentRss>http://ivanmosquera.net/index.php/2009/12/26/desarrollo-para-plataforma-flash-en-linux-minibuilder/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Probando Haxe</title>
		<link>http://ivanmosquera.net/index.php/2009/11/02/probando-haxe/</link>
		<comments>http://ivanmosquera.net/index.php/2009/11/02/probando-haxe/#comments</comments>
		<pubDate>Mon, 02 Nov 2009 20:07:05 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[software]]></category>
		<category><![CDATA[cpp]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[haxe]]></category>
		<category><![CDATA[linux]]></category>

		<guid isPermaLink="false">http://ivanmosquera.net/?p=20</guid>
		<description><![CDATA[Haxe es el sucesor de MTASC, pero no se limita a tener como objetivo la tecnología flash sino que también genera Javascript, PHP y otros. Además, se acompaña de una máquina virtual, Neko, que le sirve para la ejecución en servidor. Yo personalmente creo que es un proyecto que está intentando abarcar demasiado pero hay [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://haxe.org">Haxe</a> es el sucesor de <a href="http://mtasc.org">MTASC</a>, pero no se limita a tener como objetivo la tecnología flash sino que también genera Javascript, PHP y otros. Además, se acompaña de una máquina virtual, Neko, que le sirve para la ejecución en servidor. Yo personalmente creo que es un proyecto que está intentando abarcar demasiado pero hay varios puntos que me han animado a probarlo:</p>
<ul>
<li>Las nuevas funcionalidades y rendimiento mejorado de AVM2 (máquina virtual en las últimas versiones de Flash).</li>
<li>El lenguaje de Haxe es mejor que ActionScript.</li>
<li>La posibilidad de portar aplicaciones flash a plataforma nativa fácilmente. Esto se está utilizando por ejemplo para aplicaciones iPhone.</li>
</ul>
<p><img src="http://ivanmosquera.net/wp-content/uploads/haxe.gif" alt="" /><br />
A continuación los pasos necesarios para la instalación y un par de ejemplos de Haxe contra Flash y CPP usando el mismo código:</p>
<p><span id="more-20"></span></p>
<p>La instalación en Debian (testing) es sencilla:</p>

<div class="wp-terminal">user@computer:$ apt-get install haxe<br/>apt-get install neko<br/></div>

<p>Si no está disponible en tu distribución o se trata de versiones no actualizadas, una buena opción puede ser utilizar el instalador estándar de haxe para Linux y los siguientes pasos seguirán siendo los mismos.</p>
<p>Instalado Haxe y Neko, hacemos:</p>

<div class="wp-terminal">user@computer:$ mkdir -p /usr/lib/haxe/lib/<br/>haxelib setup<br/></div>

<p>Instalaremos hxcpp para hacer alguna prueba.</p>

<div class="wp-terminal">user@computer:$ haxelib install hxcpp<br/></div>

<p>Instalamos el fichero de sintaxis de Haxe para Vim:</p>

<div class="wp-terminal">user@computer:$ wget http://tech.motion-twin.com/zip/haxe.vim &amp;&amp; cp haxe.vim /usr/share/vim/vim72/syntax/<br/></div>

<p>Añadimos lo siguiente en nuestro .vimrc<br />
<code>" Haxe<br />
au BufNewFile,BufRead *.hx                setf haxe</code><br />
Ya estamos listos para probar un &#8220;hola mundo&#8221;:</p>
<p><code lang="actionscript"><br />
class Hola {<br />
static function main() {<br />
trace("Hola mundo");<br />
}<br />
</code></p>
<p>Compilamos a  swf con</p>

<div class="wp-terminal">user@computer:$ haxe -swf9 salida.swf -main Hola<br/></div>

<p>Podemos abrir el swf directamente con el navegador y deberíamos ver el trace. La función trace de Haxe se dibuja directamente, algo muy práctico la verdad.</p>
<p>Ahora vamos a compilar el mismo fichero a código nativo. Veremos que lo que hace Hxcpp es traducir nuestro fichero fuente en Haxe a código C++. Si falla es probable que sea porque nos falta algún paquete C++, podemos servirnos de apt-file para localizarlos.</p>
<p>Vemos que él mismo se encarga de invocar al compilador C++ con los parámetros adecuados así que nosotros obtenemos el resultado final simplemente con la línea de haxe.</p>
<p>El resultado estará en la carpeta &#8220;salida&#8221;. Ahí encontraremos nuestro ejecutable ELF (&#8220;Hola&#8221;) y las carpetas &#8220;include&#8221;, &#8220;obj&#8221; y &#8220;src&#8221;.</p>

<div class="wp-terminal">user@computer:$ ./Hola<br/>Hola.hx:3: Hola mundo<br/></div>

<p>Echamos un vistazo a las librerías de las que depende nuestro ejecutable:</p>

<div class="wp-terminal">user@computer:$ ldd Hola<br/>linux-gate.so.1 =&gt;  (0xb80d6000)<br/>libpthread.so.0 =&gt; /lib/i686/cmov/libpthread.so.0 (0xb80ad000)<br/>libdl.so.2 =&gt; /lib/i686/cmov/libdl.so.2 (0xb80a9000)<br/>libstdc++.so.6 =&gt; /usr/lib/libstdc++.so.6 (0xb7fb6000)<br/>libm.so.6 =&gt; /lib/i686/cmov/libm.so.6 (0xb7f90000)<br/>libgcc_s.so.1 =&gt; /lib/libgcc_s.so.1 (0xb7f65000)<br/>libc.so.6 =&gt; /lib/i686/cmov/libc.so.6 (0xb7e06000)<br/>/lib/ld-linux.so.2 (0xb80d7000)<br/></div>

<p>Vemos que no depende de nada extraño, es decir, neko o similar.</p>
<p>Muy bien pero esto se queda un poco pobre tratándose de un simple trace así que vamos a probar algo más. Para ello necesitaremos instalar una librería más. Con Haxe podremos programar contra el API de Flash y generar CPP gracias al wrapper de SDL que implementa NME.</p>

<div class="wp-terminal">user@computer:$ haxelib install neash<br/></div>

<p>Verás que él mismo baja de internet los ficheros necesarios y configura la instalación por lo que al parecer haxelib viene a ser algo parecido a CPAN o PEAR.</p>
<p>El código fuente del nuevo fichero que vamos a probar es el siguiente:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw3">import</span> flash.<span class="me1">events</span>.<span class="me1">MouseEvent</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw3">import</span> flash.<span class="me1">events</span>.<span class="me1">Event</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw3">import</span> flash.<span class="me1">display</span>.<span class="kw3">MovieClip</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li2">
<div class="de2"><span class="kw2">class</span> Prueba <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp;<span class="kw3">private</span> <span class="kw2">var</span> mc: flash.<span class="me1">display</span>.<span class="kw3">MovieClip</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp;<span class="kw3">private</span> <span class="kw2">var</span> square: flash.<span class="me1">display</span>.<span class="kw3">MovieClip</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp;<span class="kw2">function</span> <span class="kw2">new</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mc = flash.<span class="me1">Lib</span>.<span class="me1">current</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;drawSquare<span class="br0">&#40;</span>0xAFAFF0,<span class="nu0">50</span>,<span class="nu0">50</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mc.<span class="kw3">stage</span>.<span class="me1">addEventListener</span><span class="br0">&#40;</span>MouseEvent.<span class="me1">MOUSE_DOWN</span>, <span class="kw3">onPress</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp;<span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp;<span class="kw3">private</span> <span class="kw2">function</span> drawSquare<span class="br0">&#40;</span>pColor:<span class="kw3">Int</span>,pStartX:<span class="kw3">Int</span>,pStartY:<span class="kw3">Int</span><span class="br0">&#41;</span>:<span class="kw3">Void</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;square = <span class="kw2">new</span> <span class="kw3">MovieClip</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;square.<span class="me1">graphics</span>.<span class="kw3">beginFill</span> <span class="br0">&#40;</span>pColor<span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;square.<span class="me1">graphics</span>.<span class="kw3">moveTo</span> <span class="br0">&#40;</span>pStartX,pStartY<span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;square.<span class="me1">graphics</span>.<span class="kw3">lineTo</span> <span class="br0">&#40;</span><span class="nu0">100</span>,<span class="nu0">50</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;square.<span class="me1">graphics</span>.<span class="kw3">lineTo</span> <span class="br0">&#40;</span><span class="nu0">100</span>,<span class="nu0">100</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;square.<span class="me1">graphics</span>.<span class="kw3">lineTo</span> <span class="br0">&#40;</span><span class="nu0">50</span>,<span class="nu0">100</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;square.<span class="me1">graphics</span>.<span class="kw3">endFill</span> <span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mc.<span class="me1">addChild</span><span class="br0">&#40;</span>square<span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp;<span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp;<span class="kw3">static</span> <span class="kw2">function</span> main<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co2">#if cpp</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; neash.<span class="me1">Lib</span>.<span class="me1">mOpenGL</span> = <span class="kw2">true</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; neash.<span class="me1">Lib</span>.<span class="me1">Init</span><span class="br0">&#40;</span><span class="st0">&quot;Prueba&quot;</span>,<span class="nu0">320</span>,<span class="nu0">200</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; neash.<span class="me1">Lib</span>.<span class="me1">SetBackgroundColour</span><span class="br0">&#40;</span>0xFFFFFF<span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co2">#end</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> prueba:Prueba = <span class="kw2">new</span> Prueba<span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co2">#if cpp</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; neash.<span class="me1">Lib</span>.<span class="me1">ShowFPS</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; neash.<span class="me1">Lib</span>.<span class="me1">Run</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co2">#end</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp;<span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp;<span class="kw2">function</span> <span class="kw3">onPress</span><span class="br0">&#40;</span>event:MouseEvent<span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">trace</span><span class="br0">&#40;</span><span class="st0">&quot;Yepa!!&quot;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; square.<span class="me1">x</span> += <span class="nu0">4</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp;<span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p>Al igual que antes, primero probamos con flash:</p>

<div class="wp-terminal">user@computer:$ haxe  -swf prueba.swf -swf-version 10 -main Prueba<br/><br/><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="557" height="557" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="src" value="http://ivanmosquera.net/wp-content/uploads/2009/11/prueba.swf" /><embed type="application/x-shockwave-flash" width="557" height="557" src="http://ivanmosquera.net/wp-content/uploads/2009/11/prueba.swf"></embed></object><br/></div>

<p>Y ahora a código nativo:</p>

<div class="wp-terminal">user@computer:$ haxe -cpp salida_prueba --remap flash:neash -lib neash -main Prueba -cp /usr/lib/haxe/lib/neash/1,0,1/neash/<br/></div>

<p>Vemos que en este caso ha sido necesario directiva de precompilación y decirle a haxe que sustituya las ocurrencias de flash por neash.</p>
<p>Por ahora la sensación que me da es que Haxe como plataforma open source para Flash ya es estable, pudiendo sustituir a MTASC perfectamente pero en cuanto a CPP la cosa puede estar demasiado verde como para cosas serias.</p>
]]></content:encoded>
			<wfw:commentRss>http://ivanmosquera.net/index.php/2009/11/02/probando-haxe/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ikuspro en beta</title>
		<link>http://ivanmosquera.net/index.php/2009/10/02/ikuspro-en-beta/</link>
		<comments>http://ivanmosquera.net/index.php/2009/10/02/ikuspro-en-beta/#comments</comments>
		<pubDate>Fri, 02 Oct 2009 17:57:07 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[proyectos]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[ikuspro java antlr]]></category>

		<guid isPermaLink="false">http://ivanmosquera.net/?p=7</guid>
		<description><![CDATA[Ikuspro es el nombre del software que he desarrollado para mi PFC.  Se trata de un simulador gráfico de programas.
La idea del proyecto es de mi director de PFC que es profesor del departamento de LSI de EUITI-BI e imparte clases de “Fundamentos de Informática” por lo que pensó que una herramienta de este [...]]]></description>
			<content:encoded><![CDATA[<p>Ikuspro es el nombre del software que he desarrollado para mi PFC.  Se trata de un simulador gráfico de programas.<br />
La idea del proyecto es de mi director de PFC que es profesor del departamento de LSI de EUITI-BI e imparte clases de “Fundamentos de Informática” por lo que pensó que una herramienta de este tipo podría ser útil para quien se enfrenta por primera vez a la metodología de programación.<br />
Con Ikuspro la ejecución de los programas se hace visual y gracias a ello se alivia un poco la sensación de abstracción que suele inspirar la programación. Es algo parecido a lo que ocurre con <a class="externlink" title="Go to http://es.wikipedia.org/wiki/Logo_%28inform%C3%A1tica%29" href="http://es.wikipedia.org/wiki/Logo_%28inform%C3%A1tica%29">Logo</a>, aquella tortuga que hacíamos mover por toda la pantalla sin darnos cuenta de que estábamos programando por primera vez.</p>
<p>De todos modos lo mejor es que ponga un ejemplo. Este código por ejemplo:</p>
<p><img class="aligncenter size-full wp-image-7" title="editor" src="http://ivanmosquera.net/wp-content/uploads/2009/10/editor.jpg" alt="editor" width="509" height="400" /></p>
<p>Como puedes ver este código es C.</p>
<p>Ikuspro en la versión actual incluye un intérprete de C que he desarrollado con el objetivo de que puedan funcionar los ejercicios utilizados en la asignatura de “Fundamentos de Informática”. Este ejemplo es muy sencillo para no recargar esta entrada pero el intérprete de C de Ikuspro es bastante más avanzado soportando funciones, arrays, condicionales, bucles e incluso punteros parcialmente.</p>
<p>Hablo del intérprete como algo independiente de Ikuspro ya que una parte interesante del proyecto es que Ikuspro está pensado en realidad como un simulador gráfico que se puede extender en el futuro con nuevos intérpretes para otros lenguajes sin mayor dificultad. Siendo un poco más técnicos, lo que hace Ikuspro es ejecutar el intérprete adecuado para el tipo de programa en un hilo independiente comunicándose ambos como productor-consumidor vía mensajes XML.</p>
<p>A continuación la simulación gráfica que genera Ikuspro al término de este programa y digo al término ya que con Ikuspro se va viendo la ejecución del programa línea a línea, en realidad como si de un debugger se tratara sólo que mucho más fácil y sobre todo didáctico para el usuario objetivo.</p>
<p><img class="aligncenter size-full wp-image-9" title="simulacion" src="http://ivanmosquera.net/wp-content/uploads/2009/10/simulacion.jpg" alt="simulacion" width="366" height="550" /></p>
<p>Además, Ikuspro también genera comentarios didácticos acerca de lo que va sucediéndo línea a línea y muestra la salida estándar del intérprete, que es fiel a lo esperable.<br />
A continuación un pantallazo de Ikuspro donde puedes ver las diferentes partes y hacerte una idea del funcionamiento del mismo:</p>
<p><img class="alignnone size-full wp-image-6" title="ikuspro" src="http://ivanmosquera.net/wp-content/uploads/2009/10/ikuspro.png" alt="ikuspro" width="526" height="427" /></p>
<p style="text-align: center;"><a href="http://ivanmosquera.net/wp-content/uploads/2009/10/ikuspro.png">Enlace a imágen ampliada</a></p>
<p>Ikuspro está desarrollado enteramente en Java. El intérprete C que incorpora se ha desarrollado con <a class="externlink" title="Go to http://antlr.org" href="http://antlr.org/">ANTLR</a>.</p>
<p>Por último, el título de esta entrada es “Ikuspro en beta” porque esta semana he terminado de realizar mis pruebas así que está listo para realizar pruebas con usuarios. Ikuspro actualmente está numerado como 0.9 en lugar de 1.0 para dar cabida a alguna idea interesante y factible que pueda surgir en las pruebas con usuarios.</p>
<p>Si has llegado a leer hasta aquí y te gustaría probar Ikuspro:</p>
<p><a class="externlink" title="Go to http://ktulur.net/pro/ikuspro" href="http://ktulur.net/pro/ikuspro/index.html">Página web provisional del proyecto Ikuspro</a></p>
]]></content:encoded>
			<wfw:commentRss>http://ivanmosquera.net/index.php/2009/10/02/ikuspro-en-beta/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Editores UML gratuitos</title>
		<link>http://ivanmosquera.net/index.php/2009/04/22/editores-uml-gratuitos/</link>
		<comments>http://ivanmosquera.net/index.php/2009/04/22/editores-uml-gratuitos/#comments</comments>
		<pubDate>Wed, 22 Apr 2009 19:42:32 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[software]]></category>
		<category><![CDATA[UML free]]></category>

		<guid isPermaLink="false">http://ivanmosquera.net/?p=3</guid>
		<description><![CDATA[Aquí mantendré una lista comparativa de software gratuito para edición de diagramas UML. El prerrequisito para que el software sea incluido en la lista es la gratuidad excluyéndose licencias temporales y similares.

diagramas_uml

 

Además, daré especial importancia a los siguientes aspectos de modo que problemas relacionados con los mismos supondrán directamente una desventaja pero su cumplimiento [...]]]></description>
			<content:encoded><![CDATA[<p>Aquí mantendré una lista comparativa de software gratuito para edición de diagramas UML. El prerrequisito para que el software sea incluido en la lista es la gratuidad excluyéndose licencias temporales y similares.</p>
<div class="wp-caption aligncenter" style="width: 650px;"><img title="UML_Diagrams" src="http://upload.wikimedia.org/wikipedia/commons/8/81/UML_Diagrams.jpg" alt="diagramas_uml" width="512" height="384" /></p>
<p class="wp-caption-text">diagramas_uml</p>
</div>
<p><span id="more-15"> </span></p>
<p><span id="more-3"></span></p>
<p>Además, daré especial importancia a los siguientes aspectos de modo que problemas relacionados con los mismos supondrán directamente una desventaja pero su cumplimiento no se mencionará como ventaja:</p>
<ul>
<li>UML 2</li>
<li>Soporte como mínimo de los siguientes lenguajes de programación: Java, C#, Python.</li>
<li>Utilizable en cualquier tipo de proyecto, sea comercial o no por ejemplo.</li>
<li>Ingeniería inversa (capacidad de generar diagramas o modelos desde código fuente)</li>
<li>Binario disponible para Linux y Windows, de forma nativa o por ser multiplataforma.</li>
</ul>
<h3>Visual Paradigm Community Edition</h3>
<p><a href="http://www.visual-paradigm.com/product/vpuml/communityedition.jsp">http://www.visual-paradigm.com/product/vpuml/communityedition.jsp</a></p>
<p>Ventajas:</p>
<ul>
<li>Buena integración con IDEs.</li>
<li>Incluye localización en castellano.</li>
<li>Muy personalizable.</li>
<li>Soporta muchos más lenguajes de programación.</li>
</ul>
<p>Desventajas:</p>
<ul>
<li>No permite su uso en proyectos comerciales e incluye marca de agua recordando este hecho.</li>
<li>Muestra muchas otras funcionalidades no disponibles como gancho para las versiones de pago.</li>
</ul>
<h3>ArgoUML</h3>
<p><a href="http://argouml.tigris.org/">http://argouml.tigris.org/</a></p>
<p>Ventajas:</p>
<ul>
<li>Es software libre.</li>
<li>Soporta PHP.</li>
</ul>
<p>Desventajas:</p>
<ul>
<li>UML 1.4</li>
</ul>
<h3>StarUML</h3>
<p><a href="http://argouml.tigris.org/">http://staruml.sourceforge.net/en/</a></p>
<p>Ventajas:</p>
<ul>
<li>Es software libre.</li>
<li>Muy personalizable.</li>
</ul>
<p>Desventajas:</p>
<ul>
<li>Problemas con la ingeniería inversa si hay caracteres locales, tildes por ejemplo.</li>
<li>Sin versión para Linux aunque puede funcionar con Wine. www.tadicho.com/?p=154</li>
</ul>
<h3>UMLET</h3>
<p><a href="http://www.umlet.com">http://www.umlet.com</a></p>
<p>Ventajas:</p>
<ul>
<li>Es software libre.</li>
<li>Buena integración con Eclipse.</li>
<li>Permite edición sólo con texto (sin usar el ratón).</li>
</ul>
<p>Desventajas:</p>
<ul>
<li>Sin ingeniería inversa.</li>
</ul>
<h3>JUDE COMMUNITY</h3>
<p><a href="http://jude.change-vision.com/jude-web/product/community.html">http://jude.change-vision.com/jude-web/product/community.html</a></p>
<p>Ventajas:</p>
<ul>
<li>Buena personalización.</li>
</ul>
<p>Desventajas:</p>
<ul>
<li>Soporte incompleto UML 2</li>
</ul>
<h3>BOUML</h3>
<p><a href="http://bouml.free.fr/">http://bouml.free.fr/</a></p>
<p>Ventajas:</p>
<ul>
<li>Muy rápido.</li>
<li>Soporte PHP.</li>
<li>Es software libre.</li>
<li>Ingeniería inversa por encima de la media.</li>
</ul>
<p>Desventajas:</p>
<ul>
<li>Muy poco intuitivo, curva aprendizaje grande.</li>
</ul>
<h3>Umbrello</h3>
<p><a href="http://uml.sourceforge.net/">http://uml.sourceforge.net/</a></p>
<p>Ventajas:</p>
<ul>
<li>Es software libre.</li>
</ul>
<p>Desventajas:</p>
<ul>
<li>Sin binario actualizado para Windows.</li>
</ul>
<h3>www.websequencediagrams.com</h3>
<p><a href="http://www.websequencediagrams.com">http://www.websequencediagrams.com</a></p>
<p>Ventajas:</p>
<ul>
<li>Muy ágil y cómodo, diferentes estilos de presentación.</li>
<li>Herramienta web, no requiere instalación.</li>
<li>Permite edición sólo con texto (sin usar el ratón).</li>
</ul>
<p>Desventajas:</p>
<ul>
<li>Herramienta web, necesitas estar conectado.</li>
<li>Sólo soporta diagramas de secuencia.</li>
</ul>
<h3>yuml.me</h3>
<p><a href="http://yuml.me/">http://yuml.me/</a></p>
<p>Ventajas:</p>
<ul>
<li>Herramienta web, no requiere instalación.</li>
<li>Muy ágil y cómodo.</li>
<li>Permite edición sólo con texto (sin usar el ratón).</li>
</ul>
<p>Desventajas:</p>
<ul>
<li>Herramienta web, necesitas estar conectado.</li>
<li>Ciertos problemas con caracteres locales.</li>
<li>No soporta diagramas de secuencia.</li>
</ul>
<p>Nota: Websequencediagrams.com y yuml.me juntos sí que conforman una solución completa de UML. Lo que ocurre es que son proyectos distintos, diferentes autores, y por tanto no tiene sentido analizarlos en conjunto.</p>
]]></content:encoded>
			<wfw:commentRss>http://ivanmosquera.net/index.php/2009/04/22/editores-uml-gratuitos/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
