<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2spanishfull.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Tordek</title>
	
	<link>http://blog.tordek.com.ar</link>
	<description>Linux, Programación, Diseño Web, y todo lo bueno de la Internet.</description>
	<lastBuildDate>Mon, 17 Sep 2012 08:47:51 +0000</lastBuildDate>
	<language>es-AR</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/Tordek" /><feedburner:info uri="tordek" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><image><link>http://blog.tordek.com.ar</link><url>http://tordek.com.ar/tordek.png</url><title>Tordek</title></image><feedburner:emailServiceId>Tordek</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><item>
		<title>PDO, ó, por qué todos los tutoriales de PHP llevan a las malas prácticas</title>
		<link>http://feedproxy.google.com/~r/Tordek/~3/na_cghMlt7k/</link>
		<comments>http://blog.tordek.com.ar/2010/11/pdo-o-por-que-todos-los-tutoriales-de-php-llevan-a-las-malas-practicas/#comments</comments>
		<pubDate>Thu, 18 Nov 2010 23:36:28 +0000</pubDate>
		<dc:creator>Tordek</dc:creator>
				<category><![CDATA[Programación]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[pdo]]></category>
		<category><![CDATA[pgsql]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://blog.tordek.com.ar/?p=322</guid>
		<description><![CDATA[PDO es una panacea. Es mágico. Hace todo lo que queremos, y más. Y lo hace más fácil, rápido, y seguro que lo que podemos hacerlo nosotros. O, bueno, no tanto. Pero es mucho mejor que manejar conexiones con pg_ o mysql_ o mysqli_ o cualquiera sea el prefijo particular del motor de base de [...]]]></description>
				<content:encoded><![CDATA[<p>PDO es una panacea. Es mágico. Hace todo lo que queremos, y más. Y lo hace más fácil, rápido, y seguro que lo que podemos hacerlo nosotros.</p>
<p>O, bueno, no tanto. Pero es mucho mejor que manejar conexiones con <code>pg_</code> o <code>mysql_</code> o <code>mysqli_</code> o cualquiera sea el prefijo particular del motor de base de datos que usemos.</p>
<p><a href="http://www.php.net/pdo">PDO</a> (PHP Data Objects) es una capa de abstracción sobre las llamadas a bajo nivel de consultas a DB. Se compone de 3 clases: PDO, que se encarga de las conexiones, PDOStatement, que envuelve consultas y resultados y PDOException, su tipo nativo de excepciones.</p>
<p>En su forma más básica, usar PDO puede ser exactamente igual que usar cualquiera de los otros drivers a mano: Simplemente iniciamos una conexion, ejecutamos la consulta y usamos los resultados.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$connection</span> <span style="color: #339933;">=</span> <span style="color: #990000;">pg_connect</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;host=example.com user=tordek password=42&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #990000;">pg_query</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$connection</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;SELECT * FROM foo&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$row</span> <span style="color: #339933;">=</span> <span style="color: #990000;">pg_fetch_row</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$result</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$row</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'bar'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">' '</span><span style="color: #339933;">,</span> <span style="color: #000088;">$row</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'baz'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p><em>cf</em>.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$connection</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> PDO<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;pgsql:host=example.com user=tordek password=42&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> PDO<span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;SELECT * FROM foo&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$result</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$row</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$row</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'bar'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">' '</span><span style="color: #339933;">,</span> <span style="color: #000088;">$row</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'baz'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>La conexión se crea pasando un &#8220;DSN&#8221;,<em> Data Source Name</em> ó Nombre de Fuente de Datos, que no es más que un string que indica el tipo de base de datos, su dirección y otros detalles necesarios para su conexión.</p>
<p><code>query</code> deja de ser una función más, para transformarse en un método de clase, al igual que con mysqli; no hace mucha diferencia, pero limpia un poco el namespace global.</p>
<p><code>$result</code> es un poco más interesante. Si bien sigue siendo un objeto opaco, ahora es un generador: ya no es necesario llamar a una función para extraer un valor y avanzarlo; eso lo hace <code>foreach</code>, dejando más en claro que estamos haciendo algo con cada elemento.</p>
<p>En fin, cambios principalmente estéticos.</p>
<p>Ahora, cuando empezamos a ver características un poco más avanzadas, empieza a volverse más interesante.</p>
<p>Lo primero es que (omitiendo incompatibilidades entre las consultas SQL) lo único que tenemos que hacer para cambiar el tipo de base de datos que usamos (si antes usábamos una DB Access para pruebas, y lo subimos a un server con MySQL, por ejemplo) es cambiar el <em>string</em> de conexión.</p>
<p>Lo segundo es que agrega soporte global para cosas como consultas preparadas, aunque el motor no las soporte nativamente. Un beneficio de esto es que repetir una misma consulta con diferentes valores se vuelve más simple, y a veces hasta más rápido (si el motor lo soporta, no es necesario mandar (y procesar) la consulta entera, sino sólo los parámetros nuevos):</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$query</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$conexion</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;INSERT INTO foo (bar) VALUES (:bar)&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$array</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$val</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">bindValue</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;:bar&quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$val</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Al hacer <code>prepare</code>, creamos una consulta que tiene un &#8220;hueco&#8221; para un valor (en este caso, llamado <code>:bar</code>). <code>bindValue</code> hace que el valor de ese hueco sea igual al de <code>$val</code>. Luego, en el <code>foreach</code> se cambia la variable y se ejecuta una consulta en cada ciclo, insertando en la tabla una fila para cada valor de <code>$array</code>.</p>
<p>El otro beneficio, mucho más importante, es que, al usar consultas preparadas, no es necesario preocuparse por inyecciones SQL. El driver se encarga de sanitizar cada parámetro de la manera que vea prudente (mysql_real_escape_string vs pg_escape_string vs SQLite3::escapeString). Por default, asume que todos los parámetros son strings, pero podemos especificar que se trata de otro tipo, de ser necesario.</p>
<p>El beneficio más grande, en mi opinión, es la consistencia: Da igual que el usemos PostgreSQL, MySQL, SQLite o incluso Access; sólo necesitamos conocer <em>una</em> forma de realizar consultas que sirve para casi todos los casos que se nos ocurra. Y todo esto es mencionando tan solo lo más básico que PDO tiene para ofrecer.</p>
<p>Ahora&#8230; ¿cuál es la contra?</p>
<p>PDO es una abstracción. Todas las abtracciones tienen dos problemas: el primero es que, por cada capa de abstracción, es necesario recorrer más camino para llegar al «fondo» (en este caso, las llamadas a las DB). Eso implica una pérdida de velocidad, sí, pero una que es casi irrelevante. El otro problema es que las característicás más &#8220;<em>hardcore</em>&#8221; de las DB se pueden perder, como <code>mysql_server_info</code>. Ambos problemas son casi completamente ignorables, excepto en los casos más extremos.</p>
<p>PDO es parte de PHP desde la versión 5.1. No hay excusa para no usarlo.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Tordek?a=na_cghMlt7k:gF_ispJlfhY:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Tordek?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Tordek?a=na_cghMlt7k:gF_ispJlfhY:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/Tordek?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Tordek?a=na_cghMlt7k:gF_ispJlfhY:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/Tordek?i=na_cghMlt7k:gF_ispJlfhY:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://blog.tordek.com.ar/2010/11/pdo-o-por-que-todos-los-tutoriales-de-php-llevan-a-las-malas-practicas/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.tordek.com.ar/2010/11/pdo-o-por-que-todos-los-tutoriales-de-php-llevan-a-las-malas-practicas/</feedburner:origLink></item>
		<item>
		<title>Eso no es POO. Es CACA.</title>
		<link>http://feedproxy.google.com/~r/Tordek/~3/hitB4Cz8L8A/</link>
		<comments>http://blog.tordek.com.ar/2009/10/eso-no-es-poo-es-caca/#comments</comments>
		<pubDate>Fri, 16 Oct 2009 22:51:40 +0000</pubDate>
		<dc:creator>Tordek</dc:creator>
				<category><![CDATA[Programación]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[OO]]></category>
		<category><![CDATA[orientación a objetos]]></category>
		<category><![CDATA[poo]]></category>
		<category><![CDATA[Programación orientada a objetos]]></category>

		<guid isPermaLink="false">http://blog.tordek.com.ar/2009/10/eso-no-es-poo-es-caca/</guid>
		<description><![CDATA[Aparentemente, programar usando un diseño orientado a objetos significa hacer un dibujito UML, decirle a nuestro IDE que cree un montón de atributos (obviamente todos privados; no querríamos romper el encapsulamiento), y luego generar todos los accesores y mutadores, no vaya a ser que después no podamos cambiar algo. Al final, terminamos con una clase [...]]]></description>
				<content:encoded><![CDATA[<p>Aparentemente, programar usando un diseño orientado a objetos significa hacer un dibujito UML, decirle a nuestro IDE que cree un montón de atributos (obviamente todos privados; no querríamos romper el encapsulamiento), y luego generar todos los accesores y mutadores, no vaya a ser que después no podamos cambiar algo.</p>
<p>Al final, terminamos con una clase Persona, a la que cualquiera le puede decir que se cambie el nombre, el DNI, y cualquier cosa que le corresponda.</p>
<p>Eh, no.</p>
<p>Preguntémosle a Alan Kay, a Barbara Liskov, a Bjarne Stroustrup&#8230; y tantos otros, y creo que lo primero que nos van a decir es &#8220;Eso no es una clase; es una estructura&#8221;, y &#8220;¿No se suponía que ibas a encapsular los atributos?&#8221;&#8230;</p>
<p>A una interfaz siempre se puede agregar más métodos, sin romper nada, pero si borramos el más inútil de nuestros métodos, siempre va a haber alguien que estaba usándolo. Por eso el primer paso a un buen diseño es «<strong>No agregar accesores hasta que se demuestre útil. No agregar mutadores hasta que sea totalmente necesario.</strong>».</p>
<p>Ah, y, de paso: Las <em>Properties</em><sup class='footnote'><a href='#fn-304-1' id='fnref-304-1' onclick='return fdfootnote_show(304)'>1</a></sup> no son más que accesores y mutadores disfrazados.</p>
<h3><i>Tell, Don&#8217;t Ask</i></h3>
<p>Traduciendo libremente de <a href="http://www.ccs.neu.edu/research/demeter/related-work/pragmatic-programmer/jan_03_enbug.pdf">The Art of Enbugging</a>, &#8220;Supongamos que el diariero viene a la puerta a cobrar lo que le debés de la semana. Te das vuelta, y él saca tu billetera de tu bolsillo, toma dos dólares, y te la devuelve. En vez de eso, el diariero debería pedirle al cliente que le pague los $2,00.&#8221;.</p>
<p>Para ponerlo en código (porque sí):</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="cpp" style="font-family:monospace;">Diariero<span style="color: #008080;">::</span><span style="color: #007788;">Cobrar</span><span style="color: #008000;">&#40;</span>Cliente<span style="color: #000040;">*</span> cliente, <span style="color: #0000ff;">int</span> cantidad<span style="color: #008000;">&#41;</span> <span style="color: #0000ff;">throw</span> <span style="color: #008000;">&#40;</span>EsUnRataException<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    Billetera<span style="color: #000040;">*</span> billetera <span style="color: #000080;">=</span> Cliente<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>getBilletera<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span>billetera<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>contenido<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #000080;">&lt;</span> cantidad<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        cliente<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>setBilletera<span style="color: #008000;">&#40;</span>billetera<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        <span style="color: #0000ff;">throw</span> EsUnRataException<span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
    billetera.<span style="color: #0000dd;">remove</span><span style="color: #008000;">&#40;</span>cantidad<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    Cliente.<span style="color: #007788;">setBilletera</span><span style="color: #008000;">&#40;</span>billetera<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>vs.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="cpp" style="font-family:monospace;">Diariero<span style="color: #008080;">::</span><span style="color: #007788;">Cobrar</span><span style="color: #008000;">&#40;</span>Cliente<span style="color: #000040;">&amp;</span> cliente, <span style="color: #0000ff;">int</span> cantidad<span style="color: #008000;">&#41;</span> <span style="color: #0000ff;">throw</span> <span style="color: #008000;">&#40;</span>DineroInsuficienteException<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    Cliente.<span style="color: #007788;">cobrar</span><span style="color: #008000;">&#40;</span>cantidad<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>Y el primero probablemente necesite revisar si el cliente tiene una billetera, ver si usa monedero o nada, cosa que nos obliga a agregar varios if donde podríamos haber usado polimorfismo.</p>
<h3>¿Y mis porotos?</h3>
<p>Los <em>Beans</em> (Objetos con accesores y mutadores para cada atributo, más un constructor sin parámetros) parecen ser la necesidad básica del programador de Java moderno (?). Todo tiene que ser un bean, si vamos a usar <a href="http://www.hibernate.org">Hibernate</a>, JPA o &lt;inserte sigla de moda&gt;.</p>
<p>Para muchos, eso es todo lo que se necesita para decidir que todos los mutadores deben ser públicos: ¡Si no no puedo usar Hibernate!&#8230; pero no. Hibernate pide que existan, pero no necesariamente que sean públicos: si son protegidos, es más que suficiente.</p>
<h3>Of course&#8230;</h3>
<p>Por supuesto, hay lugares donde los accesores son útiles, y mucho mejores que un constructor repleto de parámetros. Para los que no me crean, revisen la API de Windows:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="cpp" style="font-family:monospace;">m_hWindow <span style="color: #000080;">=</span>
    <span style="color: #008080;">::</span><span style="color: #007788;">CreateWindow</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;AppWindow&quot;</span>,          <span style="color: #ff0000; font-style: italic;">/* class name */</span>
                   m_pszTitle,           <span style="color: #ff0000; font-style: italic;">/* title to window */</span>
                   WS_OVERLAPPEDWINDOW,  <span style="color: #ff0000; font-style: italic;">/* style */</span>
                   CW_USEDEFAULT,        <span style="color: #ff0000; font-style: italic;">/* start pos x */</span>
                   CW_USEDEFAULT,        <span style="color: #ff0000; font-style: italic;">/* start pos y */</span>
                   m_nWidth,             <span style="color: #ff0000; font-style: italic;">/* width */</span>
                   m_nHeight,            <span style="color: #ff0000; font-style: italic;">/* height */</span>
                   <span style="color: #0000ff;">NULL</span>,                 <span style="color: #ff0000; font-style: italic;">/* parent HWND */</span>
                   <span style="color: #0000ff;">NULL</span>,                 <span style="color: #ff0000; font-style: italic;">/* menu HANDLE */</span>
                   hInstance,            <span style="color: #ff0000; font-style: italic;">/* */</span>
                   <span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>                <span style="color: #ff0000; font-style: italic;">/* creatstruct param */</span></pre></td></tr></table></div>

<p>Todos los <code>NULL</code> y <code>CW_USEDEFAULT</code> podrían haber sido valores por defecto. <cite>The Little Manual of API Design</cite>, de los creadores de QT, ofrece una alternativa, más similar a la que se usa en QT4:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="cpp" style="font-family:monospace;">window <span style="color: #000080;">=</span> <span style="color: #0000dd;">new</span> Window<span style="color: #008080;">;</span>
window<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>setClassName<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;AppWindow&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
window<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>setWindowTitle<span style="color: #008000;">&#40;</span>winTitle<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
window<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>setStyle<span style="color: #008000;">&#40;</span>Window<span style="color: #008080;">::</span><span style="color: #007788;">Overlapped</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
window<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>setSize<span style="color: #008000;">&#40;</span>width, height<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
window<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>setModuleHandle<span style="color: #008000;">&#40;</span>moduleHandle<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>Una opción indiscutiblemente mejor: Ocupa menos líneas, y no involucra memorizar el orden arbitrario de los 11 parámetros del constructor anterior. Podría parecer más larga de escribir, por todos los &#8220;window&#8221; que se repiten, pero podría reducirse aún más si la API<sup class='footnote'><a href='#fn-304-2' id='fnref-304-2' onclick='return fdfootnote_show(304)'>2</a></sup> soporta un estilo más <a href="http://en.wikipedia.org/wiki/Fluent_interface">fluido</a> (cada método retorna <code>this</code>), permitiendo algo como:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="cpp" style="font-family:monospace;">window <span style="color: #000080;">=</span> <span style="color: #0000dd;">new</span> Window<span style="color: #008080;">;</span>
window<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>setClassName<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;AppWindow&quot;</span><span style="color: #008000;">&#41;</span>
      <span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>setWindowTitle<span style="color: #008000;">&#40;</span>winTitle<span style="color: #008000;">&#41;</span>
      <span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>setStyle<span style="color: #008000;">&#40;</span>Window<span style="color: #008080;">::</span><span style="color: #007788;">Overlapped</span><span style="color: #008000;">&#41;</span>
      <span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>setSize<span style="color: #008000;">&#40;</span>width, height<span style="color: #008000;">&#41;</span>
      <span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>setModuleHandle<span style="color: #008000;">&#40;</span>moduleHandle<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>&#8230;de lo cual más de un smalltalker se reirá.</p>
<h3>Colecciones</h3>
<p>Un lugar donde se nota obviamente la bestialidad de los accesores y mutadores es cuando hay colecciones de por medio. Primero, porque exponer una colección elimina cualquier posibilidad de concurrencia: Si dos métodos quieren modificarla, el único resultado va a ser un bug.</p>
<p>Además, se expone el tipo interno de la colección, removiendo otra de las características de la orientación a objetos: la implementación tiene libertad sobre la interfaz.</p>
<p>Acá hay que aplicar uno de los refactoreos de Fowler (y esto ya debería llegar a volverse regla natural): <a href="http://www.refactoring.com/catalog/encapsulateCollection.html">Encapsulate collection</a>. Es simple: Primero, matamos el setter. No cumple ninguna función útil. Nos aseguramos, además, de que en el constructor se cree la colección. Después procedemos a liberar la responsabilidad de la colección: El getter retorna una copia inmutable. Y, finalmente, agregamos métodos que se encarguen de agregar o remover objetos de la colección.</p>
<p><em lang="fr-FR">Voilá</em>: Nuestro objeto está un paso más cerca de ser, bueno, orientado a objetos.</p>
<h3>Ley Anti-mutantes</h3>
<p>Le debo una a William Stryker.</p>
<p>Una vez, discutiendo sobre OO con un amigo, le dije que todo debería ser inmutable, excepto en raros casos. Me dijo «¡Pero el chiste de la Orientación a Objetos es la mutabilidad del estado!».</p>
<p>Bueno, sí y no.</p>
<p>Más vale no.</p>
<p>Siguiendo con las colecciones, algunas son más críticas que otras. Si sólo tenemos un array de objetos, no importa que cualquiera de sus valores cambie. Ahora, si tenemos una <em>hashtable</em>, más vale que el hash nunca cambie, o van a pasar cosas muy malas.</p>
<p>Cualquier valor del que dependa <code>hashCode</code> (en Java) <strong>tiene</strong> que ser inmutable. Si no, estaríamos violando el contrato, y sufriremos mil y un bugs sutiles.</p>
<h3>¡Bueno, basta, prometo no hacerlo más, pero dejá de escribir!</h3>
<p>No todos los atributos de un objeto merecen un getter: Por cada getter exponemos implementación.</p>
<p>Muy pocos atributos merecen un setter: Si tiene que cambiar, que lo haga el objeto sólo.</p>
<p>Las interfaces deben revelar lo menos posible: No digas <code>HashSet</code> donde podés decir <code>Collection</code>.</p>
<p>Encapsulá tus colecciones.</p>
<p>El primer paso a una buena orientación a objetos es la paranoia.</p>
<div class='footnotes' id='footnotes-304'>
<div class='footnotedivider'></div>
<ol>
<li id='fn-304-1'>que admito amar <span class='footnotereverse'><a href='#fnref-304-1'>&#8617;</a></span></li>
<li id='fn-304-2'>O el lenguaje, con un constructo <code>with</code> o similar <span class='footnotereverse'><a href='#fnref-304-2'>&#8617;</a></span></li>
</ol>
</div>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Tordek?a=hitB4Cz8L8A:T0pJoFHzGHY:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Tordek?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Tordek?a=hitB4Cz8L8A:T0pJoFHzGHY:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/Tordek?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Tordek?a=hitB4Cz8L8A:T0pJoFHzGHY:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/Tordek?i=hitB4Cz8L8A:T0pJoFHzGHY:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://blog.tordek.com.ar/2009/10/eso-no-es-poo-es-caca/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.tordek.com.ar/2009/10/eso-no-es-poo-es-caca/</feedburner:origLink></item>
		<item>
		<title>Listas vs. Tuplas</title>
		<link>http://feedproxy.google.com/~r/Tordek/~3/zzM750sdGCA/</link>
		<comments>http://blog.tordek.com.ar/2009/04/listas-vs-tuplas/#comments</comments>
		<pubDate>Tue, 28 Apr 2009 04:15:02 +0000</pubDate>
		<dc:creator>Tordek</dc:creator>
				<category><![CDATA[Programación]]></category>
		<category><![CDATA[haskell]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://blog.tordek.com.ar/2009/04/listas-vs-tuplas/</guid>
		<description><![CDATA[En la lista de PyAr hace no mucho alguien preguntó, «¿Cuál es la diferencia entre una tupla y una lista?». Acá hago una síntesis de las respuestas, y agrego mis notas. Esta duda surge en Python porque, a primera vista, la única diferencia es que una usa corchetes, y la otra paréntesis: No importa si [...]]]></description>
				<content:encoded><![CDATA[<p>En la lista de PyAr hace no mucho alguien preguntó, «¿Cuál es la diferencia entre una tupla y una lista?». Acá hago una síntesis de las respuestas, y agrego mis notas.</p>
<p>Esta duda surge en Python porque, a primera vista, la única diferencia es que una usa corchetes, y la otra paréntesis: No importa si tengo una lista o una tupla, puedo acceder a sus elementos con <code>[<var>indice</var>]</code>, y con cualquiera puedo hacer asignación múltiple (<code>a, b = [1, 2]</code>)&#8230;</p>
<p>Lentamente las diferencias empiezan a aparecer:</p>
<ul>
<li><strong>Las tuplas, como los strings, son inmutables</strong>: Una vez que una tupla tiene un valor, no se puede cambiar, sólo crear una nueva.</li>
<li>Debido a lo anterior, <strong>las tuplas son <em>hasheables</em></strong>: Se puede crear un diccionario que use como índice tuplas&#8212;pero nunca listas.</li>
</ul>
<p>Estas diferencias técnicas son las más importantes, y las que justamente las definen.</p>
<p>Ahora, ¿Cuándo es mejor cada una?&#8230; En muchos casos realmente no hay diferencia: Si a cualquiera de las dos puedo acceder por índice, o con for&#8230; Pero podemos tomar una pista de un lenguaje más estricto: Haskell.</p>
<p>En Haskell, una tupla de 2 elementos es de un tipo diferente al de una de 3 (y no se las puede acceder por índice). Además, las tuplas pueden ser heterogéneas, mientras que las listas son homogéneas. Eso es, puedo tener una tupla (int, String, String), pero una lista puede contener sólo un tipo de datos (Claro, ese tipo puede ser una tupla&#8230; pero divago).</p>
<p>Entonces, lo «correcto» (con comillas) es que, si a todos los elementos se los va a tratar de una misma forma (sea con un for, o con map), usamos una lista, pero si cada elemento tiene un significado diferente, lo mejor es una tupla.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Tordek?a=zzM750sdGCA:9KWK0gbQNOA:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Tordek?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Tordek?a=zzM750sdGCA:9KWK0gbQNOA:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/Tordek?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Tordek?a=zzM750sdGCA:9KWK0gbQNOA:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/Tordek?i=zzM750sdGCA:9KWK0gbQNOA:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://blog.tordek.com.ar/2009/04/listas-vs-tuplas/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://blog.tordek.com.ar/2009/04/listas-vs-tuplas/</feedburner:origLink></item>
		<item>
		<title>Gente Molesta</title>
		<link>http://feedproxy.google.com/~r/Tordek/~3/daee7RqiHTk/</link>
		<comments>http://blog.tordek.com.ar/2009/04/gente-molesta/#comments</comments>
		<pubDate>Mon, 27 Apr 2009 02:30:47 +0000</pubDate>
		<dc:creator>Tordek</dc:creator>
				<category><![CDATA[Cualquiera]]></category>
		<category><![CDATA[Tordek]]></category>
		<category><![CDATA[Haxx0r]]></category>
		<category><![CDATA[humor]]></category>
		<category><![CDATA[msn]]></category>
		<category><![CDATA[noob]]></category>

		<guid isPermaLink="false">http://blog.tordek.com.ar/2009/04/gente-molesta/</guid>
		<description><![CDATA[Las personas que más me molestan son las que me agregan al MSN, y la tercera pregunta que me hacen (después de «¿Te puedo hacer una pregunta?» y «¿Por qué me insultás así?») es «Sabés robar una contraseña?».]]></description>
				<content:encoded><![CDATA[<p>Las personas que más me molestan son las que me agregan al MSN, y la tercera pregunta que me hacen (después de «¿Te puedo hacer una pregunta?» y «¿Por qué me insultás así?») es «Sabés robar una contraseña?».</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Tordek?a=daee7RqiHTk:yGxcwIAOHOc:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Tordek?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Tordek?a=daee7RqiHTk:yGxcwIAOHOc:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/Tordek?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Tordek?a=daee7RqiHTk:yGxcwIAOHOc:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/Tordek?i=daee7RqiHTk:yGxcwIAOHOc:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://blog.tordek.com.ar/2009/04/gente-molesta/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		<feedburner:origLink>http://blog.tordek.com.ar/2009/04/gente-molesta/</feedburner:origLink></item>
		<item>
		<title>Chiste pésimo</title>
		<link>http://feedproxy.google.com/~r/Tordek/~3/e6pSe1YcAO8/</link>
		<comments>http://blog.tordek.com.ar/2009/03/chiste-pesimo/#comments</comments>
		<pubDate>Fri, 27 Mar 2009 13:14:22 +0000</pubDate>
		<dc:creator>Tordek</dc:creator>
				<category><![CDATA[Geek]]></category>
		<category><![CDATA[Programación]]></category>
		<category><![CDATA[Tordek]]></category>
		<category><![CDATA[baltha]]></category>
		<category><![CDATA[chiste]]></category>
		<category><![CDATA[lisp]]></category>
		<category><![CDATA[malo]]></category>

		<guid isPermaLink="false">http://blog.tordek.com.ar/?p=296</guid>
		<description><![CDATA[Tordek: Y a ver cuando aprendes Lisp vos, ¿eh? Baltha: ¡Ya se la mitad de Lisp, ¿sabés? ¡¿Sabés?! Tordek: ¿Qué, sabés &#8216;(&#8216;?]]></description>
				<content:encoded><![CDATA[<ul>
<li><strong>Tordek</strong>: Y a ver cuando aprendes Lisp vos, ¿eh?</li>
<li><strong>Baltha</strong>: ¡Ya se la mitad de Lisp, ¿sabés? ¡¿Sabés?!</li>
<li><strong>Tordek</strong>: ¿Qué, sabés &#8216;(&#8216;?</li>
</ul>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Tordek?a=e6pSe1YcAO8:edluPyVyYZE:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Tordek?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Tordek?a=e6pSe1YcAO8:edluPyVyYZE:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/Tordek?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Tordek?a=e6pSe1YcAO8:edluPyVyYZE:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/Tordek?i=e6pSe1YcAO8:edluPyVyYZE:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://blog.tordek.com.ar/2009/03/chiste-pesimo/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://blog.tordek.com.ar/2009/03/chiste-pesimo/</feedburner:origLink></item>
		<item>
		<title>22</title>
		<link>http://feedproxy.google.com/~r/Tordek/~3/1aPS5bYn1bA/</link>
		<comments>http://blog.tordek.com.ar/2009/03/22y/#comments</comments>
		<pubDate>Sun, 08 Mar 2009 18:42:05 +0000</pubDate>
		<dc:creator>Tordek</dc:creator>
				<category><![CDATA[Tordek]]></category>
		<category><![CDATA[22]]></category>
		<category><![CDATA[cumpleaños]]></category>
		<category><![CDATA[edad]]></category>

		<guid isPermaLink="false">http://blog.tordek.com.ar/?p=288</guid>
		<description><![CDATA[void envejecer&#40;struct persona_s *persona&#41; &#123; persona-&#62;edad++; &#125; &#160; envejecer&#40;tordek&#41;; Edit: Epa. Si no, no compila&#8230;]]></description>
				<content:encoded><![CDATA[
<div class="wp_syntax"><table><tr><td class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">void</span> envejecer<span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> persona_s <span style="color: #339933;">*</span>persona<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    persona<span style="color: #339933;">-&gt;</span>edad<span style="color: #339933;">++;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
envejecer<span style="color: #009900;">&#40;</span>tordek<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p><strong>Edit</strong>: Epa. Si no, no compila&#8230;</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Tordek?a=1aPS5bYn1bA:PsIJ_2JqD4A:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Tordek?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Tordek?a=1aPS5bYn1bA:PsIJ_2JqD4A:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/Tordek?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Tordek?a=1aPS5bYn1bA:PsIJ_2JqD4A:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/Tordek?i=1aPS5bYn1bA:PsIJ_2JqD4A:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://blog.tordek.com.ar/2009/03/22y/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		<feedburner:origLink>http://blog.tordek.com.ar/2009/03/22y/</feedburner:origLink></item>
		<item>
		<title>Experimentando con Frameworks CSS</title>
		<link>http://feedproxy.google.com/~r/Tordek/~3/eJtoDyda1dY/</link>
		<comments>http://blog.tordek.com.ar/2009/03/experimentando-con-frameworks-css/#comments</comments>
		<pubDate>Tue, 03 Mar 2009 19:55:42 +0000</pubDate>
		<dc:creator>Tordek</dc:creator>
				<category><![CDATA[Tordek]]></category>
		<category><![CDATA[960]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[grid]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[semantica]]></category>

		<guid isPermaLink="false">http://blog.tordek.com.ar/?p=285</guid>
		<description><![CDATA[Hace mucho escuché sobre ellos, pero nunca los había probado. Una promesa de solución al problema del layout &#8212;la parte de la disposición de los elementos en el diseño&#8212;. Al omnisciente Google emití una plegaria de ayuda para ver de qué venía tanta alharaca, y me choqué primero con 960 Grid System, que parece ser [...]]]></description>
				<content:encoded><![CDATA[<p>Hace mucho escuché sobre ellos, pero nunca los había probado. Una promesa de solución al problema del <em>layout</em> &#8212;la parte de la disposición de los elementos en el diseño&#8212;.</p>
<p>Al omnisciente <strong>Google</strong> emití una plegaria de ayuda para ver de qué venía tanta alharaca, y me choqué primero con <a href="http://960.gs"><strong>960 Grid System</strong></a>, que parece ser el más simple de la familia.</p>
<p>Lo usé para armar un diseño que necesitaba rápido, y en seguida vi la mayoría de sus ventajas y desventajas:</p>
<p><strong>Pros:</strong></p>
<ul>
<li>Diseñar con &#8220;grillas&#8221; (grids) da resultados bastante buenos, con una apariencia ordenada.</li>
<li>Si nos mantenemos dentro de los márgenes que el sistema de grillas propone, armar los diseños es rapidísimo y simplísimo.</li>
<li>Todos los problemas de compatibilidad de navegadores son cosa del pasado. Claro, sólo en la parte de división en columnas y eso.</li>
<li>Los templates que traen para <strong>Photoshop</strong> y demás facilitan el diseño.</li>
</ul>
<p><strong>Contras:</strong></p>
<ul>
<li>¿División de contenido y presentación? ¿Qué es eso?</li>
<li>Diseños fijos<sup class='footnote'><a href='#fn-285-1' id='fnref-285-1' onclick='return fdfootnote_show(285)'>1</a></sup>.</li>
<li>Cambiar una columna implica cambiar las demás para realinear.</li>
<li>La necesidad de agregar la clase <code>clearfix</code> en un elemento vacío es poco semántico.</li>
<li>El tamaño no es algo que se pueda decir «minúsculo»<sup class='footnote'><a href='#fn-285-2' id='fnref-285-2' onclick='return fdfootnote_show(285)'>2</a></sup>.</li>
</ul>
<p>Los <em>frameworks CSS</em> tienen una utilidad innegable. Ayudan a armar un diseño muy rápidamente, sin tener que preocuparnos por si va a andar o no en &#8220;el otro navegador&#8221;.</p>
<p>Por otro lado, puristas de la separación<sup class='footnote'><a href='#fn-285-3' id='fnref-285-3' onclick='return fdfootnote_show(285)'>3</a></sup> se van a quejar de que usar un <em>framework CSS</em> vence el propósito de usar CSS: estamos poniendo en el HTML las clases que determinan el tamaño de cada columna, en vez de poner eso en el CSS, como corresponde. Al poner clases sin significado (¿Qué es un «grid_3»?) a los elementos, estamos agregando información que no es nada semántica, y no ayuda en nada a un parser, pero este problema se minimiza si usamos, además de las clases de grid, ids y clases significativos.</p>
<p>En fin, los frameworks pueden dar resultados excelentes si lo que buscamos se presta al diseño en grillas, además de hacerlo rápido y fácil, y sólo los muy extremistas tienen lugar para quejarse &#8212;y aún así, tienen una opción de usar los frameworks «correctamete», usándolos primero para «ver cómo va a quedar», y después armar su propia hoja de estilos destilada&#8212;.</p>
<div class='footnotes' id='footnotes-285'>
<div class='footnotedivider'></div>
<ol>
<li id='fn-285-1'>Claro que esto no siempre es malo <span class='footnotereverse'><a href='#fnref-285-1'>&#8617;</a></span></li>
<li id='fn-285-2'>la versión minimizada de 960.css mide 3.6kb, pero, siendo que el archivo no cambia, es perfectamente cacheable <span class='footnotereverse'><a href='#fnref-285-2'>&#8617;</a></span></li>
<li id='fn-285-3'>Me incluyo. <span class='footnotereverse'><a href='#fnref-285-3'>&#8617;</a></span></li>
</ol>
</div>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Tordek?a=eJtoDyda1dY:nA9panuYmfI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Tordek?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Tordek?a=eJtoDyda1dY:nA9panuYmfI:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/Tordek?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Tordek?a=eJtoDyda1dY:nA9panuYmfI:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/Tordek?i=eJtoDyda1dY:nA9panuYmfI:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://blog.tordek.com.ar/2009/03/experimentando-con-frameworks-css/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://blog.tordek.com.ar/2009/03/experimentando-con-frameworks-css/</feedburner:origLink></item>
		<item>
		<title>XMonad</title>
		<link>http://feedproxy.google.com/~r/Tordek/~3/fVoyWxBzyNs/</link>
		<comments>http://blog.tordek.com.ar/2009/02/xmonad/#comments</comments>
		<pubDate>Tue, 10 Feb 2009 16:22:21 +0000</pubDate>
		<dc:creator>Tordek</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[haskell]]></category>
		<category><![CDATA[X]]></category>
		<category><![CDATA[xmonad]]></category>

		<guid isPermaLink="false">http://blog.tordek.com.ar/2009/02/xmonad/</guid>
		<description><![CDATA[Off Topic: Es irónico&#8230; hace un mes, o más, que no posteaba&#8230; por, no sé, nada en particular; simplemente no lo hacía&#8230; Lo gracioso es que desde esa época, mis visitas empezaron a subir&#8230; ¿Es una señal? Acá estoy, probando mi nuevo Window Manager, XMonad. Es un &#8220;tiling window manager&#8221;, lo que significa que cada [...]]]></description>
				<content:encoded><![CDATA[<p><b>Off Topic:</b> Es irónico&#8230; hace un mes, o más, que no posteaba&#8230; por, no sé, nada en particular; simplemente no lo hacía&#8230; Lo gracioso es que desde esa época, mis visitas empezaron a subir&#8230; ¿Es una señal?</p>
<p>Acá estoy, probando mi nuevo Window Manager, <strong>XMonad</strong>. Es un &#8220;tiling window manager&#8221;, lo que significa que cada ventana ocupa todo el espacio disponible, dividiéndo la pantalla (en realidad, cada escritorio virtual) según lo necesite.</p>
<p>Entre las cosas más grosas que tiene:</p>
<dl>
<dt>(Casi) no necesito usar el mouse.</dt>
<dd>Hay unos cuantos que se oponen a que abandone a la rata. Algunos infractores son Amarok (el botón de menú de mi teclado no hace nada en la lista de canciones) y las aplicaciones en Java (que, directamente, no puedo usar). Casi todo lo demás, lo hago usando la tecla Windows, acompañada de alguna letra, para navegar las ventanas, o dividirlas, o demás.</dd>
<dt>Haskell.</dt>
<dd>Haskell ya es groso de por sí; que <strong>XMonad</strong> esté programado en Haskell significa el fin de cuelgues y caídas, porque es casi imposible poner un bug.</dd>
<dt>Las divisiones de ventanas.</dt>
<dd><a href="http://tordek.com.ar/images/screen.png">Un screenshot habla más que 1k DWORDS</a><sup class='footnote'><a href='#fn-247-1' id='fnref-247-1' onclick='return fdfootnote_show(247)'>1</a></sup></dd>
<dt>Se banca dos monitores. Pero bien.</dt>
<dd>Lo que siempre quise con <strong>KDE</strong> era tener un escritorio en cada monitor, y <strong>XMonad</strong> sí me deja; con <kbd>Mod-[1-9]</kbd> cambio la pantalla actual (que elijo con <kbd>Mod+{w,e}</kbd>) a uno de los escritorios.</dd>
</dl>
<p>Lo único que no está tan bueno es toda la configuración que requiere para empezar a usarlo; aunque es extremadamente personalizable.</p>
<p>Pruébenlo, si creen en eso de que el mouse es malo y lento, o simplemente tienen ganas de probar algo nuevo. Yo lo uso porque me gusta maximizar mis ventanas tanto como tener varias a la vista :P&#8230;</p>
<div class='footnotes' id='footnotes-247'>
<div class='footnotedivider'></div>
<ol>
<li id='fn-247-1'>Especialmente uno de 2560&#215;1024 <span class='footnotereverse'><a href='#fnref-247-1'>&#8617;</a></span></li>
</ol>
</div>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Tordek?a=fVoyWxBzyNs:J7ukyN4hfC4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Tordek?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Tordek?a=fVoyWxBzyNs:J7ukyN4hfC4:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/Tordek?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Tordek?a=fVoyWxBzyNs:J7ukyN4hfC4:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/Tordek?i=fVoyWxBzyNs:J7ukyN4hfC4:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://blog.tordek.com.ar/2009/02/xmonad/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<feedburner:origLink>http://blog.tordek.com.ar/2009/02/xmonad/</feedburner:origLink></item>
		<item>
		<title>Indirecta</title>
		<link>http://feedproxy.google.com/~r/Tordek/~3/1x8Ia53sp2Q/</link>
		<comments>http://blog.tordek.com.ar/2008/12/indirecta/#comments</comments>
		<pubDate>Fri, 19 Dec 2008 10:40:05 +0000</pubDate>
		<dc:creator>Tordek</dc:creator>
				<category><![CDATA[Tordek]]></category>

		<guid isPermaLink="false">http://blog.tordek.com.ar/?p=244</guid>
		<description><![CDATA[[Comentario humorístico, indirectamente religioso] Disclaimer: Esto es tan solo una traducción. No representa la opinión del autor de este blog, ni ninguno de sus participantes. Sólo lo estoy haciendo porque quiero visitas en mi blog, y estoy poniendo contenido que, aparentemente, no respeto, en un espacio personal.]]></description>
				<content:encoded><![CDATA[<blockquote><p>[Comentario humorístico, indirectamente religioso]</p></blockquote>
<p><strong>Disclaimer</strong>: Esto es tan solo una traducción. No representa la opinión del autor de este blog, ni ninguno de sus participantes. Sólo lo estoy haciendo porque quiero visitas en mi blog, y estoy poniendo contenido que, aparentemente, no respeto, en un espacio personal.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Tordek?a=1x8Ia53sp2Q:HLp3IOYRsEU:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Tordek?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Tordek?a=1x8Ia53sp2Q:HLp3IOYRsEU:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/Tordek?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Tordek?a=1x8Ia53sp2Q:HLp3IOYRsEU:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/Tordek?i=1x8Ia53sp2Q:HLp3IOYRsEU:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://blog.tordek.com.ar/2008/12/indirecta/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.tordek.com.ar/2008/12/indirecta/</feedburner:origLink></item>
		<item>
		<title>Do what you mean. Do what I mean.</title>
		<link>http://feedproxy.google.com/~r/Tordek/~3/BnCFqNeXtR0/</link>
		<comments>http://blog.tordek.com.ar/2008/12/do-what-you-mean-do-what-i-mean/#comments</comments>
		<pubDate>Thu, 04 Dec 2008 21:27:42 +0000</pubDate>
		<dc:creator>Tordek</dc:creator>
				<category><![CDATA[Programación]]></category>
		<category><![CDATA[confirmacion]]></category>
		<category><![CDATA[deshacer]]></category>
		<category><![CDATA[undo]]></category>

		<guid isPermaLink="false">http://blog.tordek.com.ar/2008/12/do-what-you-mean-do-what-i-mean/</guid>
		<description><![CDATA[El diálogo de &#8220;¿Estás seguro?&#8221; es total y absolutamente inutil. Estuve discutiendo con un amigo, que dice que no es así, pero la única conclusión que tengo es: Si necesitás ese diálogo, tu sistema está mal diseñado. &#8212;Pero, &#8212;algunos se quejarán&#8212; ¿y si me equivoqué? ¿Y si después de que lo hice me dí cuenta [...]]]></description>
				<content:encoded><![CDATA[<p>El diálogo de &#8220;¿Estás seguro?&#8221; es total y absolutamente inutil. Estuve discutiendo con un amigo, que dice que no es así, pero la única conclusión que tengo es: Si necesitás ese diálogo, tu sistema está mal diseñado.</p>
<p>&#8212;Pero, &#8212;algunos se quejarán&#8212; ¿y si me equivoqué? ¿Y si después de que lo hice me dí cuenta que no lo quería?</p>
<p>Bien, primero: Si te diste cuenta después, el botón de &#8220;estás seguro&#8221; no te salva. Obviamente, la opción no es &#8220;Ja, lástima, para qué hacés click ahí&#8221;. Existe una que sirve de verdad, y que hace mucho nos dimos cuenta que se puede: Deshacer.</p>
<p>Si en Windows se me ocurre borrar un archivo, va a la papelera. Si me equivoqué, lo recupero. Si en Thunderbird borro un mensaje, está en la basura.</p>
<p>Aparte, ¿para qué cambiar el significado de las cosas? Tengo un botón borrar. ¿Qué hace ese botón? ¿Borra? No. Me muestra una ventana que me pregunta &#8220;¿Estás seguro?&#8221;, y al hacer click en &#8220;Sí&#8221;, recién borra. ¿Desde cuando &#8220;Borrar&#8221; significa &#8220;Preguntame si quiero borrar&#8221;, y &#8220;Sí&#8221; significa borrar?</p>
<p>Y es imposible quejarse acerca de implementarlo. Si nuestra aplicación usa alguna forma de base de datos, tenemos una marca de &#8220;Borrado&#8221;. Si usa el sistema de archivos, una carpeta donde almacenamos los archivos &#8216;Borrados&#8217;.</p>
<p><a href="http://msdn.microsoft.com/en-us/magazine/cc163835.aspx">Confirmar es inutil, Deshacer es divino</a>, o como quieras ponerlo, basta de preguntas, y hacé lo que dije.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Tordek?a=BnCFqNeXtR0:FaNbGLzoURQ:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Tordek?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Tordek?a=BnCFqNeXtR0:FaNbGLzoURQ:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/Tordek?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Tordek?a=BnCFqNeXtR0:FaNbGLzoURQ:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/Tordek?i=BnCFqNeXtR0:FaNbGLzoURQ:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://blog.tordek.com.ar/2008/12/do-what-you-mean-do-what-i-mean/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		<feedburner:origLink>http://blog.tordek.com.ar/2008/12/do-what-you-mean-do-what-i-mean/</feedburner:origLink></item>
	</channel>
</rss>
