<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="es-ES"><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://www.luismayoral.com/atom.xml" rel="self" type="application/atom+xml" /><link href="https://www.luismayoral.com/" rel="alternate" type="text/html" hreflang="es-ES" /><updated>2025-11-10T07:04:06+01:00</updated><id>https://www.luismayoral.com/atom.xml</id><title type="html">Luis Mayoral</title><subtitle>Desarrollador. Marido. Padre. Fotógrafo. Audiófilo. Y de vez en cuando, una persona normal.</subtitle><author><name>Luis Mayoral</name><email>luis@luismayoral.com</email></author><entry><title type="html">Let’s rock again</title><link href="https://www.luismayoral.com/bitacora/2019/08/lets-rock-again" rel="alternate" type="text/html" title="Let’s rock again" /><published>2019-08-28T00:00:00+02:00</published><updated>2019-08-28T00:00:00+02:00</updated><id>https://www.luismayoral.com/bitacora/2019/08/lets-rock-again</id><content type="html" xml:base="https://www.luismayoral.com/bitacora/2019/08/lets-rock-again"><![CDATA[<p>Hace diecisiete años, allá por enero de 2002, publicaba una entrada de titulada <a href="/bitacora/2002/01/lets-rock">“Let’s rock”</a>. Esa entrada daba comienzo a mi andadura por el mundo de las bitácoras.</p>

<p>El título de esta entrada, homenaje a aquella primera, se debe a que sin prisa pero sin pausa estoy recuperando a través de diversos medios
(web.archive.org, copias de seguridad, etc) todas las entradas que he tenido en las diversas versiones de mi bitácora a lo largo de todos estos años.
Una vez estén todas adaptadas al formato de Jekyll publicaré una selección de ellas por aquí.</p>

<p>La primera bitácora que tuve se llamaba <em>“Diario de un debianita”</em> y tenía de subtítulo <em>“Pensamientos y rayadas mentales de un linuxero cualquiera”</em>. A lo largo de
su historia, y de las posteriores versiones de mi bitácora, ha habido más <em>rayadas mentales</em> que <em>pensamientos</em>, pero hay algo que me pide volver a juntarlo todo, a
sabiendas de que no hay grandes joyas dignas de conservarse.</p>

<p>Esta labor arqueológica se puede resumir en dos motivos. Por un lado, me sirve para recordar en un mismo sitio cosas que hacía mejor o peor en el pasado, seguir
aprendiendo de esas vivencias, y seguir mejorando como profesional y como persona.</p>

<p>Por otro lado, y realmente la razón principal de todo esto, es mi hijo. En el momento que escribo estas líneas tiene tres meses, pero me gustaría que el día de
mañana pudiera encontrar aquí un verdadero “cuaderno de bitácora” de su padre.</p>

<p>Aquí podrá leer sucesos de mayor o menor importancia de mi vida, y como los viví. Encontrará también decisiones que tomé, y en algunos casos incluso las consecuencias
positivas o negativas que pudieron tener. De alguna que otra historia que le contaré por aquí podrá encontrar un complemento para comprenderlas mejor.</p>

<p>Espero que con las charlas que tendremos a lo largo de los años y las posibles lecturas que pueda hacer de todo esto sea capaz de aprender de mis errores para no cometerlos él. O
que pueda ver que la pasión de su padre por lo que hace, por cómo disfruta de la música, del cine o de la lectura viene de muy atrás. Y con suerte transmitirle ese
gusanillo.</p>

<p>Si las historias aquí contadas han sido capaces de sobrevivir diecisiete años conseguiremos que sobrevivan al menos otros diecisiete más, no creéis? :)</p>]]></content><author><name>Luis Mayoral</name><email>luis@luismayoral.com</email></author><category term="Personal" /><summary type="html"><![CDATA[Sin prisa pero sin pausa estoy recuperando a través de diversos medios (web.archive.org, copias de seguridad, etc) todas las entradas que he tenido en las diversas versiones de mi bitácora a lo largo de estos últimos 17 años.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://www.luismayoral.com/images/2019/08/lets-rock-again.jpg" /><media:content medium="image" url="https://www.luismayoral.com/images/2019/08/lets-rock-again.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Hola de nuevo, Jekyll</title><link href="https://www.luismayoral.com/bitacora/2018/06/hola-de-nuevo-jekyll" rel="alternate" type="text/html" title="Hola de nuevo, Jekyll" /><published>2018-06-05T00:00:00+02:00</published><updated>2018-06-05T00:00:00+02:00</updated><id>https://www.luismayoral.com/bitacora/2018/06/hola-de-nuevo-jekyll</id><content type="html" xml:base="https://www.luismayoral.com/bitacora/2018/06/hola-de-nuevo-jekyll"><![CDATA[<p>Los viejos del lugar (unos santos) ya están acostumbrados a que cada par de años a lo máximo acabe cambiando de arriba a abajo esta página.</p>

<p>Ha pasado por gestores de contenidos de desarrollo propio (uno de ellos en PHP hace muchos años, otro más recientemente en Ruby on Rails). Ha pasado por gestores de contenido ajenos (así que recuerde, y limitando el listado a aquellos en los que la prueba durase más de una semana, Movable Type, Joomla, PHP-Nuke, Nucleus y Drupal). También por generadores estáticos, como Jekyll y Octopress. Y hasta hace unos días, Wordpress.</p>

<h2 id="por-qué-abandono-wordpress">¿Por qué abandono Wordpress?</h2>

<p>Tengo mucho respeto a PHP. Aunque ya llevaba años desarrollando aplicaciones de escritorio, mi salto al desarrollo web se produjo en 2001, y el primer lenguaje que usé fue precisamente PHP. Desde muy temprano aprendí la potencia y la gran flexibilidad que tiene. Y es esto último, la flexibilidad, lo que considero una de sus mayores defectos.</p>

<p>Una página en PHP puede ser algo tan simple como meter código dentro de una etiqueta <code class="language-plaintext highlighter-rouge">&lt;?php ?&gt;</code> en mitad de un HTML normal y corriente:</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;!DOCTYPE html&gt;</span>
<span class="nt">&lt;html&gt;</span>
  <span class="nt">&lt;body&gt;</span>
    <span class="nt">&lt;h1&gt;</span>Mi primera página en PHP<span class="nt">&lt;/h1&gt;</span>

    <span class="nt">&lt;p&gt;</span>
      <span class="cp">&lt;?php</span> <span class="k">echo</span> <span class="s2">"¡Hola mundo!"</span><span class="p">;</span> <span class="cp">?&gt;</span>
    <span class="nt">&lt;/p&gt;</span>
  <span class="nt">&lt;/body&gt;</span>
<span class="nt">&lt;/html&gt;</span>
</code></pre></div></div>

<p>Si andas dando tus primeros pasos en la programación, solo sabes programación procedural, pero lo anterior te parece un horror y lo quieres hacer mejor, no hay problema. Puedes tener ficheros de código PHP que generen el HTML a partir de plantillas, usando algún motor de plantillas tipo Smarty.</p>

<p>Si quieres hacer las cosas bien, con programación orientado a objetos, PHP sigue siendo tu lenguaje. Puedes desatar toda su potencia con frameworks maravillosamente construidos, como Zend, o cosas más del estilo de Rails, como puede ser Symfony.</p>

<p>Básicamente, depende de ti hacer un código PHP maravilloso o hacer una gran basura.</p>

<p>Si alguna vez te da por curiosear el código de Wordpress, te encontrarías las tres cosas anteriores. Páginas HTML con algún que otro fragmento en PHP. Ficheros PHP totalmente procedurales.  Clases en PHP muy bien construidas. No hay una arquitectura claramente definida. La cosa empeora cuando empiezas a añadir plugins de terceros. Si el código de Wordpress puede llegar a dar miedo, el de los plugins, en líneas generales, aterroriza.</p>

<p>Wordpress es todo lo contrario a lo que yo entiendo y defiendo como software bien desarrollado. Nunca me he sentido cómodo usándolo. No me consolaba para nada pensar que es uno de los proyectos de software más usados del mundo.</p>

<p>Mucho tendría que cambiar en el futuro para que volviese a usarlo.</p>

<h2 id="la-alternativa-medium">La alternativa: Medium</h2>

<p>Me encanta Medium. Desde hace tiempo pienso que es una de las experiencias de escritura mejor conseguidas. Y en cuestión de lectura también tiene una experiencia de lo más cuidada. Las herramientas para poder subrayar o comentar el contenido son una delicia. Si conectas tu cuenta de Twitter o Facebook con el servicio, puedes seguir de forma automática en Medium a aquellas personas que ya seguías en otras redes.</p>

<p>Pero también tiene sus contras. Como cualquier empresa, Medium busca la manera de generar dinero. Dentro de esa búsqueda, lanzó hace un tiempo un modelo de suscripción de 5$ al mes para pagar a los autores. Estas suscripciones tenían como intención el evitar meter anuncios en la plataforma. Junto a esto, para determinar qué autores se merecían más cobrar parte de ese dinero, añadieron los aplausos. Y con esto se empezó a torcer todo.</p>

<p>Sobre el papel, si yo soy suscriptor y a lo largo de un mes aplaudo una vez a cinco historias de distintos autores, estaré dando 1$ a cada uno de ellos. Si hago 250 aplausos a distintos autores, literalmente estaré dándoles dos céntimos a cada uno. También puedo aplaudir varias veces al mismo, o no aplaudir. En este último caso se repartiría entre los más populares de la plataforma, aunque yo no haya leído nada de ellos.</p>

<p>Esto ha convertido Medium en una búsqueda constante de los aplausos fáciles. Si no recibes aplausos, no se te destaca. Si no se te destaca, es muy complicado que te visiten. Si no te visitan, no existes.</p>

<p>Medium ofrece a los no suscriptores el poder leer hasta tres historias exclusivas de suscriptores al mes. Al principio, la newsletter que Medium manda de forma periódica mostraba en un primer lugar a la gente de tu red que había publicado o le había gustado algo. A día de hoy esa newsletter es casi todo contenido para el cual necesitas estar suscrito. Si visitas la portada de Medium te ocurre lo mismo, es muy complicado localizar las historias de las personas que sigues.</p>

<p>La experiencia para la gente que no está registrada en Medium también ha empeorado. Actualmente es un bombardeo de notificaciones para que te registres y te hagas premium.</p>

<p>No quería esa experiencia para la gente que de vez en cuando para por aquí y lee lo que escribo, así que tocaba seguir buscando.</p>

<h2 id="la-vuelta-a-jekyll">La vuelta a Jekyll</h2>

<p>Como comentaba al principio de esta entrada, no es la primera vez que lo que aquí se ve está generado por Jekyll. En su momento las opciones eran utilizar GitHub Pages con un conjunto muy limitado de Jekyll, como subdominio dentro de github.io, o bien montar algún Apache o nginx en un servidor propio, construir en local el contenido de Jekyll y subirlo vía FTP o rsync al servidor. Nada complicado, pero un poco tedioso.</p>

<p>A día de hoy, GitHub Pages ha evolucionado muchísimo, soportando más plugins de Jekyll, posibilidad de utilizar dominios propios, generación automática de las páginas al hacer commit si tu sitio es compatible con Pages, y la ya tradicional publicación de la rama <code class="language-plaintext highlighter-rouge">gh-pages</code>. Aparte, han salido multitud de servicios especializados en el alojamiento de páginas estáticas, como <a href="https://www.netlify.com">Netlify</a>, que incorporan todo tipo de facilidades para proyectos Jekyll. Además desde hace ya tiempo también soporta HTTPS integrando certificados emitidos con Let’s Encrypt. Una maravilla, vamos.</p>

<h2 id="dónde-están-los-comentarios">¿Dónde están los comentarios?</h2>

<p>He estado muy tentado de volver a poner Disqus, pero de momento he preferido no hacerlo.</p>

<p>Han pasado ya unos cuantos años desde la primera vez que usé Disqus. Primero en la anterior versión Jekyll de esta web, posteriormente en la vuelta a Wordpress. Durante mucho tiempo estaba encantado con el servicio, pero poco a poco las cosas fueron cambiando dentro de Disqus haciendo que la experiencia haya ido a peor.</p>

<p>Disqus necesitaba buscar una manera de monetizar el servicio, y decidió apoyarse en un aumento de la publicidad que acompañaba a los comentarios. Aun así, a finales de 2016  quedó tocado cuando tuvo que despedir a un 20% de su plantilla, momento en el que comentaron que iban a focalizarse todavía más en servicios para publicaciones y anunciantes. Para rematar la faena, a finales de 2017 Zeta Global, una multinacional dedicada al marketing y la tecnología, adquirió Disqus. ¿Adivináis para qué?</p>

<h2 id="pero-yo-quiero-poder-comentar">¡Pero yo quiero poder comentar!</h2>

<p>Es por eso que he planteado el siguiente experimento.</p>

<p>Voy a seguir anunciando todas las cosas que publique a través de las redes sociales. Además, todas las entradas que publique por aquí serán también publicadas en <a href="https://www.medium.com/@mayoral">mi perfil de Medium</a>. Allí podrán ser anotadas, comentadas, replicadas… Lo que os apetezca.</p>

<p>Veremos cual de los dos formatos me acaba convenciendo más.</p>]]></content><author><name>Luis Mayoral</name><email>luis@luismayoral.com</email></author><category term="Opinión" /><category term="jekyll" /><summary type="html"><![CDATA[Tras un largo periodo con Wordpress, y después de haber estado evaluando diferentes alternativas (entre otras Medium), esta web vuelve a estar generada con Jekyll. Vamos a ver por qué.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://www.luismayoral.com/images/2018/06/jekyll.jpg" /><media:content medium="image" url="https://www.luismayoral.com/images/2018/06/jekyll.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Enganchado a los podcasts</title><link href="https://www.luismayoral.com/bitacora/2018/04/enganchado-a-los-podcasts" rel="alternate" type="text/html" title="Enganchado a los podcasts" /><published>2018-04-05T00:00:00+02:00</published><updated>2018-04-05T00:00:00+02:00</updated><id>https://www.luismayoral.com/bitacora/2018/04/enganchado-a-los-podcasts</id><content type="html" xml:base="https://www.luismayoral.com/bitacora/2018/04/enganchado-a-los-podcasts"><![CDATA[<p>De un tiempo a esta parte me he aficionado a los podcasts, pequeñas píldoras de audio de duración variable (algunos no llegan a los 10 minutos, otros pueden sobrepasar las dos horas) con información de los más diversos temas. Ya sea a través del ordenador, o bien a través del móvil con alguna app tipo <a href="https://overcast.fm/">Overcast</a>, cualquier momento es bueno para tener estos audios de fondo y poder mantenerse al día en aquellas áreas que nos interesan.</p>

<p>A continuación dejo enlaces de algunos de los podcasts que sigo en la actualidad. Si conocéis alguno que no está en esta lista no dudéis en compartirlo en los comentarios :)</p>

<p><strong>Tecnológicos</strong>:</p>

<ul>
  <li><a href="https://emilcar.fm/4ventanas">4 Ventanas</a>: Noticias sobre el mundo Microsoft (aplicaciones, servicios, dispositivos, etc).</li>
  <li><a href="https://cuonda.com/binarios">Binarios</a>: Tecnología en genral, con Ángel Jiménez de Luis.</li>
  <li><a href="https://www.spreaker.com/show/code-on-the-rocks_1">Code on the rocks</a></li>
  <li><a href="https://emilcar.fm/daily">Emilcar Daily</a>: Píldoras diarias de Emilcar sobre, como dice siempre al principio de cada episodio, “tecnología en general, Apple en particular, redes sociales, productividad personal y, francamente, cualquier otra cosa que me interese”.</li>
  <li><a href="https://emilcar.fm/proyectomacintosh">Proyecto Macintosh</a>: Noticias sobre el mundo Mac.</li>
  <li><a href="https://incognicast.com">Incognicast</a>: El podcast de Incognitosis, el blog de Javier Pastor.</li>
</ul>

<p><strong>Mundo “estartapil”</strong>:</p>

<ul>
  <li><a href="https://masquestartups.com">Más que startups</a>: Mis queridos Alberto Molpeceres y Gonzalo Valverde, junto con David Pombar, se dedican a entrevistar cada semana a emprendedores del ecosistema español de startups.</li>
  <li><a href="https://soundcloud.com/user-756421755">PodKast de K Fund</a>: La gente de K Fund, el fondo de venture capital más conocido de este país, traen de forma periódica a un invitado del mundo startup al que entrevistan.</li>
</ul>

<p><strong>Blockchain, criptomonedas, etc</strong>:</p>

<ul>
  <li><a href="www.getrevue.co/profile/blockchainminutes">Blockchain Minutes</a>: Raúl Marcos y Pablo Ventura acerca de todo lo relacionado con Blockchain.</li>
</ul>

<p><strong>Cine</strong>:</p>

<ul>
  <li><a href="https://www.ivoox.com/podcast-cinemascopazo_sq_f1424117_1.html">CINEMASCOPAZO</a>: Arturo González-Campos, Juan Gómez-Jurado y un invitado especial se juntan cada semana para hablar sobre cine.</li>
  <li><a href="https://www.ivoox.com/podcast-todopoderosos_sq_f1147805_1.html">Todopoderosos</a>: Arturo González-Campos, Rodrigo Cortés, Javier Cansado y Juan Gómez-Jurado se juntan para hablar de El podcast de cine, libros, series, cómics…</li>
</ul>

<p><strong>Biología y salud</strong>:</p>

<ul>
  <li><a href="https://emilcar.fm/bacteriofagos">Bacteriófagos</a>: Bacteriófagos, un podcast quincenal de curiosidades biológicas y actualidad científica para todos los públicos. Presentado por Carmela García.</li>
  <li><a href="https://emilcar.fm/nutrimatrix">Nutrimatrix</a>: Un podcast quincenal con consejos sobre nutrición y en el que desmontaremos algunos mitos sobre alimentación. Presentado por Ángela Manso.</li>
</ul>

<p><strong>Fotografía</strong>:</p>

<ul>
  <li><a href="https://emilcar.fm/granangular">Gran Angular</a>: El podcast de fotografía de la red de Emilcar, presentado por David Calaveras.</li>
  <li><a href="https://www.spreaker.com/show/f2-2-fotografia-con-fotomaf">f2.2 fotografía con fotomaf</a>: Mauro Fuentes, más conocido como fotomaf, entrevista a gente de lo más interesante en el mundo de la fotografía.</li>
</ul>

<p><strong>Viajes</strong>:</p>

<ul>
  <li><a href="www.spreaker.com/user/unminutoennuevayork">Un minuto en Nueva York</a>: Una manera distinta de conocer Nueva York.</li>
</ul>]]></content><author><name>Luis Mayoral</name><email>luis@luismayoral.com</email></author><category term="Tecnología" /><category term="podcast" /><summary type="html"><![CDATA[De un tiempo a esta parte me he aficionado a los podcasts, pequeñas píldoras de audio de duración variable (algunos no llegan a los 10 minutos, otros pueden sobrepasar las dos horas) con información de los más diversos temas. Ya sea a través del ordenador, o bien a través del móvil con alguna app tipo [Overcast](https://overcast.fm/), cualquier momento es bueno para tener estos audios de fondo y poder mantenerse al día en aquellas áreas que nos interesan.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://www.luismayoral.com/images/2018/04/podcasts.jpg" /><media:content medium="image" url="https://www.luismayoral.com/images/2018/04/podcasts.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Objetivos para la temporada 2016-2017</title><link href="https://www.luismayoral.com/bitacora/2016/08/objetivos-para-la-temporada-2016-2017" rel="alternate" type="text/html" title="Objetivos para la temporada 2016-2017" /><published>2016-08-24T00:00:00+02:00</published><updated>2016-08-24T00:00:00+02:00</updated><id>https://www.luismayoral.com/bitacora/2016/08/objetivos-para-la-temporada-2016-2017</id><content type="html" xml:base="https://www.luismayoral.com/bitacora/2016/08/objetivos-para-la-temporada-2016-2017"><![CDATA[<p>Muchas personas aprovechan el final del año para marcarse los objetivos que quieren cumplir en el año que está a punto de empezar. Otras personas sin embargo preferimos establecernos los objetivos al finalizar el verano.</p>

<p>En mi caso esto viene motivado por algo tan sencillo como que en estas fechas logro desconectar mejor que en la época navideña, donde los compromisos familiares acaban copando casi todo el tiempo que tienes. Puedo organizar mejor las ideas, hacer una revisión del año transcurrido y plantear objetivos realistas a cumplir para el año siguiente.</p>

<p>Al no tener lista de la temporada anterior voy a comentar directamente los de esta temporada que empieza. El año que viene prometo que repasaremos los objetivos plasmados en esta entrada :)</p>

<p><strong>MÁS TIEMPO PARA LA FORMACIÓN</strong>: Estos dos últimos años he ido renovando la cuenta de Code School pero no le he podido sacar todo el provecho que me hubiese gustado. Tampoco he podido dedicarle el tiempo que se merecen a varios cursos que adquirí en Udemy. Por no hablar de libros pendientes de leer. Esta temporada tengo que romper esa dinámica y asegurar un tiempo de la semana a este tema.</p>

<p><strong>DESCONECTAR MEJOR</strong>: La gran maldición para los que nos dedicamos a esta profesión. No vale como excusa que cuando se termine de desarrollar se eche uno una partida a un juego, o se ponga a editar fotos. Desconectar es desconectar, lejos del ordenador. Y en esto creo que ayudará tomarme un poco más en serio el horario… por muy bien que me lo esté pasando con lo que esté implementando en ese momento, cuando llegue la hora de terminar la jornada laboral toca pasar a otros temas.</p>

<p><strong>LEER MÁS</strong>: En este tema el Kindle está resultando ser un gran aliado. Lo puedo llevar encima durante todo el año y disponer de toda mi biblioteca digital en cualquier momento. Aunque puntualizaría este objetivo: Quiero aumentar el número de lecturas “no técnicas”. Por poner una cifra: Al menos un libro al mes, y si encima aprovecho para comentarlos por aquí, mejor que mejor.</p>

<p><strong>CUIDARSE MÁS</strong>: Al igual que con los libros aquí quiero poner una cifra, y es bajar 10 kilos. Es un objetivo que se que puedo conseguir, se de sobra qué necesito hacer para lograrlo, y su consecución está bastante relacionada con el objetivo de desconectar mejor.</p>

<p><strong>REVITALIZAR ESTA BITÁCORA</strong>: Llevo escribiendo en una bitácora, con mayor o menor regularidad, desde hace 14 años. Y sigo pensando que las bitácoras todavía tienen su público y su utilidad. Aunque no ayuda mucho a demostrarlo que ésta vaya a ser la primera entrada escrita en 2016. No me quiero marcar cifras, pero sí el propósito de al menos compartir por aquí parte del contenido que comparto por otros medios como el Slack de la empresa, Twitter, Facebook o en conversaciones privadas.</p>

<p>¿Cuales son tus objetivos para esta temporada?</p>]]></content><author><name>Luis Mayoral</name><email>luis@luismayoral.com</email></author><category term="Opinión" /><summary type="html"><![CDATA[Muchas personas aprovechan el final del año para marcarse los objetivos que quieren cumplir en el año que está a punto de empezar. Otras personas sin embargo preferimos establecernos los objetivos al finalizar el verano.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://www.luismayoral.com/images/2016/08/objetivos.jpg" /><media:content medium="image" url="https://www.luismayoral.com/images/2016/08/objetivos.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Hipervitaminando Atom</title><link href="https://www.luismayoral.com/bitacora/2015/09/hipervitaminando-atom" rel="alternate" type="text/html" title="Hipervitaminando Atom" /><published>2015-09-02T00:00:00+02:00</published><updated>2015-09-02T00:00:00+02:00</updated><id>https://www.luismayoral.com/bitacora/2015/09/hipervitaminando-atom</id><content type="html" xml:base="https://www.luismayoral.com/bitacora/2015/09/hipervitaminando-atom"><![CDATA[<p>Aunque llevo ya unos años utilizando (y siendo fan) de RubyMine para mi trabajo diario, nunca he dejado de utilizar o probar otros editores y entornos siempre que he tenido oportunidad.</p>

<p><a href="https://atom.io/">Atom</a> me llamó la atención cuando lo probé hace más de un año, poco después de su lanzamiento, pero no ha sido hasta hace unas semanas, aprovechando la excusa de que ya era una versión 1.0, cuando me he puesto a utilizarlo en serio.</p>

<h2 id="en-todas-partes">En todas partes</h2>

<p>En Atom todos los ficheros de configuración, paquetes instalados, etc residen en el directorio <code class="language-plaintext highlighter-rouge">~/.atom</code>. Podemos aprovechar esto para por ejemplo poner esta carpeta dentro de Dropbox y hacer un enlace simbólico, tal que así:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mv ~/.atom ~/Dropbox
ln -s ~/Dropbox/.atom ~/.atom
</code></pre></div></div>

<p>Luego, en el resto de equipos donde vayamos a utilizar Atom podemos hacer lo siguiente:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>rm -rf ~/.atom
ln -s ~/Dropbox/.atom ~/.atom
</code></pre></div></div>

<p>De esta manera tendremos la misma configuración de Atom en todos nuestros equipos. Cualquier paquete o tema que instalemos, cualquier opción de la configuración que cambiemos, la tendremos en todos nuestros equipos.</p>

<h2 id="paquetes-recomendados">Paquetes recomendados</h2>

<p>Estos son algunos de los paquetes que tengo instalados y que me resultan de más utilidad:</p>

<ul>
  <li><a href="https://atom.io/packages/atom-beautify">atom-beautify</a>: “Embellece” nuestro código fuente. Soporta HTML, CSS, JavaScript, PHP, Python, Ruby, Java, C, C++, C#, Objective-C, CoffeeScript, TypeScript, y SQL. Para algunos de estos lenguajes necesitarás instalar alguna aplicación de apoyo o una gema, como por ejemplo <a href="https://github.com/erniebrodeur/ruby-beautify">ruby-beautify</a> en el caso de Ruby.</li>
  <li><a href="https://atom.io/packages/color-picker">color-picker</a>: Muestra un color picker interactivo con soporte para los formatos HEX, HEXa, RGB, RGBa, HSL, HSLa, HSV, HSVa, VEC3 y VEC4, así como conversiones entre estos formatos. También soporta la inspección de colores en ficheros SASS y LESS. Imprescindible si te toca tocar hojas de estilos y ajustar colores.</li>
  <li><a href="https://atom.io/packages/editorconfig">editorconfig</a>: Dota a Atom de soporte para el estandar <a href="http://editorconfig.org/">EditorConfig</a>. Básico en proyectos donde cada uno utiliza su propio editor pero quieres asegurar que todos sigan las mismas reglas de formateo de código.</li>
  <li><a href="https://atom.io/packages/file-icons">file-icons</a>: Cambia el icono de fichero en base a las extensiones para así poder distinguir de forma bastante visual qué tipo de fichero vamos a abrir. Estético, pero muy útil.</li>
  <li><a href="https://atom.io/packages/git-plus">git-plus</a>: Implementa como acciones accesibles desde la paleta de comandos muchas de las acciones que podemos realizar desde consola con git.</li>
  <li><a href="https://atom.io/packages/linter">linter</a>: Provee de una base para soportar multitud de linters específicos de diferentes lenguajes. Por ejemplo, para Ruby yo lo uso en combinación con <a href="https://atom.io/packages/linter-rubocop">linter-rubocop</a>. Entre las diferentes opciones está la de linting sobre la marcha, o mostrar los totales de advertencias y errores por línea, fichero o proyecto.</li>
  <li><a href="https://atom.io/packages/merge-conflicts">merge-conflicts</a>: Una ayuda visual para resolver los conflictos de los merges.</li>
  <li><a href="https://atom.io/packages/minimap">minimap</a>: Añade un minimap al estilo del que tiene Sublime Text. Algunos plugins, como el propio linter, tienen soporte para mostrar más información en este minimapa.</li>
  <li><a href="https://atom.io/packages/project-manager">project-manager</a>: Permite guardar y cambiar de forma rápida entre proyectos.</li>
  <li><a href="https://atom.io/packages/recent-files-fuzzy-finder">recent-files-fuzzy-finder</a>: Mejora el fuzzy finder de Atom sugiriendo en primer lugar los ficheros de apertura más reciente, al estilo de lo que hace RubyMine.</li>
</ul>]]></content><author><name>Luis Mayoral</name><email>luis@luismayoral.com</email></author><category term="Desarrollo" /><category term="apps" /><summary type="html"><![CDATA[Muchas personas aprovechan el final del año para marcarse los objetivos que quieren cumplir en el año que está a punto de empezar. Otras personas sin embargo preferimos establecernos los objetivos al finalizar el verano.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://www.luismayoral.com/images/2015/09/atom.jpg" /><media:content medium="image" url="https://www.luismayoral.com/images/2015/09/atom.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Novedades en Rails 4.2: config_for</title><link href="https://www.luismayoral.com/bitacora/2014/10/novedades-en-Rails-4-2-config-for" rel="alternate" type="text/html" title="Novedades en Rails 4.2: config_for" /><published>2014-10-18T00:00:00+02:00</published><updated>2014-10-18T00:00:00+02:00</updated><id>https://www.luismayoral.com/bitacora/2014/10/novedades-en-Rails-4-2-config-for</id><content type="html" xml:base="https://www.luismayoral.com/bitacora/2014/10/novedades-en-Rails-4-2-config-for"><![CDATA[<p>Hasta ahora un patrón bastante común en aplicaciones Rails que necesitan de un fichero de configuración era encontrarse en el <code class="language-plaintext highlighter-rouge">config/application.rb</code> algo parecido a esto:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">require</span> <span class="s2">"ostruct"</span>
<span class="n">config_file</span> <span class="o">=</span> <span class="no">File</span><span class="p">.</span><span class="nf">join</span><span class="p">(</span><span class="s2">"config/myapp.yml"</span><span class="p">)</span>
<span class="n">config</span> <span class="o">=</span> <span class="no">YAML</span><span class="p">.</span><span class="nf">load</span><span class="p">(</span><span class="no">File</span><span class="p">.</span><span class="nf">read</span><span class="p">(</span><span class="n">config_file</span><span class="p">))[</span><span class="no">Rails</span><span class="p">.</span><span class="nf">env</span><span class="p">]</span>
<span class="no">AppConfig</span> <span class="o">=</span> <span class="no">OpenStruct</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">config</span><span class="p">)</span>
</code></pre></div></div>

<p>De esa manera podíamos usar el objeto AppConfig en toda la aplicación y así llevar a nuestros controladores o modelos algunas variables de configuración que debían cambiar dependiendo del entorno (host y puerto para Redis, número de segundos de delay que indicar a un worker Sidekiq en el perform_in, app id y secret de una API externa, etc).</p>

<p>Suele pasar en la comunidad Rails que conforme un patrón de este tipo empieza a ser muy usado acabe siendo adaptado e incorporado al propio framework. En este caso, en la versión 4.2 nos llega en la forma de <code class="language-plaintext highlighter-rouge">config_for</code>.</p>

<p>Supongamos que tenemos un fichero llamado <code class="language-plaintext highlighter-rouge">config/redis.yml</code> con el siguiente contenido:</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">development</span><span class="pi">:</span>
  <span class="na">host</span><span class="pi">:</span> <span class="s">localhost</span>
  <span class="na">port</span><span class="pi">:</span> <span class="m">6379</span>
<span class="na">test</span><span class="pi">:</span>
  <span class="na">host</span><span class="pi">:</span> <span class="s">localhost</span>
  <span class="na">port</span><span class="pi">:</span> <span class="m">6379</span>
<span class="na">production</span><span class="pi">:</span>
  <span class="na">host</span><span class="pi">:</span> <span class="s">my-production-redis-server</span>
  <span class="na">port</span><span class="pi">:</span> <span class="m">6379</span>
</code></pre></div></div>

<p>Ahora podemos hacer la siguiente llamada en la aplicación:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">&gt;</span> <span class="no">Rails</span><span class="p">.</span><span class="nf">application</span><span class="p">.</span><span class="nf">config_for</span><span class="p">(</span><span class="ss">:redis</span><span class="p">)</span>
<span class="o">=&gt;</span> <span class="p">{</span><span class="s2">"host"</span> <span class="o">=&gt;</span> <span class="s2">"localhost"</span><span class="p">,</span> <span class="s2">"port"</span> <span class="o">=&gt;</span> <span class="mi">6379</span><span class="p">}</span>
</code></pre></div></div>

<p>El valor del hash en este ejemplo dependería del entorno en el que nos encontrásemos.</p>

<p>Podéis encontrar más información acerca de <code class="language-plaintext highlighter-rouge">config_for</code> en el propio <a href="https://github.com/rails/rails/pull/16129">pull request</a> en el que se incorporó a Rails.</p>]]></content><author><name>Luis Mayoral</name><email>luis@luismayoral.com</email></author><category term="Desarrollo" /><category term="ruby" /><summary type="html"><![CDATA[Como ha hecho en muchas otras ocasiones, Rails ha adoptado y versionado un patrón bastante común en las aplicaciones Rails a la hora de gestionar la configuración de las mismas en diferentes entornos: los ficheros YML de configuración.]]></summary></entry><entry><title type="html">The coding zone</title><link href="https://www.luismayoral.com/bitacora/2014/03/the-coding-zone" rel="alternate" type="text/html" title="The coding zone" /><published>2014-03-23T00:00:00+01:00</published><updated>2014-03-23T00:00:00+01:00</updated><id>https://www.luismayoral.com/bitacora/2014/03/the-coding-zone</id><content type="html" xml:base="https://www.luismayoral.com/bitacora/2014/03/the-coding-zone"><![CDATA[<p>De un tiempo a esta parte se lleva popularizando entre las bitácoras de desarrolladores el compartir lo que cada uno define como su “coding zone”, su entorno de trabajo ideal para tener sesiones de programación lo más productivas posibles.</p>

<p>En mi caso, mi entorno ideal se compone de cuatro pilares fundamentales.</p>

<h2 id="buena-música">Buena música</h2>

<p>No lo puedo evitar, <a href="/entradas/music-rules-my-life/">me encanta la música</a>. Y a la hora de trabajar me ayuda a concentrarme en las tareas que tengo que realizar.</p>

<p>En mi caso a la hora de programar no tengo predilección en especial por géneros musicales. Lo que sí que suelo optar es mucho por la escucha de directos (El <a href="http://open.spotify.com/album/0S8mVxRM9uftA1C6dLp7ip">Alchemy</a> de Dire Straits es uno de mis favoritos).</p>

<p>No suelo optar por escuchar playlists autogeneradas por parte de iTunes o Spotify. En ambas plataformas tengo listas de varios géneros compuestas poquito a poco a lo largo de estos años que me evitan tener que perder el foco al encontrarme con una canción que no me guste.</p>

<p>Tanto estos últimos años de trabajo en remoto, como anteriormente cuando trabajaba en oficinas con más gente, unos buenos cascos siempre me han acompañado. Hay momentos en los que necesitas ese aislamiento.</p>

<h2 id="sin-interrupciones">Sin interrupciones</h2>

<p>Procuro concentrar las reuniones que tenga que mantener o a primera hora o a última. Así minimizo en gran medida el cambio de contexto que supone volver a la resolución de la tarea en la que me encuentre enfrascado en ese momento.</p>

<p>También procuro que sean lo más breves posibles. Una reunión de media hora por Skype en realidad es un tiempo de al menos una hora de programación perdida. Los 15 minutos previos a la reunión en los que estás ya pensando en la reunión más que en la tarea, la reunión propiamente dicha, y otros 15 minutos para volver a concentrarte al 100% en la tarea que tenías entre manos.</p>

<p>Sobre todo en épocas donde nos marcamos deadlines ajustados, las notificaciones las reduzco al mínimo. Móviles en modo silencio o modo avión, correo cerrado, y otras aplicaciones solo con las notificaciones más importantes activadas (por ejemplo, en HipChat solo las menciones directas).</p>

<h2 id="organización">Organización</h2>

<p>Tres componentes definen este área:</p>

<ul>
  <li>Todas las historias que componen el proyecto en el que trabajo están gestionadas a través de <a href="https://www.pivotaltracker.com">Pivotal Tracker</a>. Una pestaña fija en el navegador.</li>
  <li>Mantengo en Evernote una libreta donde voy almacenando artículos técnicos que voy necesitando (bendito <a href="https://evernote.com/intl/es/webclipper/">Web Clipper</a>).</li>
  <li><a href="https://culturedcode.com/things/">Things</a> recopila todas las tareas, tanto del trabajo como asuntos personales, que debo atacar. Todas las acciones que supongan más que una respuesta rápida de menos de unos pocos minutos queda anotada por aquí, y dos veces al día el Inbox es revisado.</li>
</ul>

<h2 id="motivación-por-lo-que-haces">Motivación por lo que haces</h2>

<p>Esto es básico. Es imposible ser productivo en tu trabajo si no sientes cada mañana cuando te pones delante de la pantalla que te espera un día interesante, cargado de retos.</p>

<p>¿De qué se compone tu “coding zone”?</p>]]></content><author><name>Luis Mayoral</name><email>luis@luismayoral.com</email></author><category term="Desarrollo" /><category term="ruby" /><summary type="html"><![CDATA[De un tiempo a esta parte se lleva popularizando entre las bitácoras de desarrolladores el compartir lo que cada uno define como su “coding zone”, su entorno de trabajo ideal para tener sesiones de programación lo más productivas posibles. En mi caso, mi entorno ideal se compone de cuatro pilares fundamentales.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://www.luismayoral.com/images/2014/03/the-coding-zone.jpg" /><media:content medium="image" url="https://www.luismayoral.com/images/2014/03/the-coding-zone.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">La plataforma ideal</title><link href="https://www.luismayoral.com/bitacora/2013/08/la-plataforma-ideal" rel="alternate" type="text/html" title="La plataforma ideal" /><published>2013-08-24T00:00:00+02:00</published><updated>2013-08-24T00:00:00+02:00</updated><id>https://www.luismayoral.com/bitacora/2013/08/la-plataforma-ideal</id><content type="html" xml:base="https://www.luismayoral.com/bitacora/2013/08/la-plataforma-ideal"><![CDATA[<p>Hace unos días Paul Stamatiou, diseñador en Twitter, escribió un post titulado <a href="http://paulstamatiou.com/android-is-better">“Android is better”</a>, donde cuenta cómo en apenas tres meses desde que empezó a usar primero un LG Nexus 4 y después un Samsung Galaxy S4 Google Edition acabó por vender su iPhone y su iPad y convertirse en defensor a ultranza de los paradigmas de Android y sus ventajas frente a los de iOS.</p>

<p>Entre todas las respuestas que generó esta entrada una de las que más me gustó fue <a href="http://www.marco.org/2013/08/13/google-blindness">“Google blindness”</a> de Marco Arment, el creador de Instapaper.</p>

<p>Una de las cosas que me gustaría destacar la entrada de Arment es algo que ya ha tratado en el pasado en entradas como <a href="http://www.marco.org/2013/08/05/be-your-own-platform">“Be your own platform”</a> y <a href="http://www.marco.org/2011/07/11/own-your-identity">“Own your identity”</a>: Es muy peligroso dejar toda tu identidad online en manos de un único proveedor. La “ventaja” de una experiencia más integrada nos deja completamente vendidos a las exigencias del propietario de la plataforma, ya sea Apple, Google, Microsoft o quien quiera, y a expensas de que en el momento menos pensado se produzcan cambios o cancelaciones de servicio de forma unilateral.</p>

<p>Otra cosa en la que coincido con la visión de Arment es: en este preciso momento, y en mi caso concreto, la plataforma ideal de desarrollo para móviles es iOS. Pero puede que en este preciso momento, y en tu caso concreto, la plataforma ideal sea Android. O Windows Mobile. O incluso BlackBerry 10. Cada uno tenemos nuestras preferencias, cada uno nos movemos más cómodos en unos entornos, y todo esto nos hará decantarnos por una cosa o por otra.</p>

<p>Como en muchas cosas en esta vida, lo importante es no convertirnos en fanáticos de ninguna de ellas, y que procuremos mantener la mente lo más abierta posible al cambio. Que no perdamos en ningún momento de vista la evolución que sufren cada una de ellas. Puede que dentro de un año salga una plataforma nueva y nos resulte interesante cambiarnos. O que alguna de las que ya existen mejore hasta el punto que nos merezca la pena migrar.</p>

<p>Los cambios siempre son bienvenidos. Aunque casi siempre suponen un esfuerzo por nuestra parte. Pero son fundamentales para crecer, como profesional, y también como persona.</p>]]></content><author><name>Luis Mayoral</name><email>luis@luismayoral.com</email></author><category term="Desarrollo" /><summary type="html"><![CDATA[Hace unos días Paul Stamatiou, diseñador en Twitter, escribió un post titulado ["Android is better"](http://paulstamatiou.com/android-is-better), donde cuenta cómo en apenas tres meses desde que empezó a usar primero un LG Nexus 4 y después un Samsung Galaxy S4 Google Edition acabó por vender su iPhone y su iPad y convertirse en defensor a ultranza de los paradigmas de Android y sus ventajas frente a los de iOS.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://www.luismayoral.com/images/2013/08/la-plataforma-ideal.jpg" /><media:content medium="image" url="https://www.luismayoral.com/images/2013/08/la-plataforma-ideal.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Clases curiosas en Rails</title><link href="https://www.luismayoral.com/bitacora/2013/04/clases-curiosas-en-rails" rel="alternate" type="text/html" title="Clases curiosas en Rails" /><published>2013-04-14T00:00:00+02:00</published><updated>2013-04-14T00:00:00+02:00</updated><id>https://www.luismayoral.com/bitacora/2013/04/clases-curiosas-en-rails</id><content type="html" xml:base="https://www.luismayoral.com/bitacora/2013/04/clases-curiosas-en-rails"><![CDATA[<p>Por muchos años que lleves utilizando Rails, siempre te encontrarás navegando por la documentación con clases de lo más útiles y que probablemente estés usando de forma indirecta sin conocerlo.</p>

<p>Intentaré a lo largo de una serie de entradas como ésta ir contando cosas sobre algunas de las más importantes “en la sombra”.</p>

<h2 id="activesupportstringinquirer"><a href="http://api.rubyonrails.org/classes/ActiveSupport/StringInquirer.html">ActiveSupport::StringInquirer</a></h2>

<p>Introducida en la versión 2.2, y dando un uso curioso a method_missing, esta clase es la que está detrás de la “magia” de que:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="no">Rails</span><span class="p">.</span><span class="nf">env</span> <span class="o">==</span> <span class="s2">"production"</span>
</code></pre></div></div>

<p>también se pueda escribir como:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="no">Rails</span><span class="p">.</span><span class="nf">env</span><span class="p">.</span><span class="nf">production?</span>
</code></pre></div></div>

<p>En una clase real podríamos hacer algo como:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Video</span>
  <span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">title</span><span class="p">)</span>
    <span class="vi">@title</span> <span class="o">=</span> <span class="n">title</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="nf">title</span>
    <span class="no">ActiveSupport</span><span class="o">::</span><span class="no">StringInquirer</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="vi">@title</span><span class="p">)</span>
  <span class="k">end</span>
<span class="k">end</span>

<span class="n">v</span> <span class="o">=</span> <span class="no">Video</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="s2">"awesome"</span><span class="p">)</span>
<span class="n">v</span><span class="p">.</span><span class="nf">title</span><span class="p">.</span><span class="nf">radical?</span> <span class="c1"># =&gt; false</span>
<span class="n">v</span><span class="p">.</span><span class="nf">title</span><span class="p">.</span><span class="nf">awesome?</span> <span class="c1"># =&gt; true</span>
</code></pre></div></div>

<h2 id="activesupportmessageverifier"><a href="http://api.rubyonrails.org/classes/ActiveSupport/MessageVerifier.html">ActiveSupport::MessageVerifier</a></h2>

<p>Esta clase nos acompaña desde Rails 2.3. Al igual que la clase anterior, es raro que la hayas utilizado de forma directa, pero seguro que más de una vez en tu código has escrito algo como</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">cookies</span><span class="p">.</span><span class="nf">permanent</span><span class="p">.</span><span class="nf">signed</span><span class="p">[</span><span class="ss">:remember_me</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="n">current_user</span><span class="p">.</span><span class="nf">id</span><span class="p">,</span> <span class="n">current_user</span><span class="p">.</span><span class="nf">salt</span><span class="p">]</span>
</code></pre></div></div>

<p>La implementación de <code class="language-plaintext highlighter-rouge">cookies.signed</code> se basa en el uso de <code class="language-plaintext highlighter-rouge">MessageVerifier</code>, una clase especializada en generar mensajes firmados con una clave (en el caso de las cookies, <code class="language-plaintext highlighter-rouge">ActionController::Base.cookie_verifier_secret</code>). Para <code class="language-plaintext highlighter-rouge">MessageVerifier</code> un mensaje puede ser tanto una cadena de texto como cualquier cosa susceptible de ser serializada.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">&gt;&gt;</span> <span class="vi">@verifier</span> <span class="o">=</span> <span class="no">ActiveSupport</span><span class="o">::</span><span class="no">MessageVerifier</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="s2">"nuestra-clave-secreta"</span><span class="p">)</span>
<span class="o">=&gt;</span> <span class="c1">#&lt;ActiveSupport::MessageVerifier:0x007fe10cb32438 @secret="nuestra-clave-secreta", @digest="SHA1", @serializer=Marshal&gt;</span>
<span class="o">&gt;&gt;</span> <span class="n">mensaje_cifrado</span> <span class="o">=</span> <span class="vi">@verifier</span><span class="p">.</span><span class="nf">generate</span><span class="p">([</span><span class="s2">"Hola"</span><span class="p">,</span> <span class="s2">"Mundo"</span><span class="p">])</span>
<span class="o">=&gt;</span> <span class="s2">"BAhbB0kiCUhvbGEGOgZFVEkiCk11bmRvBjsAVA==--f2c2e657ec1501c984d8c44154b398a3a2ac9cbc"</span>
<span class="o">&gt;&gt;</span> <span class="vi">@verifier</span><span class="p">.</span><span class="nf">verify</span><span class="p">(</span><span class="n">mensaje_cifrado</span><span class="p">)</span>
<span class="o">=&gt;</span> <span class="p">[</span><span class="s2">"Hola"</span><span class="p">,</span> <span class="s2">"Mundo"</span><span class="p">]</span>
</code></pre></div></div>

<p>Dentro de la serialización por defecto se utiliza <code class="language-plaintext highlighter-rouge">Marshall</code>, pero si por ejemplo preferimos utilizar YAML podríamos hacer algo como:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="vi">@verifier</span><span class="p">.</span><span class="nf">serializer</span> <span class="o">=</span> <span class="no">YAML</span>
</code></pre></div></div>

<p>Y hasta aquí por hoy. ¿Qué otras clases curiosas te has encontrado utilizando Rails en tu día a día?</p>]]></content><author><name>Luis Mayoral</name><email>luis@luismayoral.com</email></author><category term="Desarrollo" /><category term="ruby" /><summary type="html"><![CDATA[Por muchos años que lleves utilizando Rails, siempre te encontrarás navegando por la documentación con clases de lo más útiles y que probablemente estés usando de forma indirecta sin conocerlo.]]></summary></entry><entry><title type="html">Pensando en Sphinx</title><link href="https://www.luismayoral.com/bitacora/2012/06/pensando-en-sphinx" rel="alternate" type="text/html" title="Pensando en Sphinx" /><published>2012-06-17T00:00:00+02:00</published><updated>2012-06-17T00:00:00+02:00</updated><id>https://www.luismayoral.com/bitacora/2012/06/pensando-en-sphinx</id><content type="html" xml:base="https://www.luismayoral.com/bitacora/2012/06/pensando-en-sphinx"><![CDATA[<p>A lo largo de estos años he realizado una buena cantidad de proyectos cuyas búsquedas se apoyaban en el excelente motor <a href="http://sphinxsearch.com/">Sphinx</a>.</p>

<p>Me gustaría aprovechar esta entrada para compartir algunas de las configuraciones más habituales que he utilizado. Todas ellas están pensadas para añadir a vuestra sección development o production, según corresponda, en el fichero <code class="language-plaintext highlighter-rouge">config/sphinx.yml</code> si usáis Thinking Sphinx como gema para interactuar con Sphinx desde Ruby.</p>

<h2 id="búsquedas-con-wildcards">Búsquedas con wildcards</h2>

<p>Por defecto Sphinx solo realiza búsquedas del término completo. Si buscamos por <code class="language-plaintext highlighter-rouge">"madr"</code> no encontraríamos <code class="language-plaintext highlighter-rouge">"madrid"</code>, por ejemplo.</p>

<p>Mediante configuración podemos activar la indexación del contenido y el soporte de búsquedas tipo wildcard:</p>

<div class="language-yml highlighter-rouge"><div class="highlight"><pre class="highlight"><code>  <span class="na">enable_star</span><span class="pi">:</span> <span class="m">1</span>
  <span class="na">min_infix_len</span><span class="pi">:</span> <span class="m">3</span>
</code></pre></div></div>

<p>Con las líneas anteriores estamos activando las búsquedas wildcard (enable_star). A las búsquedas habituales podríamos realizar las búsquedas <code class="language-plaintext highlighter-rouge">"termino"</code>, <code class="language-plaintext highlighter-rouge">"*termino"</code> y <code class="language-plaintext highlighter-rouge">"*termino*"</code>.</p>

<p>También estamos definiendo el tamaño mínimo del infijo a tener en cuenta en 3. En el caso del término <code class="language-plaintext highlighter-rouge">"madrid"</code>, este se indexaría como <code class="language-plaintext highlighter-rouge">"mad"</code>, <code class="language-plaintext highlighter-rouge">"adr"</code>, <code class="language-plaintext highlighter-rouge">"dri"</code>, <code class="language-plaintext highlighter-rouge">"rid"</code>, etc.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="vi">@contacts</span> <span class="o">=</span> <span class="no">Contact</span><span class="p">.</span><span class="nf">search</span> <span class="s2">"foo"</span><span class="p">,</span> <span class="ss">match_mode: :any</span><span class="p">,</span> <span class="ss">order: </span><span class="s2">"@relevance DESC"</span><span class="p">,</span> <span class="ss">star: </span><span class="kp">true</span>
</code></pre></div></div>

<p>Mediante <code class="language-plaintext highlighter-rouge">star: true</code> estamos realizando una búsqueda de <code class="language-plaintext highlighter-rouge">"*foo*"</code>.</p>

<h2 id="memoria-usada-por-sphinx">Memoria usada por Sphinx</h2>

<p>A no ser que se lo especifiquemos explícitamente en la configuración, por defecto Sphinx usa solo 32 megas para realizar la indexación. En muchos casos es suficiente, pero hay veces, con grandes volúmenes de datos, en los cuales aumentar esta memoria puede suponer una mejora en el rendimiento de la indexación.</p>

<div class="language-yml highlighter-rouge"><div class="highlight"><pre class="highlight"><code>  <span class="na">mem_limit</span><span class="pi">:</span> <span class="s">512M</span>
</code></pre></div></div>

<p>Desde la web de Sphinx especifican que el límite está en 2 gigas, pero que normalmente con un valor entre 128 megas y 1 giga ninguna de tus aplicaciones debería tener problemas.</p>

<p>Hay que tener en cuenta a la hora de configurar este valor de no poner valores demasiado altos para tu aplicación, ya que cuanta más memoria use en la indexación más tiempo pasará entre conexión y conexión a tu base de datos para obtener los nuevos datos a indexar, lo cual en algunos casos puede originarte timeouts.</p>

<h2 id="jugando-con-los-charset-tables">Jugando con los charset tables</h2>

<p>En un proyecto me vi en la necesidad de trabar con datos de múltiples idiomas. Aparte, queríamos buscar una manera “cómoda” de normalizar los datos hacia minúsculas a la hora de realizar las búsquedas. En esto entró el juego el soporte en Sphinx de los charset tables.</p>

<div class="language-yml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">charset_table</span><span class="pi">:</span> <span class="s2">"</span><span class="s">0..9,</span><span class="nv"> </span><span class="s">a..z,</span><span class="nv"> </span><span class="s">_,</span><span class="nv"> </span><span class="s">A..Z-&gt;a..z,</span><span class="nv"> </span><span class="s">U+00C0-&gt;a,</span><span class="nv"> </span><span class="s">U+00C1-&gt;a,</span>
  <span class="s">U+00C2-&gt;a,</span><span class="nv"> </span><span class="s">U+00C3-&gt;a,</span><span class="nv"> </span><span class="s">U+00C4-&gt;a,</span><span class="nv"> </span><span class="s">U+00C5-&gt;a,</span><span class="nv"> </span><span class="s">U+00C7-&gt;c,</span><span class="nv"> </span><span class="s">U+00C8-&gt;e,</span>
  <span class="s">U+00C9-&gt;e,</span><span class="nv"> </span><span class="s">U+00CA-&gt;e,</span><span class="nv"> </span><span class="s">U+00CB-&gt;e,</span><span class="nv"> </span><span class="s">U+00CC-&gt;i,</span><span class="nv"> </span><span class="s">U+00CD-&gt;i,</span><span class="nv"> </span><span class="s">U+00CE-&gt;i,</span>
  <span class="s">U+00CF-&gt;i,</span><span class="nv"> </span><span class="s">U+00D1-&gt;n,</span><span class="nv"> </span><span class="s">U+00D2-&gt;o,</span><span class="nv"> </span><span class="s">U+00D3-&gt;o,</span><span class="nv"> </span><span class="s">U+00D4-&gt;o,</span><span class="nv"> </span><span class="s">U+00D5-&gt;o,</span>
  <span class="s">U+00D6-&gt;o,</span><span class="nv"> </span><span class="s">U+00D8-&gt;o,</span><span class="nv"> </span><span class="s">U+00D9-&gt;u,</span><span class="nv"> </span><span class="s">U+00DA-&gt;u,</span><span class="nv"> </span><span class="s">U+00DB-&gt;u,</span><span class="nv"> </span><span class="s">U+00DC-&gt;u,</span>
  <span class="s">U+00DD-&gt;y,</span><span class="nv"> </span><span class="s">U+00E0-&gt;a,</span><span class="nv"> </span><span class="s">U+00E1-&gt;a,</span><span class="nv"> </span><span class="s">U+00E2-&gt;a,</span><span class="nv"> </span><span class="s">U+00E3-&gt;a,</span><span class="nv"> </span><span class="s">U+00E4-&gt;a,</span>
  <span class="s">U+00E5-&gt;a,</span><span class="nv"> </span><span class="s">U+00E7-&gt;c,</span><span class="nv"> </span><span class="s">U+00E8-&gt;e,</span><span class="nv"> </span><span class="s">U+00E9-&gt;e,</span><span class="nv"> </span><span class="s">U+00EA-&gt;e,</span><span class="nv"> </span><span class="s">U+00EB-&gt;e,</span>
  <span class="s">U+00EC-&gt;i,</span><span class="nv"> </span><span class="s">U+00ED-&gt;i,</span><span class="nv"> </span><span class="s">U+00EE-&gt;i,</span><span class="nv"> </span><span class="s">U+00EF-&gt;i,</span><span class="nv"> </span><span class="s">U+00F1-&gt;n,</span><span class="nv"> </span><span class="s">U+00F2-&gt;o,</span>
  <span class="s">U+00F3-&gt;o,</span><span class="nv"> </span><span class="s">U+00F4-&gt;o,</span><span class="nv"> </span><span class="s">U+00F5-&gt;o,</span><span class="nv"> </span><span class="s">U+00F6-&gt;o,</span><span class="nv"> </span><span class="s">U+00F8-&gt;o,</span><span class="nv"> </span><span class="s">U+00F9-&gt;u,</span>
  <span class="s">U+00FA-&gt;u,</span><span class="nv"> </span><span class="s">U+00FB-&gt;u,</span><span class="nv"> </span><span class="s">U+00FC-&gt;u,</span><span class="nv"> </span><span class="s">U+00FD-&gt;y,</span><span class="nv"> </span><span class="s">U+00FF-&gt;y,</span><span class="nv"> </span><span class="s">U+0100-&gt;a,</span>
  <span class="s">U+0101-&gt;a,</span><span class="nv"> </span><span class="s">U+0102-&gt;a,</span><span class="nv"> </span><span class="s">U+0103-&gt;a,</span><span class="nv"> </span><span class="s">U+0104-&gt;a,</span><span class="nv"> </span><span class="s">U+0105-&gt;a,</span><span class="nv"> </span><span class="s">U+0106-&gt;c,</span>
  <span class="s">U+0107-&gt;c,</span><span class="nv"> </span><span class="s">U+0108-&gt;c,</span><span class="nv"> </span><span class="s">U+0109-&gt;c,</span><span class="nv"> </span><span class="s">U+010A-&gt;c,</span><span class="nv"> </span><span class="s">U+010B-&gt;c,</span><span class="nv"> </span><span class="s">U+010C-&gt;c,</span>
  <span class="s">U+010D-&gt;c,</span><span class="nv"> </span><span class="s">U+010E-&gt;d,</span><span class="nv"> </span><span class="s">U+010F-&gt;d,</span><span class="nv"> </span><span class="s">U+0112-&gt;e,</span><span class="nv"> </span><span class="s">U+0113-&gt;e,</span><span class="nv"> </span><span class="s">U+0114-&gt;e,</span>
  <span class="s">U+0115-&gt;e,</span><span class="nv"> </span><span class="s">U+0116-&gt;e,</span><span class="nv"> </span><span class="s">U+0117-&gt;e,</span><span class="nv"> </span><span class="s">U+0118-&gt;e,</span><span class="nv"> </span><span class="s">U+0119-&gt;e,</span><span class="nv"> </span><span class="s">U+011A-&gt;e,</span>
  <span class="s">U+011B-&gt;e,</span><span class="nv"> </span><span class="s">U+011C-&gt;g,</span><span class="nv"> </span><span class="s">U+011D-&gt;g,</span><span class="nv"> </span><span class="s">U+011E-&gt;g,</span><span class="nv"> </span><span class="s">U+011F-&gt;g,</span><span class="nv"> </span><span class="s">U+0120-&gt;g,</span>
  <span class="s">U+0121-&gt;g,</span><span class="nv"> </span><span class="s">U+0122-&gt;g,</span><span class="nv"> </span><span class="s">U+0123-&gt;g,</span><span class="nv"> </span><span class="s">U+0124-&gt;h,</span><span class="nv"> </span><span class="s">U+0125-&gt;h,</span><span class="nv"> </span><span class="s">U+0128-&gt;i,</span>
  <span class="s">U+0129-&gt;i,</span><span class="nv"> </span><span class="s">U+012A-&gt;i,</span><span class="nv"> </span><span class="s">U+012B-&gt;i,</span><span class="nv"> </span><span class="s">U+012C-&gt;i,</span><span class="nv"> </span><span class="s">U+012D-&gt;i,</span><span class="nv"> </span><span class="s">U+012E-&gt;i,</span>
  <span class="s">U+012F-&gt;i,</span><span class="nv"> </span><span class="s">U+0130-&gt;i,</span><span class="nv"> </span><span class="s">U+0134-&gt;j,</span><span class="nv"> </span><span class="s">U+0135-&gt;j,</span><span class="nv"> </span><span class="s">U+0136-&gt;k,</span><span class="nv"> </span><span class="s">U+0137-&gt;k,</span>
  <span class="s">U+0139-&gt;l,</span><span class="nv"> </span><span class="s">U+013A-&gt;l,</span><span class="nv"> </span><span class="s">U+013B-&gt;l,</span><span class="nv"> </span><span class="s">U+013C-&gt;l,</span><span class="nv"> </span><span class="s">U+013D-&gt;l,</span><span class="nv"> </span><span class="s">U+013E-&gt;l,</span>
  <span class="s">U+0142-&gt;l,</span><span class="nv"> </span><span class="s">U+0143-&gt;n,</span><span class="nv"> </span><span class="s">U+0144-&gt;n,</span><span class="nv"> </span><span class="s">U+0145-&gt;n,</span><span class="nv"> </span><span class="s">U+0146-&gt;n,</span><span class="nv"> </span><span class="s">U+0147-&gt;n,</span>
  <span class="s">U+0148-&gt;n,</span><span class="nv"> </span><span class="s">U+014C-&gt;o,</span><span class="nv"> </span><span class="s">U+014D-&gt;o,</span><span class="nv"> </span><span class="s">U+014E-&gt;o,</span><span class="nv"> </span><span class="s">U+014F-&gt;o,</span><span class="nv"> </span><span class="s">U+0150-&gt;o,</span>
  <span class="s">U+0151-&gt;o,</span><span class="nv"> </span><span class="s">U+0154-&gt;r,</span><span class="nv"> </span><span class="s">U+0155-&gt;r,</span><span class="nv"> </span><span class="s">U+0156-&gt;r,</span><span class="nv"> </span><span class="s">U+0157-&gt;r,</span><span class="nv"> </span><span class="s">U+0158-&gt;r,</span>
  <span class="s">U+0159-&gt;r,</span><span class="nv"> </span><span class="s">U+015A-&gt;s,</span><span class="nv"> </span><span class="s">U+015B-&gt;s,</span><span class="nv"> </span><span class="s">U+015C-&gt;s,</span><span class="nv"> </span><span class="s">U+015D-&gt;s,</span><span class="nv"> </span><span class="s">U+015E-&gt;s,</span>
  <span class="s">U+015F-&gt;s,</span><span class="nv"> </span><span class="s">U+0160-&gt;s,</span><span class="nv"> </span><span class="s">U+0161-&gt;s,</span><span class="nv"> </span><span class="s">U+0162-&gt;t,</span><span class="nv"> </span><span class="s">U+0163-&gt;t,</span><span class="nv"> </span><span class="s">U+0164-&gt;t,</span>
  <span class="s">U+0165-&gt;t,</span><span class="nv"> </span><span class="s">U+0168-&gt;u,</span><span class="nv"> </span><span class="s">U+0169-&gt;u,</span><span class="nv"> </span><span class="s">U+016A-&gt;u,</span><span class="nv"> </span><span class="s">U+016B-&gt;u,</span><span class="nv"> </span><span class="s">U+016C-&gt;u,</span>
  <span class="s">U+016D-&gt;u,</span><span class="nv"> </span><span class="s">U+016E-&gt;u,</span><span class="nv"> </span><span class="s">U+016F-&gt;u,</span><span class="nv"> </span><span class="s">U+0170-&gt;u,</span><span class="nv"> </span><span class="s">U+0171-&gt;u,</span><span class="nv"> </span><span class="s">U+0172-&gt;u,</span>
  <span class="s">U+0173-&gt;u,</span><span class="nv"> </span><span class="s">U+0174-&gt;w,</span><span class="nv"> </span><span class="s">U+0175-&gt;w,</span><span class="nv"> </span><span class="s">U+0176-&gt;y,</span><span class="nv"> </span><span class="s">U+0177-&gt;y,</span><span class="nv"> </span><span class="s">U+0178-&gt;y,</span>
  <span class="s">U+0179-&gt;z,</span><span class="nv"> </span><span class="s">U+017A-&gt;z,</span><span class="nv"> </span><span class="s">U+017B-&gt;z,</span><span class="nv"> </span><span class="s">U+017C-&gt;z,</span><span class="nv"> </span><span class="s">U+017D-&gt;z,</span><span class="nv"> </span><span class="s">U+017E-&gt;z,</span>
  <span class="s">U+01A0-&gt;o,</span><span class="nv"> </span><span class="s">U+01A1-&gt;o,</span><span class="nv"> </span><span class="s">U+01AF-&gt;u,</span><span class="nv"> </span><span class="s">U+01B0-&gt;u,</span><span class="nv"> </span><span class="s">U+01CD-&gt;a,</span><span class="nv"> </span><span class="s">U+01CE-&gt;a,</span>
  <span class="s">U+01CF-&gt;i,</span><span class="nv"> </span><span class="s">U+01D0-&gt;i,</span><span class="nv"> </span><span class="s">U+01D1-&gt;o,</span><span class="nv"> </span><span class="s">U+01D2-&gt;o,</span><span class="nv"> </span><span class="s">U+01D3-&gt;u,</span><span class="nv"> </span><span class="s">U+01D4-&gt;u,</span>
  <span class="s">U+01D5-&gt;u,</span><span class="nv"> </span><span class="s">U+01D6-&gt;u,</span><span class="nv"> </span><span class="s">U+01D7-&gt;u,</span><span class="nv"> </span><span class="s">U+01D8-&gt;u,</span><span class="nv"> </span><span class="s">U+01D9-&gt;u,</span><span class="nv"> </span><span class="s">U+01DA-&gt;u,</span>
  <span class="s">U+01DB-&gt;u,</span><span class="nv"> </span><span class="s">U+01DC-&gt;u,</span><span class="nv"> </span><span class="s">U+01DE-&gt;a,</span><span class="nv"> </span><span class="s">U+01DF-&gt;a,</span><span class="nv"> </span><span class="s">U+01E0-&gt;a,</span><span class="nv"> </span><span class="s">U+01E1-&gt;a,</span>
  <span class="s">U+01E6-&gt;g,</span><span class="nv"> </span><span class="s">U+01E7-&gt;g,</span><span class="nv"> </span><span class="s">U+01E8-&gt;k,</span><span class="nv"> </span><span class="s">U+01E9-&gt;k,</span><span class="nv"> </span><span class="s">U+01EA-&gt;o,</span><span class="nv"> </span><span class="s">U+01EB-&gt;o,</span>
  <span class="s">U+01EC-&gt;o,</span><span class="nv"> </span><span class="s">U+01ED-&gt;o,</span><span class="nv"> </span><span class="s">U+01F0-&gt;j,</span><span class="nv"> </span><span class="s">U+01F4-&gt;g,</span><span class="nv"> </span><span class="s">U+01F5-&gt;g,</span><span class="nv"> </span><span class="s">U+01F8-&gt;n,</span>
  <span class="s">U+01F9-&gt;n,</span><span class="nv"> </span><span class="s">U+01FA-&gt;a,</span><span class="nv"> </span><span class="s">U+01FB-&gt;a,</span><span class="nv"> </span><span class="s">U+0200-&gt;a,</span><span class="nv"> </span><span class="s">U+0201-&gt;a,</span><span class="nv"> </span><span class="s">U+0202-&gt;a,</span>
  <span class="s">U+0203-&gt;a,</span><span class="nv"> </span><span class="s">U+0204-&gt;e,</span><span class="nv"> </span><span class="s">U+0205-&gt;e,</span><span class="nv"> </span><span class="s">U+0206-&gt;e,</span><span class="nv"> </span><span class="s">U+0207-&gt;e,</span><span class="nv"> </span><span class="s">U+0208-&gt;i,</span>
  <span class="s">U+0209-&gt;i,</span><span class="nv"> </span><span class="s">U+020A-&gt;i,</span><span class="nv"> </span><span class="s">U+020B-&gt;i,</span><span class="nv"> </span><span class="s">U+020C-&gt;o,</span><span class="nv"> </span><span class="s">U+020D-&gt;o,</span><span class="nv"> </span><span class="s">U+020E-&gt;o,</span>
  <span class="s">U+020F-&gt;o,</span><span class="nv"> </span><span class="s">U+0210-&gt;r,</span><span class="nv"> </span><span class="s">U+0211-&gt;r,</span><span class="nv"> </span><span class="s">U+0212-&gt;r,</span><span class="nv"> </span><span class="s">U+0213-&gt;r,</span><span class="nv"> </span><span class="s">U+0214-&gt;u,</span>
  <span class="s">U+0215-&gt;u,</span><span class="nv"> </span><span class="s">U+0216-&gt;u,</span><span class="nv"> </span><span class="s">U+0217-&gt;u,</span><span class="nv"> </span><span class="s">U+0218-&gt;s,</span><span class="nv"> </span><span class="s">U+0219-&gt;s,</span><span class="nv"> </span><span class="s">U+021A-&gt;t,</span>
  <span class="s">U+021B-&gt;t,</span><span class="nv"> </span><span class="s">U+021E-&gt;h,</span><span class="nv"> </span><span class="s">U+021F-&gt;h,</span><span class="nv"> </span><span class="s">U+0226-&gt;a,</span><span class="nv"> </span><span class="s">U+0227-&gt;a,</span><span class="nv"> </span><span class="s">U+0228-&gt;e,</span>
  <span class="s">U+0229-&gt;e,</span><span class="nv"> </span><span class="s">U+022A-&gt;o,</span><span class="nv"> </span><span class="s">U+022B-&gt;o,</span><span class="nv"> </span><span class="s">U+022C-&gt;o,</span><span class="nv"> </span><span class="s">U+022D-&gt;o,</span><span class="nv"> </span><span class="s">U+022E-&gt;o,</span>
  <span class="s">U+022F-&gt;o,</span><span class="nv"> </span><span class="s">U+0230-&gt;o,</span><span class="nv"> </span><span class="s">U+0231-&gt;o,</span><span class="nv"> </span><span class="s">U+0232-&gt;y,</span><span class="nv"> </span><span class="s">U+0233-&gt;y,</span><span class="nv"> </span><span class="s">U+1E00-&gt;a,</span>
  <span class="s">U+1E01-&gt;a,</span><span class="nv"> </span><span class="s">U+1E02-&gt;b,</span><span class="nv"> </span><span class="s">U+1E03-&gt;b,</span><span class="nv"> </span><span class="s">U+1E04-&gt;b,</span><span class="nv"> </span><span class="s">U+1E05-&gt;b,</span><span class="nv"> </span><span class="s">U+1E06-&gt;b,</span>
  <span class="s">U+1E07-&gt;b,</span><span class="nv"> </span><span class="s">U+1E08-&gt;c,</span><span class="nv"> </span><span class="s">U+1E09-&gt;c,</span><span class="nv"> </span><span class="s">U+1E0A-&gt;d,</span><span class="nv"> </span><span class="s">U+1E0B-&gt;d,</span><span class="nv"> </span><span class="s">U+1E0C-&gt;d,</span>
  <span class="s">U+1E0D-&gt;d,</span><span class="nv"> </span><span class="s">U+1E0E-&gt;d,</span><span class="nv"> </span><span class="s">U+1E0F-&gt;d,</span><span class="nv"> </span><span class="s">U+1E10-&gt;d,</span><span class="nv"> </span><span class="s">U+1E11-&gt;d,</span><span class="nv"> </span><span class="s">U+1E12-&gt;d,</span>
  <span class="s">U+1E13-&gt;d,</span><span class="nv"> </span><span class="s">U+1E14-&gt;e,</span><span class="nv"> </span><span class="s">U+1E15-&gt;e,</span><span class="nv"> </span><span class="s">U+1E16-&gt;e,</span><span class="nv"> </span><span class="s">U+1E17-&gt;e,</span><span class="nv"> </span><span class="s">U+1E18-&gt;e,</span>
  <span class="s">U+1E19-&gt;e,</span><span class="nv"> </span><span class="s">U+1E1A-&gt;e,</span><span class="nv"> </span><span class="s">U+1E1B-&gt;e,</span><span class="nv"> </span><span class="s">U+1E1C-&gt;e,</span><span class="nv"> </span><span class="s">U+1E1D-&gt;e,</span><span class="nv"> </span><span class="s">U+1E1E-&gt;f,</span>
  <span class="s">U+1E1F-&gt;f,</span><span class="nv"> </span><span class="s">U+1E20-&gt;g,</span><span class="nv"> </span><span class="s">U+1E21-&gt;g,</span><span class="nv"> </span><span class="s">U+1E22-&gt;h,</span><span class="nv"> </span><span class="s">U+1E23-&gt;h,</span><span class="nv"> </span><span class="s">U+1E24-&gt;h,</span>
  <span class="s">U+1E25-&gt;h,</span><span class="nv"> </span><span class="s">U+1E26-&gt;h,</span><span class="nv"> </span><span class="s">U+1E27-&gt;h,</span><span class="nv"> </span><span class="s">U+1E28-&gt;h,</span><span class="nv"> </span><span class="s">U+1E29-&gt;h,</span><span class="nv"> </span><span class="s">U+1E2A-&gt;h,</span>
  <span class="s">U+1E2B-&gt;h,</span><span class="nv"> </span><span class="s">U+1E2C-&gt;i,</span><span class="nv"> </span><span class="s">U+1E2D-&gt;i,</span><span class="nv"> </span><span class="s">U+1E2E-&gt;i,</span><span class="nv"> </span><span class="s">U+1E2F-&gt;i,</span><span class="nv"> </span><span class="s">U+1E30-&gt;k,</span>
  <span class="s">U+1E31-&gt;k,</span><span class="nv"> </span><span class="s">U+1E32-&gt;k,</span><span class="nv"> </span><span class="s">U+1E33-&gt;k,</span><span class="nv"> </span><span class="s">U+1E34-&gt;k,</span><span class="nv"> </span><span class="s">U+1E35-&gt;k,</span><span class="nv"> </span><span class="s">U+1E36-&gt;l,</span>
  <span class="s">U+1E37-&gt;l,</span><span class="nv"> </span><span class="s">U+1E38-&gt;l,</span><span class="nv"> </span><span class="s">U+1E39-&gt;l,</span><span class="nv"> </span><span class="s">U+1E3A-&gt;l,</span><span class="nv"> </span><span class="s">U+1E3B-&gt;l,</span><span class="nv"> </span><span class="s">U+1E3C-&gt;l,</span>
  <span class="s">U+1E3D-&gt;l,</span><span class="nv"> </span><span class="s">U+1E3E-&gt;m,</span><span class="nv"> </span><span class="s">U+1E3F-&gt;m,</span><span class="nv"> </span><span class="s">U+1E40-&gt;m,</span><span class="nv"> </span><span class="s">U+1E41-&gt;m,</span><span class="nv"> </span><span class="s">U+1E42-&gt;m,</span>
  <span class="s">U+1E43-&gt;m,</span><span class="nv"> </span><span class="s">U+1E44-&gt;n,</span><span class="nv"> </span><span class="s">U+1E45-&gt;n,</span><span class="nv"> </span><span class="s">U+1E46-&gt;n,</span><span class="nv"> </span><span class="s">U+1E47-&gt;n,</span><span class="nv"> </span><span class="s">U+1E48-&gt;n,</span>
  <span class="s">U+1E49-&gt;n,</span><span class="nv"> </span><span class="s">U+1E4A-&gt;n,</span><span class="nv"> </span><span class="s">U+1E4B-&gt;n,</span><span class="nv"> </span><span class="s">U+1E4C-&gt;o,</span><span class="nv"> </span><span class="s">U+1E4D-&gt;o,</span><span class="nv"> </span><span class="s">U+1E4E-&gt;o,</span>
  <span class="s">U+1E4F-&gt;o,</span><span class="nv"> </span><span class="s">U+1E50-&gt;o,</span><span class="nv"> </span><span class="s">U+1E51-&gt;o,</span><span class="nv"> </span><span class="s">U+1E52-&gt;o,</span><span class="nv"> </span><span class="s">U+1E53-&gt;o,</span><span class="nv"> </span><span class="s">U+1E54-&gt;p,</span>
  <span class="s">U+1E55-&gt;p,</span><span class="nv"> </span><span class="s">U+1E56-&gt;p,</span><span class="nv"> </span><span class="s">U+1E57-&gt;p,</span><span class="nv"> </span><span class="s">U+1E58-&gt;r,</span><span class="nv"> </span><span class="s">U+1E59-&gt;r,</span><span class="nv"> </span><span class="s">U+1E5A-&gt;r,</span>
  <span class="s">U+1E5B-&gt;r,</span><span class="nv"> </span><span class="s">U+1E5C-&gt;r,</span><span class="nv"> </span><span class="s">U+1E5D-&gt;r,</span><span class="nv"> </span><span class="s">U+1E5E-&gt;r,</span><span class="nv"> </span><span class="s">U+1E5F-&gt;r,</span><span class="nv"> </span><span class="s">U+1E60-&gt;s,</span>
  <span class="s">U+1E61-&gt;s,</span><span class="nv"> </span><span class="s">U+1E62-&gt;s,</span><span class="nv"> </span><span class="s">U+1E63-&gt;s,</span><span class="nv"> </span><span class="s">U+1E64-&gt;s,</span><span class="nv"> </span><span class="s">U+1E65-&gt;s,</span><span class="nv"> </span><span class="s">U+1E66-&gt;s,</span>
  <span class="s">U+1E67-&gt;s,</span><span class="nv"> </span><span class="s">U+1E68-&gt;s,</span><span class="nv"> </span><span class="s">U+1E69-&gt;s,</span><span class="nv"> </span><span class="s">U+1E6A-&gt;t,</span><span class="nv"> </span><span class="s">U+1E6B-&gt;t,</span><span class="nv"> </span><span class="s">U+1E6C-&gt;t,</span>
  <span class="s">U+1E6D-&gt;t,</span><span class="nv"> </span><span class="s">U+1E6E-&gt;t,</span><span class="nv"> </span><span class="s">U+1E6F-&gt;t,</span><span class="nv"> </span><span class="s">U+1E70-&gt;t,</span><span class="nv"> </span><span class="s">U+1E71-&gt;t,</span><span class="nv"> </span><span class="s">U+1E72-&gt;u,</span>
  <span class="s">U+1E73-&gt;u,</span><span class="nv"> </span><span class="s">U+1E74-&gt;u,</span><span class="nv"> </span><span class="s">U+1E75-&gt;u,</span><span class="nv"> </span><span class="s">U+1E76-&gt;u,</span><span class="nv"> </span><span class="s">U+1E77-&gt;u,</span><span class="nv"> </span><span class="s">U+1E78-&gt;u,</span>
  <span class="s">U+1E79-&gt;u,</span><span class="nv"> </span><span class="s">U+1E7A-&gt;u,</span><span class="nv"> </span><span class="s">U+1E7B-&gt;u,</span><span class="nv"> </span><span class="s">U+1E7C-&gt;v,</span><span class="nv"> </span><span class="s">U+1E7D-&gt;v,</span><span class="nv"> </span><span class="s">U+1E7E-&gt;v,</span>
  <span class="s">U+1E7F-&gt;v,</span><span class="nv"> </span><span class="s">U+1E80-&gt;w,</span><span class="nv"> </span><span class="s">U+1E81-&gt;w,</span><span class="nv"> </span><span class="s">U+1E82-&gt;w,</span><span class="nv"> </span><span class="s">U+1E83-&gt;w,</span><span class="nv"> </span><span class="s">U+1E84-&gt;w,</span>
  <span class="s">U+1E85-&gt;w,</span><span class="nv"> </span><span class="s">U+1E86-&gt;w,</span><span class="nv"> </span><span class="s">U+1E87-&gt;w,</span><span class="nv"> </span><span class="s">U+1E88-&gt;w,</span><span class="nv"> </span><span class="s">U+1E89-&gt;w,</span><span class="nv"> </span><span class="s">U+1E8A-&gt;x,</span>
  <span class="s">U+1E8B-&gt;x,</span><span class="nv"> </span><span class="s">U+1E8C-&gt;x,</span><span class="nv"> </span><span class="s">U+1E8D-&gt;x,</span><span class="nv"> </span><span class="s">U+1E8E-&gt;y,</span><span class="nv"> </span><span class="s">U+1E8F-&gt;y,</span><span class="nv"> </span><span class="s">U+1E96-&gt;h,</span>
  <span class="s">U+1E97-&gt;t,</span><span class="nv"> </span><span class="s">U+1E98-&gt;w,</span><span class="nv"> </span><span class="s">U+1E99-&gt;y,</span><span class="nv"> </span><span class="s">U+1EA0-&gt;a,</span><span class="nv"> </span><span class="s">U+1EA1-&gt;a,</span><span class="nv"> </span><span class="s">U+1EA2-&gt;a,</span>
  <span class="s">U+1EA3-&gt;a,</span><span class="nv"> </span><span class="s">U+1EA4-&gt;a,</span><span class="nv"> </span><span class="s">U+1EA5-&gt;a,</span><span class="nv"> </span><span class="s">U+1EA6-&gt;a,</span><span class="nv"> </span><span class="s">U+1EA7-&gt;a,</span><span class="nv"> </span><span class="s">U+1EA8-&gt;a,</span>
  <span class="s">U+1EA9-&gt;a,</span><span class="nv"> </span><span class="s">U+1EAA-&gt;a,</span><span class="nv"> </span><span class="s">U+1EAB-&gt;a,</span><span class="nv"> </span><span class="s">U+1EAC-&gt;a,</span><span class="nv"> </span><span class="s">U+1EAD-&gt;a,</span><span class="nv"> </span><span class="s">U+1EAE-&gt;a,</span>
  <span class="s">U+1EAF-&gt;a,</span><span class="nv"> </span><span class="s">U+1EB0-&gt;a,</span><span class="nv"> </span><span class="s">U+1EB1-&gt;a,</span><span class="nv"> </span><span class="s">U+1EB2-&gt;a,</span><span class="nv"> </span><span class="s">U+1EB3-&gt;a,</span><span class="nv"> </span><span class="s">U+1EB4-&gt;a,</span>
  <span class="s">U+1EB5-&gt;a,</span><span class="nv"> </span><span class="s">U+1EB6-&gt;a,</span><span class="nv"> </span><span class="s">U+1EB7-&gt;a,</span><span class="nv"> </span><span class="s">U+1EB8-&gt;e,</span><span class="nv"> </span><span class="s">U+1EB9-&gt;e,</span><span class="nv"> </span><span class="s">U+1EBA-&gt;e,</span>
  <span class="s">U+1EBB-&gt;e,</span><span class="nv"> </span><span class="s">U+1EBC-&gt;e,</span><span class="nv"> </span><span class="s">U+1EBD-&gt;e,</span><span class="nv"> </span><span class="s">U+1EBE-&gt;e,</span><span class="nv"> </span><span class="s">U+1EBF-&gt;e,</span><span class="nv"> </span><span class="s">U+1EC0-&gt;e,</span>
  <span class="s">U+1EC1-&gt;e,</span><span class="nv"> </span><span class="s">U+1EC2-&gt;e,</span><span class="nv"> </span><span class="s">U+1EC3-&gt;e,</span><span class="nv"> </span><span class="s">U+1EC4-&gt;e,</span><span class="nv"> </span><span class="s">U+1EC5-&gt;e,</span><span class="nv"> </span><span class="s">U+1EC6-&gt;e,</span>
  <span class="s">U+1EC7-&gt;e,</span><span class="nv"> </span><span class="s">U+1EC8-&gt;i,</span><span class="nv"> </span><span class="s">U+1EC9-&gt;i,</span><span class="nv"> </span><span class="s">U+1ECA-&gt;i,</span><span class="nv"> </span><span class="s">U+1ECB-&gt;i,</span><span class="nv"> </span><span class="s">U+1ECC-&gt;o,</span>
  <span class="s">U+1ECD-&gt;o,</span><span class="nv"> </span><span class="s">U+1ECE-&gt;o,</span><span class="nv"> </span><span class="s">U+1ECF-&gt;o,</span><span class="nv"> </span><span class="s">U+1ED0-&gt;o,</span><span class="nv"> </span><span class="s">U+1ED1-&gt;o,</span><span class="nv"> </span><span class="s">U+1ED2-&gt;o,</span>
  <span class="s">U+1ED3-&gt;o,</span><span class="nv"> </span><span class="s">U+1ED4-&gt;o,</span><span class="nv"> </span><span class="s">U+1ED5-&gt;o,</span><span class="nv"> </span><span class="s">U+1ED6-&gt;o,</span><span class="nv"> </span><span class="s">U+1ED7-&gt;o,</span><span class="nv"> </span><span class="s">U+1ED8-&gt;o,</span>
  <span class="s">U+1ED9-&gt;o,</span><span class="nv"> </span><span class="s">U+1EDA-&gt;o,</span><span class="nv"> </span><span class="s">U+1EDB-&gt;o,</span><span class="nv"> </span><span class="s">U+1EDC-&gt;o,</span><span class="nv"> </span><span class="s">U+1EDD-&gt;o,</span><span class="nv"> </span><span class="s">U+1EDE-&gt;o,</span>
  <span class="s">U+1EDF-&gt;o,</span><span class="nv"> </span><span class="s">U+1EE0-&gt;o,</span><span class="nv"> </span><span class="s">U+1EE1-&gt;o,</span><span class="nv"> </span><span class="s">U+1EE2-&gt;o,</span><span class="nv"> </span><span class="s">U+1EE3-&gt;o,</span><span class="nv"> </span><span class="s">U+1EE4-&gt;u,</span>
  <span class="s">U+1EE5-&gt;u,</span><span class="nv"> </span><span class="s">U+1EE6-&gt;u,</span><span class="nv"> </span><span class="s">U+1EE7-&gt;u,</span><span class="nv"> </span><span class="s">U+1EE8-&gt;u,</span><span class="nv"> </span><span class="s">U+1EE9-&gt;u,</span><span class="nv"> </span><span class="s">U+1EEA-&gt;u,</span>
  <span class="s">U+1EEB-&gt;u,</span><span class="nv"> </span><span class="s">U+1EEC-&gt;u,</span><span class="nv"> </span><span class="s">U+1EED-&gt;u,</span><span class="nv"> </span><span class="s">U+1EEE-&gt;u,</span><span class="nv"> </span><span class="s">U+1EEF-&gt;u,</span><span class="nv"> </span><span class="s">U+1EF0-&gt;u,</span>
  <span class="s">U+1EF1-&gt;u,</span><span class="nv"> </span><span class="s">U+1EF2-&gt;y,</span><span class="nv"> </span><span class="s">U+1EF3-&gt;y,</span><span class="nv"> </span><span class="s">U+1EF4-&gt;y,</span><span class="nv"> </span><span class="s">U+1EF5-&gt;y,</span><span class="nv"> </span><span class="s">U+1EF6-&gt;y,</span>
  <span class="s">U+1EF7-&gt;y,</span><span class="nv"> </span><span class="s">U+1EF8-&gt;y,</span><span class="nv"> </span><span class="s">U+1EF9-&gt;y"</span>
</code></pre></div></div>

<p>Con este charset table tienes:</p>

<ul>
  <li>Las mayúsculas convertidas a minúsculas (<code class="language-plaintext highlighter-rouge">"A"</code> se convierte en <code class="language-plaintext highlighter-rouge">"a"</code>, <code class="language-plaintext highlighter-rouge">"B"</code> en <code class="language-plaintext highlighter-rouge">"b"</code>, etc).</li>
  <li>Acentos del tipo <code class="language-plaintext highlighter-rouge">"À"</code> y <code class="language-plaintext highlighter-rouge">"Ử"</code> convertidos a <code class="language-plaintext highlighter-rouge">"a"</code> y <code class="language-plaintext highlighter-rouge">"u"</code> respectivamente.</li>
</ul>

<p>Hay muchos más parámetros de Sphinx que puedes alterar para adecuarlo a tus necesidades. No tienes más que echar un vistazo en <a href="http://sphinxsearch.com/docs/">su documentación</a>. Y tú, ¿qué otros parámetros de Sphinx sueles modificar en tus proyectos?.</p>]]></content><author><name>Luis Mayoral</name><email>luis@luismayoral.com</email></author><category term="Desarrollo" /><category term="ruby" /><summary type="html"><![CDATA[A lo largo de estos años he realizado una buena cantidad de proyectos cuyas búsquedas se apoyaban en el excelente motor [Sphinx](http://sphinxsearch.com/). Me gustaría aprovechar esta entrada para compartir algunas de las configuraciones más habituales que he utilizado. Todas ellas están pensadas para añadir a vuestra sección development o production, según corresponda, en el fichero config/sphinx.yml si usáis Thinking Sphinx como gema para interactuar con Sphinx desde Ruby.]]></summary></entry></feed>