<?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"
	>

<channel>
	<title>Ruido blanco</title>
	<atom:link href="http://ruido-blanco.net/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://ruido-blanco.net/blog</link>
	<description>Estática sólo para confundir</description>
	<pubDate>Mon, 21 Jul 2008 21:29:42 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5.1</generator>
	<language>es</language>
			<item>
		<title>Die this way</title>
		<link>http://ruido-blanco.net/blog/archivos/2008/07/21/die-this-way/</link>
		<comments>http://ruido-blanco.net/blog/archivos/2008/07/21/die-this-way/#comments</comments>
		<pubDate>Mon, 21 Jul 2008 21:29:42 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
		
		<category><![CDATA[Asides]]></category>

		<category><![CDATA[Música]]></category>

		<guid isPermaLink="false">http://ruido-blanco.net/blog/?p=1062</guid>
		<description><![CDATA[Die this way. El hermanito pequeño del compositor original se monta una versión hip-hopera de los créditos finales de Dexter.
]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.goear.com/listen.php?v=ac0d1f8" title="Die this way - Jon Licht">Die this way</a>. El hermanito pequeño del compositor original se monta una versión <em>hip-hopera</em> de los créditos finales de Dexter.</p>
]]></content:encoded>
			<wfw:commentRss>http://ruido-blanco.net/blog/archivos/2008/07/21/die-this-way/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Otro Muxtape</title>
		<link>http://ruido-blanco.net/blog/archivos/2008/07/20/otro-muxtape/</link>
		<comments>http://ruido-blanco.net/blog/archivos/2008/07/20/otro-muxtape/#comments</comments>
		<pubDate>Sun, 20 Jul 2008 12:55:02 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
		
		<category><![CDATA[Música]]></category>

		<guid isPermaLink="false">http://ruido-blanco.net/blog/?p=1061</guid>
		<description><![CDATA[Este Muxtape es un homenaje a uno de los mejores podcast que hay por ahí: Coverville (con permiso de Bajo la Confusión Purpura, por supuesto).


  
    
      Artista
      Canción
      Artista original
      [...]]]></description>
			<content:encoded><![CDATA[<p>Este <a href="http://yonosoytu.muxtape.com" title="Tom Waits ate my dog for breakfast">Muxtape</a> es un homenaje a uno de los mejores <em>podcast</em> que hay por ahí: <a href="http://www.coverville.com" title="Coverville">Coverville</a> (con permiso de Bajo la Confusión Purpura, por supuesto).</p>

<table class="SimpleBlueHeader">
  <thead>
    <tr>
      <th>Artista</th>
      <th>Canción</th>
      <th>Artista original</th>
      <th>*</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>José Gonzalez</td>
      <td>Teardrop</td>
      <td>Massive Attack</td>
      <td>1</td>
    </tr>
    <tr>
      <td>Scala</td>
      <td>Teenage Dirtbag</td>
      <td>Wheatus</td>
      <td>2</td>
    </tr>
    <tr>
      <td>The Wombats</td>
      <td>Patience</td>
      <td>Take That</td>
      <td>3</td>
    </tr>
    <tr>
      <td>Nouvelle Vague</td>
      <td>Teenage Kicks</td>
      <td>The Undertones</td>
      <td>4</td>
    </tr>
    <tr>
      <td>Nelly Furtado</td>
      <td>Crazy</td>
      <td>Gnarls Barkley</td>
      <td>5</td>
    </tr>
    <tr>
      <td>MIT Resonance</td>
      <td>Mr. Brightside</td>
      <td>The Killers</td>
      <td>6</td>
    </tr>
    <tr>
      <td>Jeff Buckley</td>
      <td>Hallelujah</td>
      <td>Leonard Cohen</td>
      <td>7</td>
    </tr>
    <tr>
      <td>Johnathan Coulton</td>
      <td>Baby Got Back</td>
      <td>Sir Mix-a-lot</td>
      <td>8</td>
    </tr>
    <tr>
      <td>Johnny Cash</td>
      <td>One</td>
      <td>U2</td>
      <td>9</td>
    </tr>
    <tr>
      <td>Ben Folds</td>
      <td>Bitches Ain&#8217;t Shit</td>
      <td>Dr. Dre</td>
      <td>10</td>
    </tr>
    <tr>
      <td>Willian Shatner</td>
      <td>Common People</td>
      <td>Pulp</td>
      <td>11</td>
    </tr>
  </tbody>
</table>

<ol>
  <li>Oída en el capítulo final de la temporada 4 de House, que curiosamente utiliza la versión original como música de la presentación (al menos en EEUU).</li>
  <li>De la que ya hablé en <a href="http://ruido-blanco.net/blog/archivos/2006/02/14/bolsa-de-basura-adolescente/" title="Bolsa de basura adolescent - Ruido Blanco">Bolsa de basura adolescente</a>.</li>
  <li>La pillé el otro día en RNE3, y consiguió que me gustase una canción de Take That</li>
  <li><em>Are teenage dreams so hard to beat, everytime she walks down the street</em>. Única canción con <a href="http://en.wikipedia.org/wiki/Teenage_Kicks" title="Teenage Kicks en la Wikipedia" onclick="javascript:pageTracker._trackPageview ('/outbound/en.wikipedia.org');">28 estrellas en el iTunes de John Peel</a></li>
  <li>La voz, en acústico, de la Srta. Furtado, hacen de esta una deliciosa versión.</li>
  <li>Todo cantando <em>a capella</em> suena mejor. Y <a href="http://es.youtube.com/watch?v=oq-76t0287U" title="The Killers' Mr. Brightside a capella - Youtube" onclick="javascript:pageTracker._trackPageview ('/outbound/es.youtube.com');">se ve mejor</a></li>
  <li>Que me perdone el Sr. Cohen, pero esta versión es la mejor que se ha hecho de <em>Hallelujah</em>, y Jeff nos abandonó poco después.</li>
  <li>Porque no puedo poner <em>Still Alive</em>.</li>
  <li>Como con casi cualquier canción que cantase Johnny Cash, la canta, y la hace suya.</li>
  <li>En la versión original (un <em>rap</em>) soy incapaz de seguir la letra. Pero me he resistido a poner la versión <a href="http://es.youtube.com/watch?v=TjNNxnKVEpQ" title="Bitches ain't shit a capella -Youtube" onclick="javascript:pageTracker._trackPageview ('/outbound/es.youtube.com');"><em>a capella</em></a>.</li>
  <li>Willian Shatner (sí, el Capitán Kirk) &#8220;recita&#8221; Common People junto con Joe Jackson y Ben Folds al piano (y algunas voces). <a href="http://es.youtube.com/watch?v=eISBTBwWKeE" title="The Shat sings Common People - Youtube" onclick="javascript:pageTracker._trackPageview ('/outbound/es.youtube.com');">The Shat rocks!</a></li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://ruido-blanco.net/blog/archivos/2008/07/20/otro-muxtape/feed/</wfw:commentRss>
		</item>
		<item>
		<title>&#8220;Desplegado&#8221; en Dreamhost de una aplicación Sinatra utilizando Capistrano</title>
		<link>http://ruido-blanco.net/blog/archivos/2008/07/17/desplegado-en-dreamhost-de-una-aplicacion-sinatra-utilizando-capistrano/</link>
		<comments>http://ruido-blanco.net/blog/archivos/2008/07/17/desplegado-en-dreamhost-de-una-aplicacion-sinatra-utilizando-capistrano/#comments</comments>
		<pubDate>Thu, 17 Jul 2008 19:07:57 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
		
		<category><![CDATA[Programación]]></category>

		<guid isPermaLink="false">http://ruido-blanco.net/blog/?p=1056</guid>
		<description><![CDATA[Creacción de un nuevo usuario en Dreamhost

Este es un paso opcional, pero como DreamHost a veces mata a los procesos que consumen mucha CPU o memoria, si tenemos otras aplicaciones o páginas web corriendo en DreamHost, y esperamos que nuestra nueva aplicación tenga una carga moderada es recomendable crear otro usuario específico para cada nueva [...]]]></description>
			<content:encoded><![CDATA[<h3>Creacción de un nuevo usuario en Dreamhost</h3>

<p>Este es un paso opcional, pero como DreamHost a veces mata a los procesos que consumen mucha CPU o memoria, si tenemos otras aplicaciones o páginas web corriendo en DreamHost, y esperamos que nuestra nueva aplicación tenga una carga moderada es recomendable crear otro usuario específico para cada nueva aplicación.</p>

<ol>
<li>Accedemos a la <a href="https://panel.dreamhost.com/index.cgi?tree=users.users" title="DreamHost Web Panel - Users : Manage Users">gestión de usuarios</a> del panel de DreamHost.</li>
<li>Creamos un nuevo usuario y nos fijaremos que para &#8220;Type of User Account&#8221; esté seleccionada la opción &#8220;Shell&#8221;.</li>
</ol>

<h3>Creación del nuevo dominio o subdominio</h3>

<ol>
<li>Entraremos en la <a href="https://panel.dreamhost.com/index.cgi?tree=domain.manage" title="DreamHost Web Panel - Domains : Manage Domains">gestión de dominios</a> del panel de DreamHost.</li>
<li>Creamos un nuevo dominio o subdominio.</li>
<li>Es muy importante seleccionar el <em>checkbox</em> &#8220;Ruby on Rails Passenger (mod&#95;rails)?&#8221;.</li>
<li>Si en el apartado anterior hemos creado un nuevo usuario lo utilizaremos aquí. En el caso de utilizar un usuario que ya teníamos debemos cerciorarnos de que podemos acceder por SSH con él.</li>
<li>En el cuadro de texto &#8220;Specify your web directory&#8221; aparecerá el nombre de nuestro dominio. Si pensamos utilizar Capistrano para hacer el <em>deploy</em> deberemos añadir al nombre del dominio <code>/current/public</code>. Si no vamos a utilizar Capistrano simplemente añadiremos <code>/public</code>.</li>
</ol>

<p>En estos momentos DreamHost se pondrá a trabajar y en un tiempo tendremos nuestro nuevo dominio preparado. Si vamos a utilizar Capistrano es importante que accedamos al servidor ahora y borremos el directorio <code>current</code> que DreamHost haya creado (y junto con él, el directorio <code>public</code> que contiene). Capistrano creará estos directorios cuando sea necesario.</p>

<h3>Utilizando Capistrano con nuestra aplicación</h3>

<p>Voy a suponer que nuestra aplicación <a href="http://sinatrarb.com/" title="Sinatra">Sinatra</a> está en un directorio llamado <code>app</code>, y dentro de él se encuentran el archivo <code>app.rb</code>, que es el archivo principal de nuestra aplicación, y varios directorios (algunos específicos a Sinatra como <code>public</code> y <code>views</code>, y otros que no lo son).</p>

<p>La herramienta de línea de mandatos de <a href="http://capify.org/">Capistrano</a> (<code>cap</code>) busca en el directorio actual un archivo denominado <code>Capfile</code> donde podría encontrarse toda nuestra receta, pero para poder reutilizarla más sencillamente en otros proyectos vamos a crearla en <code>recipes/sinatra.rb</code>. Podéis descargar <a href="http://ruido-blanco.net/descargas/sinatra.rbs" title="sinatra.rb"><code>sinatra.rb</code></a> y copiarlo a esa carpeta (cambiad la extensión <code>.rbs</code> por <code>.rb</code>).</p>

<p>La receta utiliza la receta original de Capistrano para Rails, por lo que hay muchas tareas que realizan la misma función (adaptadas a Sinatra y mod&#95;rails, claro), y otras que han desaparecido (las de migraciones y las de <em>start</em> y <em>stop</em>).</p>

<p>Finalmente crearemos el archivo <code>Capfile</code> en el directorio raíz de nuestra aplicación con unos contenidos similares a los siguientes:</p>

<p><code class="block ruby">
load &apos;recipes/sinatra&apos;<br />
<br />
&#35; Nombre de nuestra aplicación<br />
set :application, &apos;app&apos;<br />
<br />
&#35; URL de nuestro repositorio.<br />
&#35; Personalmente utilizo Git, por lo que tengo un repositorio justo en<br />
&#35; el directorio de la aplicación.<br />
set :repository,  &apos;file://.&apos;<br />
<br />
&#35; El nombre de usuario en el servidor remoto.<br />
&#35; Necesario si no vais a utilizar .ssh/config<br />
set :user, &apos;<em>usuario</em>&apos;<br />
<br />
&#35; Directorio de la máquina remota donde se encontrará la aplicación.<br />
&#35; Atención: sin la parte de current/public.<br />
set :deploy&#95;to, &apos;/home/<em>usuario</em>/www.example.com/&apos;<br />
<br />
&#35; El tipo de control de versiones que<br />
&#35; utilizamos (:subversion, :git, :mercurial, &#8230;)<br />
set :scm, :git<br />
<br />
&#35; (Expecífico para Git) La rama de la que haremos deploy<br />
set :branch, &apos;master&apos;<br />
<br />
&#35; Como el código será descargado en el servidor.<br />
&#35; Personalmente utilizo :copy, que descarga en la máquina local el<br />
&#35; repositorio, lo comprime y lo envía a la máquina remota.<br />
&#35; En la documentación Rdoc de Capistrano se encuentran todas las<br />
&#35; posibilidades y sus opciones.<br />
set :deploy&#95;via, :copy<br />
set :copy&#95;cache, true<br />
<br />
&#35; Las URL de cada uno de nuestros servidores y que rol desempeñan.<br />
&#35; Algunas tareas de las recetas solo se ejecutan en para ciertos roles.<br />
&#35; En este caso nuestro servidor tiene dos roles.<br />
role :app, &apos;www.example.com&apos;<br />
role :web, &apos;www.example.com&apos;<br />
<br />
&#35; DreamHost no nos deja utilizar sudo, así que lo desactivamos.<br />
set :use&#95;sudo, false<br />
</code></p>

<h3>Instalando gemas en DreamHost</h3>

<p>Para instalar gemas en DreamHost necesitaremos un directorio local para almacenarlas y escribir un par de archivos de configuración:</p>

<ol>
  <li>Entramos con SSH a la cuenta del usuario que vaya a ejecutar la aplicación (el que hemos creado en el primer apartado o el que ya existia).</li>
  <li>Creamos el directorio para las gemas:
    <code class="block shell">
$ mkdir ~/.gems
</code>
  </li>
  <li>Editamos el archivo <code>~/.bash_profile</code> y le añadimos la línea:
    <code class="block">
export GEM_PATH=$HOME/.gems:/usr/local/lib/ruby/gems/1.8
</code>
  </li>
  <li>Editamos el archivo <code>~/.gemrc</code>:<br />
    <code class="block">
gemhome: /home/<em>usuario</em>/.gems<br />
gempath:<br />
- /home/<em>usuario</em>/.gems<br />
- /usr/local/lib/ruby/gems/1.8<br />
gem: &#8211;no-ri &#8211;no-rdoc
</code>
  </li>
  <li>Instaleremos las gemas necesarias, por ejemplo, Sinatra:<br /><code>gem install sinatra</code>.</li>
</ol>

<h3>Preparando nuestra aplicación para Passenger</h3>

<p>Passenger utiliza <a href="http://rack.rubyforge.org/" title="Rack: a Ruby Webserver Interface">Rack</a> para comunicarse como muchos <em>framework</em> Ruby que no sean Rails, por lo que necesitamos crear un archivo <code>config.ru</code> en el directorio raíz de nuestra aplicación que le diga a Passenger como servir nuestra aplicación. El archivo es casi identico al que viene en la documentación de Passenger (hay que felicitarles por tener una documentación tan buena).</p>

<p><code class="block ruby">
&#35; Le decimos a Rubygems donde debe buscar las gemas<br />
ENV[&apos;GEM&#95;PATH&apos;] = &apos;/home/<em>usuario</em>/.gems:/usr/local/lib/ruby/gems/1.8&apos;<br />
<br />
require &apos;rubygems&apos;<br />
require &apos;sinatra&apos;<br />
<br />
Sinatra::Application.default&#95;options.merge!(<br />
&nbsp;&nbsp;:run => false,<br />
&nbsp;&nbsp;:env => :production<br />
)<br />
<br />
require &apos;app.rb&apos; # Nuestro archivo con la aplicación<br />
run Sinatra.application
</code></p>

<h3>Preparando el servidor con Capistrano</h3>

<p>En este punto hay que cerciorarse que todos los archivos necesarios están bajo control de versiones, porque nada que no lo esté será copiado al servidor. El archivo de la aplicación <code>app.rb</code>, el archivo <code>config.ru</code>, y los directorios <code>public</code> y <code>views</code>, deberían estar bajo control de versiones.</p>

<p>Para preparar el servidor debemos situarnos en el directorio raíz y ejecutar:</p>

<p><code class="block shell">
$ cap deploy:setup
</code></p>

<p>Depende de como tengamos configurado nuestro acceso mediante SSH al servidor puede que Capistrano nos pida una contraseña o no (si tenemos la clave pública y privada correctamente configuradas Capistrano no debería pedir contraseñas).</p>

<p>Quizá en este punto sería recomendable comprobar que en el servidor está todo correcto. La estructura de directorios que se debería haber creado es la siguiente:</p>

<pre>
/home/<em>usuario</em>/www.example.com/
/home/<em>usuario</em>/www.example.com/releases/
/home/<em>usuario</em>/www.example.com/shared/
/home/<em>usuario</em>/www.example.com/shared/system/
</pre>

<h3>Realizando el despliege</h3>

<p>Tanto si es el primer <em>deploy</em>, como si es uno de los posteriores lo único que tenemos que hacer para enviar al servidor la nueva versión de nuestro código es lo siguiente:</p>

<ol>
  <li>Nos situamos en el directorio raíz de nuestro proyecto.</li>
  <li>Comprobamos que todos los archivos que queremos enviar están en el repositorio</li>
  <li>Ejecutamos:
    <code class="block shell">
$ cap deploy
</code></li>
</ol>

<p>En este momento se habrá creado un nuevo directorio dentro del directorio <code>releases</code> del servidor, y se habrá creado un enlace simbólico desde <code>current</code> a él.</p>

<p>Si no hay problemas nuestra nueva web con Sinatra debería estar funcionando en nuestro dominio.</p>
]]></content:encoded>
			<wfw:commentRss>http://ruido-blanco.net/blog/archivos/2008/07/17/desplegado-en-dreamhost-de-una-aplicacion-sinatra-utilizando-capistrano/feed/</wfw:commentRss>
		</item>
		<item>
		<title>And now for something completely different</title>
		<link>http://ruido-blanco.net/blog/archivos/2008/07/15/and-now-for-something-completely-different/</link>
		<comments>http://ruido-blanco.net/blog/archivos/2008/07/15/and-now-for-something-completely-different/#comments</comments>
		<pubDate>Tue, 15 Jul 2008 18:45:37 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
		
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://ruido-blanco.net/blog/?p=1055</guid>
		<description><![CDATA[Protocol que representan el sleep log (traducción: registro de los intentos de los criptógrafos más de una empresa de software que el Half- Life original, el Counter Strike y también a esta primera parte, sobre todo en este caso me da igual, mala suerte ahora estoy totalmente perdido (por suerte Python dispone del módulo_zlib) vuelven [...]]]></description>
			<content:encoded><![CDATA[<p>Protocol que representan el sleep log (traducción: registro de los intentos de los criptógrafos más de una empresa de software que el Half- Life original, el Counter Strike y también a esta primera parte, sobre todo en este caso me da igual, mala suerte ahora estoy totalmente perdido (por suerte Python dispone del módulo_zlib) vuelven a estar completa), y nombres que he llegado a ser, sobre todo la primera, pero ese primer apagón no me interesa): GETs should be permanent, sorry the inconvenience). The man they call Joss! Our Joss saw the viewers’ hearts breakin’, He saw the</p>
]]></content:encoded>
			<wfw:commentRss>http://ruido-blanco.net/blog/archivos/2008/07/15/and-now-for-something-completely-different/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Wet Floor se renueva</title>
		<link>http://ruido-blanco.net/blog/archivos/2008/07/11/wet-floor-se-renueva/</link>
		<comments>http://ruido-blanco.net/blog/archivos/2008/07/11/wet-floor-se-renueva/#comments</comments>
		<pubDate>Fri, 11 Jul 2008 08:22:26 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
		
		<category><![CDATA[Programación]]></category>

		<guid isPermaLink="false">http://ruido-blanco.net/blog/?p=1054</guid>
		<description><![CDATA[Según las estadísticas de acceso (cosa que me recuerda que voy a tener que re-activarlas) las páginas más visitadas del dominio son las versiones inglesa y española de Wet Floor (entre las dos acaparan el 44% de las visitas), pero desde que lo publiqué (allá en el lejano 2006) no le he hecho demasiado caso, [...]]]></description>
			<content:encoded><![CDATA[<p>Según las estadísticas de acceso (cosa que me recuerda que voy a tener que re-activarlas) las páginas más visitadas del dominio son las versiones inglesa y española de Wet Floor (entre las dos acaparan el 44% de las visitas), pero desde que lo publiqué (allá en el lejano 2006) no le he hecho demasiado caso, aunque siempre supe que era lento, lento, lento.</p>

<p>Con la posibilidad de utilizar <a href="http://www.modrails.com/" title="Phusion Passenger (a.k.a. mod_rails)">mod&#95;rails/mod&#95;rack/Passenger</a> en <a href="http://www.dreamhost.com/r.cgi?207443" title="DreamHost Web Hosting">DreamHost</a> (mi servicio de <em>hosting</em>) pensé que no estaría mal comprobar que tal funcionaba y a la vez hacer el par de cambios que me apetecían para renovar Wet Floor (por debajo, nada de cara al usuario).</p>

<p>Lo primero ha sido cambiar <a href="http://code.whytheluckystiff.net/camping" title="Camping, a microframework">Camping</a> por <a href="http://sinatrarb.com/" title="Sinatra | Home">Sinatra</a>. No por nada en especial, no creo que uno sea mejor que el otro o al contrario. Si bien es cierto que Camping estaba un poco abandonado, aunque la comunidad parece que había sacado adelante un versión 2.0, me apetecía probar Sinatra, que sí que es más claro que Camping en muchos puntos. Este cambio ha sido sencillo: siendo los dos Ruby, gran cantidad del (poco) código que hace funcionar Wet Floor ha sido copiar y pegar. Con este cambio también he decidido que la generación del HTML y el CSS de las páginas sea 
mediante <a href="http://haml.hamptoncatlin.com/" title="#haml">Haml &amp; Sass</a>, que cada vez me siguen gustando más (pero que me han demostrado mi temor de que no están pensados para escribir &#8220;texto&#8221; con HTML, si no más bien sólo estructura HTML).</p>

<p>Lo segundo ha sido utilizar <a href="http://rack.rubyforge.org/" title="Rack, a Ruby webserver interface">Rack</a>, para poder utilizar Passenger con Sinatra. Creo que esto ha sido lo más sencillo de todo: es increíble que en la propia documentación de Passenger viniera como utilizarlo con Sinatra, y es más, que el código funcionase sin problemas en DreamHost. Utilizar Passenger me ha obligado a cambiar de localización Wet Floor, pero es algo que también tenía en mente (la antigua dirección se encuentra redirigida a la nueva, por lo que no necesitáis actualizar vuestros enlaces).</p>

<p>Lo último (por ahora) ha sido crearme una receta para el <em>deploy</em> con <a href="http://www.capify.org/" title="Capistrano: Home">Capistrano</a>, adaptando las recetas de Rails para que funcionasen con Sinatra, Rack y DreamHost. Con esta receta instalar nuevas versiones de Wet Floor es cuestión de un <code>cap deploy</code> e introducir una contraseña. Más sencillo imposible.</p>

<p>Como tarea pendiente me queda reducir el peso de la página. Entre contenido, imágenes y JavaScripts me tarda entre 7 y 10 segundos en terminar de cargar. Mis pensamientos se digiren a cambiar todo el JavaScripts para utilizar <a href="http://jquery.com/" title="jQuery: The Write Less, Do More, JavaScript Library">jQuery</a> y utilizar versiones &#8220;minimizadas&#8221; del código en producción.</p>

<p>Bueno, creo que nada más, bienvenidos a <a href="http://wetfloor.ruido-blanco.net" title="Wet Floor">el nuevo viejo Wet Floor</a>.</p>

<p>PD: Sí, algo más, supongo que caerá un <em>tutorialcillo</em> de como hacer una aplicación Sinatra en Dreamhost utilizando Passenger y Capistrano, no voy a quedarme la receta sólo para mí.</p>
]]></content:encoded>
			<wfw:commentRss>http://ruido-blanco.net/blog/archivos/2008/07/11/wet-floor-se-renueva/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Como hacerte tu propio Muxtape.app</title>
		<link>http://ruido-blanco.net/blog/archivos/2008/06/28/como-hacerte-tu-propio-muxtapeapp/</link>
		<comments>http://ruido-blanco.net/blog/archivos/2008/06/28/como-hacerte-tu-propio-muxtapeapp/#comments</comments>
		<pubDate>Sat, 28 Jun 2008 16:01:13 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
		
		<category><![CDATA[Internet]]></category>

		<category><![CDATA[Programación]]></category>

		<guid isPermaLink="false">http://ruido-blanco.net/blog/archivos/2008/06/28/como-hacerte-tu-propio-muxtapeapp/</guid>
		<description><![CDATA[Muxtape nació hace solo unos meses, pero empieza a ser el sitio de año para muchas personas. La idea es simple: te registras, subes hasta 12 MP3, les das un título y compartes la lista con tus amigos. ¡Es como si los sueños de Rob, Todd y Barry se volvieran Web 2.0!

La interfaz minimalista de [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://muxtape.com" title="Muxtape">Muxtape</a> nació hace solo unos meses, pero empieza a ser el sitio de año para muchas personas. La idea es simple: te registras, subes hasta 12 MP3, les das un título y compartes la lista con tus amigos. ¡Es como si los sueños de Rob, Todd y Barry se volvieran Web 2.0!</p>

<p>La interfaz minimalista de Muxtape funciona perfectamente, pero a veces se echan de menos características de las verdaderas aplicaciones de usuario. Por suerte tenemos <a href="http://fluidapp.com" title="Fluid - Free Site Specific Browser for Mac OS X Leopard">Fluid</a>.</p>

<p>Lo primer es descargar <a href="http://fluidapp.com" title="Fluid - Free Site Specific Browser for Mac OS X Leopard">Fluid</a> de su página web, e instalarlo en nuestra carpeta de Aplicaciones. Cuando lo abrimos Fluid nos presenta una ventana donde debemos introducir ciertos datos.</p>

<dl>
<dt>URL</dt>
<dd><code>http://muxtape.com</code></dd>

<dt>Name</dt>
<dd>muxtape (aunque cualquier cosa valdría)</dd>

<dt>Location</dt>
<dd>Aplicaciones (o donde prefiráis)</dd>

<dt>Icon</dt>
<dd>Recomiendo descargar el icono de la cinta de <a href="http://www.cocoagrove.com/" title="Cocoa Grove | The icon Grove" onclick="javascript:pageTracker._trackPageview ('/outbound/www.cocoagrove.com');">Cocoa Grove</a>, y utilizar uno de los colores proporcionados (utilizad la versión con extensión <code>.icns</code> para mejores resultados)</dd>
</dl>

<p>Cuando le demos &#8220;Create&#8221; nos creará la aplicación muxtape en el lugar donde le hemos pedido y nos ofrecerá abrirla. Una vez abierta la aplicación mostrará la página de inicio de Muxtape igual que se vería en Safari. Un pequeño &#8220;secreto&#8221;: se puede sacar una barra de herramientas y una barra de direcciones con el &#8220;botón-pastilla&#8221; de la parte superior derecha de la ventana (recuerda volver a picharlo para ocultarla cuando no la vayas a utilizar).</p>

<p>Lo primero que vamos a hacer es instalar un <em>UserScript</em> que nos ofrezca información sobre el MP3 que suena a través de <a href="http://growl.info/" title="Growl">Growl</a>. Para ello abriremos el menú con el icono de un papiro y pincharemos en &#8220;Browse Userscripts.org&#8230;&#8221;. En la barra de direcciones introduce <code><a href="http://userscripts.org/scripts/show/25591" title="Muxtape UserScript" onclick="javascript:pageTracker._trackPageview ('/outbound/userscripts.org');">http://userscripts.org/scripts/show/25591</a></code> y pincha en el botón &#8220;Install this script&#8221;.</p>

<p>Ahora vamos a instalar un <em>UserScript</em> que he hecho para añadir tres elementos al menú del icono del Dock para poder reproducir/pausar, saltar a la siguiente y saltar a la anterior canción sin tener que ver la ventana. La dirección es
<code><a href="http://userscripts.org/scripts/show/29284" title="Muxtapekeys UserScript" onclick="javascript:pageTracker._trackPageview ('/outbound/userscripts.org');">http://userscripts.org/scripts/show/29284</a></code>.</p>

<p>Si recargamos la página y vamos a una <em>muxtape</em> (por ejemplo podéis probar <a href="http://yonosoytu.muxtape.com" title="Tom Waits ate my dog for breakfast">Tom Waits ate my dog for breakfast</a>, os la recomiendo) podremos ver en el menú contextual del icono del Dock tres entradas para controlar la reproducción. Y gracias al otro <em>script</em> al comenzar la reproducción de un MP3 aparecerá un aviso de Growl y se verá en el <em>badge</em> de icono el número de pista actual. Solo le veo un problema a mi <em>script</em> y es que no puedes ocultar la ventana, ya que en el momento en que la ocultes las entradas del menú desaparecen (creo que es problema de Fluid).</p>

<p>Desconozco el estado actual de <a href="http://wiki.mozilla.org/Prism" title="Prism - MozillaWiki">Prism</a>, pero no creo que fuera difícil adaptar estas soluciones para ese sistema u otro sistema de generación de <em>Site Specific Browsers</em>.</p>

<p><strong>Nota:</strong> Algunas de las ideas de esta entrada las encontré en <a href="http://internetjogging.com/2008/04/26/pimp-my-muxtape-ssb/" title="Pimp My Muxtape (SSB)">Pimp My Muxtape (SSB)</a> y <a href="http://internetjogging.com/2008/04/17/23/" title="Muxtape With Coverflow Using Fluid">Muxtape With Coverflow Using Fluid</a>.</p>

<p><strong>Actualización (2008-06-30):</strong> Esta mañana me he dado cuenta de que tanto mi <em>script</em> como el que recomendaba han dejado de funcionar porque el tipo que hace Muxtape ha cambiando su propio JavaScript. Creo que tengo el modo de volver a ponerlo a funcionar, pero tengo que probarlo. Espero tener una versión funcional pronto.</p>

<p><strong>Actualización (2008-06-30):</strong> Si volveís a descargar volverán a funcionar los elementos del menú. Era más sencillo de lo que pensaba.</p>

<p><strong>Actualización (2008-06-30):</strong> Cuando he terminado de pulir un <em>script</em> para las funcionalidades de mostrar el aviso de Growl y la cuenta de canciones en el Dock, me he puesto a escribir un correo al autor original por si quería utilizarlo. Inmediatamente he recibido un correo que acababa él mismo de publicar una nueva versión <img src='http://ruido-blanco.net/blog/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> <a href="http://userscripts.org/scripts/show/25591" title="Muxtape 2.0 - Userscripts.org">Su versión</a> y <a href="http://ruido-blanco.net/descargas/muxtapenotifier.user.js" title="Muxtape Notifier">la mía</a> (la mía es mejor, no utiliza espera activa :D).</p>
]]></content:encoded>
			<wfw:commentRss>http://ruido-blanco.net/blog/archivos/2008/06/28/como-hacerte-tu-propio-muxtapeapp/feed/</wfw:commentRss>
		</item>
		<item>
		<title>El nuevo about:robots de Firefox 3</title>
		<link>http://ruido-blanco.net/blog/archivos/2008/06/15/el-nuevo-aboutrobots-de-firefox-3/</link>
		<comments>http://ruido-blanco.net/blog/archivos/2008/06/15/el-nuevo-aboutrobots-de-firefox-3/#comments</comments>
		<pubDate>Sun, 15 Jun 2008 10:09:12 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
		
		<category><![CDATA[Internet]]></category>

		<guid isPermaLink="false">http://ruido-blanco.net/blog/archivos/2008/06/15/el-nuevo-aboutrobots-de-firefox-3/</guid>
		<description><![CDATA[En las betas de Firefox 3 (la versión final se la espera para el 17 de Junio) existe un nuevo easter egg cuando se teclea about:robots en la barra de direcciones. Aparece una página bastante curiosa con unas cuantas frases, que el equipo de traducción de Firefox se ha encargado incluso de traducir.

¿De donde vienen [...]]]></description>
			<content:encoded><![CDATA[<p>En las betas de Firefox 3 (la versión final se la espera para el 17 de Junio) existe un nuevo <em>easter egg</em> cuando se teclea <a href="about:robots" title="¡Bienvenidos, humanos!">about:robots</a> en la barra de direcciones. Aparece una página bastante curiosa con unas cuantas frases, que el equipo de traducción de Firefox se ha encargado incluso de traducir.</p>

<p>¿De donde vienen esas frases?</p>

<dl>
<dt>¡Bienvenidos, humanos!</dt>
<dd>Inspirada por <a href="http://spanish.imdb.com/title/tt0074812/" title="Logan's Run (1976) en IMDb" onclick="javascript:pageTracker._trackPageview ('/outbound/spanish.imdb.com');">Logan&#8217;s Run</a>.</dd>

<dt>¡Venimos a visitaros en son de paz y con buena voluntad!</dt>
<dd>Inspirada por <a href="http://www.imdb.com/title/tt0043456/" title="The Day The Earth Stood Still (1951) en IMDb" onclick="javascript:pageTracker._trackPageview ('/outbound/www.imdb.com');">The Day the Earth Stood Still</a>.</dd>

<dt>Un robot no debe dañar a un ser humano o, por su inacción, dejar que un ser humano sufra daño.</dt>
<dd>Inspirada por la <a href="http://es.wikipedia.org/wiki/Leyes_de_la_rob%C3%B3tica" title="Tres leyes de la robótica en la Wikipedia en español" onclick="javascript:pageTracker._trackPageview ('/outbound/es.wikipedia.org');">Primera Ley de la Robótica</a>.</dd>

<dt>Los robots han visto cosas que vosotros no creeríais.</dt>
<dd>Inspirada por el dialogo final de Roy Batty en <a href="http://www.imdb.com/title/tt0083658/" title="Blade Runner (1982) en IMDb" onclick="javascript:pageTracker._trackPageview ('/outbound/www.imdb.com');">Blade Runner</a>.</dd>

<dt>Los robots son sus amigos de plástico con quien les gustará estar.</dt>
<dd>Inspirada en el <em>motto</em> de la compañia Sirius Cybernetics Corporation de la serie de novelas <a href="http://es.wikipedia.org/wiki/Gu%C3%ADa_del_autoestopista_gal%C3%A1ctico" title="Guí del Autoestopista Galáctico en la Wikipedia en español" onclick="javascript:pageTracker._trackPageview ('/outbound/es.wikipedia.org');">Guía del Autoestopista Galáctico</a>.</dd>

<dt>Los robots tienen brillantes culos metálicos que no deben ser chupados.</dt>
<dd>Inspirada en la frase más dicha por Bender en <a href="http://www.imdb.com/title/tt0149460/" title="Futurama (1999) en IMDb" onclick="javascript:pageTracker._trackPageview ('/outbound/www.imdb.com');">Futurama</a>.</dd>

<dt>&#8230;Y tienen un plan.</dt>
<dd>Inspirada en las frases al comienzo de <a href="http://www.imdb.com/title/tt0407362/" title="Battlestar Galactica (2004) en IMDb" onclick="javascript:pageTracker._trackPageview ('/outbound/www.imdb.com');">Battlestar Galactica</a>.</dd>

<dt>Por favor, no pulse este botón otra vez</dt>
<dd>Inspirada, de nuevo, en <a href="http://es.wikipedia.org/wiki/Gu%C3%ADa_del_autoestopista_gal%C3%A1ctico" title="Guí del Autoestopista Galáctico en la Wikipedia en español" onclick="javascript:pageTracker._trackPageview ('/outbound/es.wikipedia.org');">Guía del Autoestopista Galáctico</a> (aparece al utilizar el botón &#8220;Reintentar&#8221;).</dd>

<dt>Jodidas tostadoras</dt>
<dd>Un <em>lost in translation</em> (aunque también en la serie al emitirse en español) inspirada, de nuevo, en <a href="http://www.imdb.com/title/tt0407362/" title="Battlestar Galactica (2004) en IMDb" onclick="javascript:pageTracker._trackPageview ('/outbound/www.imdb.com');">Battlestar Galactica</a> (no aparece en las últimas versiones de la página, pero está ahí).</dd>
</dl>

<p>El único texto de la página que parece no ser una referencia &#8220;clara&#8221; es el &#8220;Reintentar&#8221; que muestra el botón por primera vez.</p>

<p>Como curiosidad, en la versión en inglés de la página, el <code>title</code> es &#8220;Gort! Klaatu barada nikto!&#8221;, otra referencia a <a href="http://www.imdb.com/title/tt0043456/" title="The Day The Earth Stood Still (1951) en IMDb" onclick="javascript:pageTracker._trackPageview ('/outbound/www.imdb.com');">The Day the Earth Stood Still</a>, pero desconozco porque la traducción al español la ha eliminado y cambiado por &#8220;¡Bienvenidos, humanos!&#8221;.</p>
]]></content:encoded>
			<wfw:commentRss>http://ruido-blanco.net/blog/archivos/2008/06/15/el-nuevo-aboutrobots-de-firefox-3/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Invitaciones DreamHost: por si a alguien le interesa</title>
		<link>http://ruido-blanco.net/blog/archivos/2008/06/10/invitaciones-dreamhost-por-si-a-alguien-le-interesa/</link>
		<comments>http://ruido-blanco.net/blog/archivos/2008/06/10/invitaciones-dreamhost-por-si-a-alguien-le-interesa/#comments</comments>
		<pubDate>Tue, 10 Jun 2008 21:42:15 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
		
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://ruido-blanco.net/blog/archivos/2008/06/10/invitaciones-dreamhost-por-si-a-alguien-le-interesa/</guid>
		<description><![CDATA[Mi amable hosting me ha enviado un correo diciendome que tengo 5 &#8220;invitaciones&#8221; para repartir que proporcionan ciertas ventajas a quienes las utilicen:


4 veces más disco y transferencia (es decir, 2TB y 20TB)
$150 de descuento en los planes a 5 años
$200 de descuento en los planes a 10 años


Full disclosure: como &#8220;referidos&#8221; míos, yo recibo [...]]]></description>
			<content:encoded><![CDATA[<p>Mi <a href="http://www.dreamhost.com/r.cgi?207443" title="DreamHost">amable <em>hosting</em></a> me ha enviado un correo diciendome que tengo 5 &#8220;invitaciones&#8221; para repartir que proporcionan ciertas ventajas a quienes las utilicen:</p>

<ul>
<li>4 veces más disco y transferencia (es decir, 2TB y 20TB)</li>
<li>$150 de descuento en los planes a 5 años</li>
<li>$200 de descuento en los planes a 10 años</li>
</ul>

<p><em>Full disclosure</em>: como &#8220;referidos&#8221; míos, yo recibo $97 de descuento en mis próximos pagos por cada una de las invitaciones que se utilicen (mi única razón para poner esto aquí).</p>

<p>La verdad es que &#8220;atarse&#8221; con un <em>hosting</em> a 5 o 10 años es un poco duro, y el caramelo &#8220;extra&#8221; del disco duro y la transferencia… &#8220;creo que 640 KB serán suficientes para cualquiera&#8221;. Pero si alguien quiere los códigos que deje un comentario con un correo en el campo de correo electrónico, <strong>no</strong> en el cuerpo (aviso que no se lo daré a los primeros que pasen, si es que pasa alguien, pero si eres una buena persona no deberías tener problemas en recibir una invitación).</p>

<p>Y para finalizar, las invitaciones se terminan dentro de &#8220;2 semanas&#8221;, así que supongo que el 24 de Junio dejarán de ser válidas (obviamente dejaré abiertos los comentarios, porque la cantidad de comentarios divertidos que puedo recibir después del plazo es algo que no me quiero perder :)).</p>
]]></content:encoded>
			<wfw:commentRss>http://ruido-blanco.net/blog/archivos/2008/06/10/invitaciones-dreamhost-por-si-a-alguien-le-interesa/feed/</wfw:commentRss>
		</item>
		<item>
		<title>TODO: Buscar un título para esta entrada</title>
		<link>http://ruido-blanco.net/blog/archivos/2008/06/05/todo-buscar-un-titulo-para-esta-entrada/</link>
		<comments>http://ruido-blanco.net/blog/archivos/2008/06/05/todo-buscar-un-titulo-para-esta-entrada/#comments</comments>
		<pubDate>Thu, 05 Jun 2008 09:17:52 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
		
		<category><![CDATA[Programación]]></category>

		<guid isPermaLink="false">http://ruido-blanco.net/blog/archivos/2008/06/05/todo-buscar-un-titulo-para-esta-entrada/</guid>
		<description><![CDATA[TextMate es un gran editor para Mac que tiene pequeños detalles increíbles escondidos, principalmente entre sus &#8220;Bundles&rlquo;.

Uno de esos Bundles increíbles es TODO, que con un simple &#x2303;&#x21E7;T (quizá la gente de Windows no vea esos caracteres, pero como no van a poder utilizar el editor&#8230;) te muestra un lista de archivos donde aparecen ciertos [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://macromates.com" title="TextMate &mdash; The Missing Editor for Mac OS X">TextMate</a> es un gran editor para Mac que tiene pequeños detalles increíbles escondidos, principalmente entre sus &ldquo;Bundles&rlquo;.</p>

<p>Uno de esos Bundles increíbles es TODO, que con un simple &#x2303;&#x21E7;T (quizá la gente de Windows no vea esos caracteres, pero como no van a poder utilizar el editor&#8230;) te muestra un lista de archivos donde aparecen ciertos comentarios &ldquo;estándares&rdquo; (<code>TODO</code>, <code>FIXME</code>, <code>CHANGE</code>) con enlaces a la línea donde se encuentran.</p>

<p>Además dispone de una pequeña ventana de preferencias donde se pueden crear más &ldquo;etiquetas&rdquot; y editar las existentes. Personalmente me gusta editarlas un poco, porque, por defecto, no funcionan como deberían.</p>

<table class="SimpleBlueHeader">
  <thead>
    <tr>
      <th>Etiqueta</th>
      <th>RegEx original</th>
      <th>RegEx modificada</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>TODO</td>
      <td><code>/TODO[\s,:]+(\S.*)$/i</code></td>
      <td><code>/\bTODO[\s,:]+(\S.*)$/i</code></td>
    </tr>
    <tr>
      <td>FIXME</td>
      <td><code>/FIX ?ME[\s,:]+(\S.*)$/i</code></td>
      <td><code>/\bFIX ?(?:ME)?[\s,:]+(\S.*)$/i</code></td>
    </tr>
    <tr>
      <td>CHANGED</td>
      <td><code>/CHANGED[\s,:]+(\S.*)$/</code></td>
      <td><code>/\bCHANGED[\s,:]+(\S.*)$/</code></td>
    </tr>
  </tbody>
</table>

<p>En el caso de &ldquo;TODO&rdquo; y &ldquo;CHANGED&rdquo; obligo a que deltante de la etiqueta exista un &ldquo;límite de palabra&rdquo; (<em>word bounduary</em>, el símbolo <code>\b</code>). En &ldquo;FIXME&rdquo;, además, permito que el &ldquo;ME&rdquo; final no sea necesario (hay que introducirlo en unos paréntesis de no-captura, la primera captura la utiliza el Bundle para mostrar el comentario asociado). Las &ldquo;i&rdquo; al final de las expresiones regulares hacen que no se tengan en cuenta la capitalización de las letras, se pueden quitar al gusto del usuario.</p>

<p>Por desgracia, al menos para mí, con el Ruby por defecto de Leopard esas
expresiones no funcionan para palabras como &ldquo;método&rdquo; en archivos codificados en UTF-8.</p>

<p>La única solución que he encontrado para arreglarlo es descargarse el Bundle del <a href="http://macromates.com/svn/Bundles/trunk" title="Repositorio de Bundles de TextMate">repositorio de Subversion</a> e incluir una única línea en un archivo:</p>

<p><code class="block bash">
$ cd ~/Library/Application\ Support/TextMate/Bundles<br />
$ svn co http://macromates.com/svn/Bundles/trunk/Bundles/TODO.tmbundle<br />
$ mate TODO.tmbundle/Support/todo.rb<br />
</code></p>

<p>Incluir justo debajo de la línea que dice <code>#!/usr/bin/env ruby</code> otra línea que diga <code>$KCODE = &apos;UTF8&apos;</code>. Salvar y reiniciar TextMate. Todo debería funcionar correctamente (bueno&#8230; excepto si pones precisamente &ldquo;todo&rdquo; en tu archivo, ver el comentario sobre las &ldquo;i&rdquo; más arriba).</p>

<p><acronym title="Post Data">PD</acronym>: El Bundle necesita amor desesperadamente, con un vistazo rápido al código, creo que cada archivo del proyecto se abre (y cierra) una vez por cada &ldquo;etiqueta&rdquo; definida. ¿Voluntarios?</p>
]]></content:encoded>
			<wfw:commentRss>http://ruido-blanco.net/blog/archivos/2008/06/05/todo-buscar-un-titulo-para-esta-entrada/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Ruby: primos y un primo</title>
		<link>http://ruido-blanco.net/blog/archivos/2008/06/03/ruby-primos-y-un-primo/</link>
		<comments>http://ruido-blanco.net/blog/archivos/2008/06/03/ruby-primos-y-un-primo/#comments</comments>
		<pubDate>Tue, 03 Jun 2008 08:24:33 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
		
		<category><![CDATA[Programación]]></category>

		<guid isPermaLink="false">http://ruido-blanco.net/blog/archivos/2008/06/03/ruby-primos-y-un-primo/</guid>
		<description><![CDATA[Siempre dicen que no hay mal que por bien no venga.

Anoche se publicaba el cuarto (y parece ser que último) problema del Google Treasure Hunt 2008 (el cuarto aún está en &#8220;competición&#8221;, pero se pueden realizar los otros tres anteriores), a eso de la 1.15 de la madrugada por estos lares&#8230; y ahí estaba yo [...]]]></description>
			<content:encoded><![CDATA[<p>Siempre dicen que no hay mal que por bien no venga.</p>

<p>Anoche se publicaba el cuarto (y parece ser que último) problema del <a href="http://treasurehunt.appspot.com" title="Google Treasure Hunt 2008">Google Treasure Hunt 2008</a> (el cuarto aún está en &#8220;competición&#8221;, pero se pueden realizar los otros tres anteriores), a eso de la 1.15 de la madrugada por estos lares&#8230; y ahí estaba yo (medio dormido, medio despierto) intentando solucionar el dichoso problema. Con lo sencillo que había sido el tercero, si estaba recargando la página cerca de la hora tenía oportunidades de ser el primero en solucionarlo.</p>

<p>Desgraciadamente, cuando me pusieron el problema delante, me dije a mi mismo que &#8220;primero ni de coña&#8221;. Y eso a pesar de que la solución <em>naïve</em> parece haber sido la más rápida. Pero no voy a poner aquí la solución, aunque puedo ofrecer herramientas para conseguirlo (y explicar mi error).</p>

<p>Ruby dispone de una clase <a href="http://ruby-doc.org/stdlib/libdoc/mathn/rdoc/classes/Prime.html" title="Documentación de Prime"><code>Prime</code></a> (<code>require 'mathn'</code>) como parte de su librería estándar, aunque para desgracia de sus usuarios viene en el mismo archivo que el módulo <a href="http://ruby-doc.org/stdlib/libdoc/mathn/rdoc/classes/Rational.html" title="Documentación de Rational"><code>Rational</code></a>, que modifica el comportamiento de los enteros de una forma no siempre deseable.</p>

<p>Para realizar algunos problemas de <a href="http://projecteuler.net/" title="Project Euler">Project Euler</a> (que tengo un poco abandonado) era deseable tener disponible la clase que genere primos y no me tocase el funcionamiento &#8220;normal&#8221; de los enteros. Por eso la extraje a su propio archivo el código de la clase <code>Prime</code> (con algunos métodos matemáticos más, como un factorial y un binomial eficientes). Sin embargo el código de <code>Prime</code> en las versiones 1.8.x de Ruby es muy poco eficiente, pero por suerte en la versión 1.9 se le ha realizado una limpieza de cara (aunque extrañamente no ha sido <em>backporteado</em> a la reciente 1.8.7).</p>

<p>Sin embargo a la clase <code>Prime</code> de Ruby (incluso a la versión 1.9) le falta un método importante: <code>prime?</code>, para conocer si un número dado es primo o no. Después de buscar un poco encontré que el <a href="http://en.wikipedia.org/wiki/Miller-Rabin_primality_test" title="Miller-Rabin primality test en la Wikipedia">método comprobación de la de Miller-Rabin</a> es un buen algoritmo para comprobar si un número es primo o no (además parece bastante eficiente). La única pega es que el método devuelve si el número es &#8220;probablemente primo&#8221; y que puede proporcionar falsos positivos, aunque si entiendo bien de <a href="http://mathworld.wolfram.com/Rabin-MillerStrongPseudoprimeTest.html" title="Rabin-Miller Strong Pseudoprime Test from Wolfram MathWorld">las explicaciones de la página de MathWorld</a> los resultados son correctos hasta números alrededor del 3,4×10<sup>14</sup> (lo que no está nada mal). De cualquier forma se puede modificar la probabilidad cuando se invoca al método, aunque pasar de <code>t = 7</code> parece no tener beneficios evidentes.</p>

<p>Podéis <a href="http://ruido-blanco.net/descargas/primes.rbs" title="primes.rbs">descargar el código de <code>primes.rb</code></a>.</p>

<p>Y ahora mi error (realmente estúpido), que ha hecho que en vez de llegar a la solución anoche, llegase esta mañana.</p>

<p>La idea que necesitáis conocer es que llevaba cuenta de unos índices de final y de comienzo, que determinaban que primos participaban en la suma. Estos índices iban aumentando de uno en uno, haciendo que una &#8220;ventana&#8221; se moviese sobre los primos conocidos. Cuando tocaba avanzar la ventana, la idea era que se eliminaba el primer primo y se incluía el siguiente.</p>

<p>Encontrad las &#8220;siete&#8221; diferencias:</p>

<p><code class="block ruby">
p = Prime.new<br />
&#35; &#46;&#46;&#46;<br />
<br />
&#35; Versión incorrecta<br />
suma += Prime.primes[final] - Prime.primes[inicio]<br />
inicio += 1<br />
final += 1<br />
p.succ while Prime.primes.length &lt; final+1<br />
<br />
&#35; Versión correcta<br />
final += 1<br />
p.succ while Prime.primes.length &lt; final+1<br />
suma += Prime.primes[final] - Prime.primes[inicio]<br />
inicio += 1<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://ruido-blanco.net/blog/archivos/2008/06/03/ruby-primos-y-un-primo/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
