<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1437970354124720603</id><updated>2012-01-27T22:11:31.231-03:00</updated><category term='pdflatex'/><category term='rubygame'/><category term='dentista'/><category term='scholar'/><category term='pydev'/><category term='ingenio'/><category term='erlang'/><category term='bouncer'/><category term='seguridad'/><category term='latex'/><category term='benedicto xvi'/><category term='gracioso'/><category term='soja'/><category term='hosting'/><category term='regexp'/><category term='analytics'/><category term='paver'/><category term='tokenizer'/><category term='cs'/><category term='wipe'/><category term='glorieta'/><category term='firefox'/><category term='alfredo'/><category term='diarrea'/><category term='raphaeljs'/><category term='calefón'/><category term='git'/><category term='fabric'/><category term='ocd'/><category term='bibtex'/><category term='haskell'/><category term='e4x'/><category term='angina'/><category term='público'/><category term='video'/><category term='servlet'/><category term='server room'/><category term='xss'/><category term='vim'/><category term='eclipse'/><category term='c++'/><category term='dengue'/><category term='chiste'/><category term='rant'/><category term='sh'/><category term='humor'/><category term='reversing'/><category term='nicolás'/><category term='facebook'/><category term='papa'/><category term='hacklu'/><category term='java'/><category term='x11'/><category term='vmware'/><category term='ligamento'/><category term='acm'/><category term='aureliax'/><category term='inauguración'/><category term='catarsis'/><category term='cloud'/><category term='bash'/><category term='markaby'/><category term='lenguajes'/><category term='c'/><category term='tcp/ip'/><category term='android'/><category term='mousehole'/><category term='svg'/><category term='dns'/><category term='visualización'/><category term='html'/><category term='marketing'/><category term='sinatra'/><category term='lyx'/><category term='ubuntu'/><category term='rap'/><category term='operación'/><category term='rhino'/><category term='pentest'/><category term='rapidito'/><category term='svn'/><category term='google'/><category term='bindiff'/><category term='ruby'/><category term='monkeypatch'/><category term='csrf'/><category term='tango'/><category term='proxy'/><category term='advisory'/><category term='javascript'/><category term='canción'/><category term='dia'/><category term='perl'/><category term='efímero'/><category term='indent'/><category term='github'/><category term='conducto'/><category term='youtube'/><category term='balancer'/><category term='música'/><category term='turbodiff'/><category term='viaje'/><category term='logo'/><category term='arte'/><category term='ratzinger'/><category term='command_injection'/><category term='política'/><category term='bizarro'/><category term='commonjs'/><category term='python'/><category term='jetty'/><category term='dubai'/><category term='speedy'/><category term='consorcio'/><category term='rack-test'/><category term='firewall'/><category term='caricaturas'/><category term='csv'/><category term='new york'/><category term='wave'/><category term='atlantic city'/><category term='history channel'/><category term='rake'/><category term='abstracto'/><category term='pugliese'/><category term='paloma'/><category term='linux'/><category term='conferencia'/><category term='hack'/><category term='proceedings'/><category term='cloud computing'/><category term='php'/><category term='libertad'/><category term='fiebre'/><category term='gpf'/><category term='filadelfia'/><category term='lisp'/><category term='visio'/><category term='biblia'/><category term='x'/><category term='xorg'/><category term='dibujo'/><category term='phishing'/><category term='telefónica'/><category term='appengine'/><category term='wireless'/><category term='charla'/><category term='euler'/><category term='servers'/><category term='twitter'/><category term='privado'/><category term='windows7'/><category term='zip'/><category term='reflexión'/><title type='text'>aurelianito</title><subtitle type='html'>Blog de Aureliano Calvo. 
Aureliano Calvo's blog.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default?start-index=101&amp;max-results=100'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>193</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-8188462322099960073</id><published>2012-01-26T10:01:00.001-03:00</published><updated>2012-01-26T10:03:16.257-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='libertad'/><category scheme='http://www.blogger.com/atom/ns#' term='chiste'/><title type='text'>Porque defiendo la libertad de expresión quiero que sigamos pudiendo ver este chiste</title><content type='html'>&lt;a href="http://3.bp.blogspot.com/-VrtiRbaWkWA/TyFO94A0C2I/AAAAAAAAAJo/63MeE1nbjIs/s1600/AN-ADVENTURE-OF-DAVID-GHETTO_LG.JPG"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 139px;" src="http://3.bp.blogspot.com/-VrtiRbaWkWA/TyFO94A0C2I/AAAAAAAAAJo/63MeE1nbjIs/s400/AN-ADVENTURE-OF-DAVID-GHETTO_LG.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5701925428142541666" /&gt;&lt;/a&gt;&lt;br /&gt;No dejemos que ninguna corporación nos quite nuestra libertad de expresión.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-8188462322099960073?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/8188462322099960073/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=8188462322099960073' title='6 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/8188462322099960073'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/8188462322099960073'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2012/01/porque-defiendo-la-libertad-de.html' title='Porque defiendo la libertad de expresión quiero que sigamos pudiendo ver este chiste'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-VrtiRbaWkWA/TyFO94A0C2I/AAAAAAAAAJo/63MeE1nbjIs/s72-c/AN-ADVENTURE-OF-DAVID-GHETTO_LG.JPG' height='72' width='72'/><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-535766945186729389</id><published>2012-01-14T15:06:00.002-03:00</published><updated>2012-01-14T15:17:57.561-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tango'/><title type='text'>¿En qué pensar cuándo bailamos tango?</title><content type='html'>Algo que es muy común cuando uno lleva a una principiante es que "baile sola". O sea, que da pasos que no son marcados. ¿Por qué? Creo que es el miedo al vacío, a que había que hacer algo en ese compás y el paso que le enseñaron era ése.&lt;br /&gt;Poder esperar hasta el siguiente paso, manteniendo el equilibrio, no es fácil. Y a mi me gusta mucho hacer pausas cuando bailo y pasar 2 o 3 compases sin pisar (o sea, conservando el peso de los pies tanto míos como los de mi pareja). Entonces estuve buscando alguna forma de poder ayudar a que puedan estar sin pisar, cosa que hace que yo disfrute más del baile y que ellas bailen mejor (y, espero, que lo disfruten también). A lo que llegué, es que están demasiado enfocadas en los pasos. Creo que esto es algo común tanto para cuando llevamos como para cuando somos llevados.&lt;br /&gt;Mi contrapropuesta es que pensemos en otra cosa. Pensemos en nuestra pareja de baile y como interactúa con nosotros. En el calor que se siente en las partes del cuerpo que están en contacto. Brazo con espalda, mano con mano, pecho con pecho, panza con panza, etc. Y hagamos eso todo el tiempo. Pensemos en cómo va variando cuando hacemos diferentes pasos, con la respiración. Si nos concentramos, a veces también podemos sentir los latidos del corazón.&lt;br /&gt;Lamentablemente, cuando llevamos tenemos otras responsabilidades. Manejar el espacio y la circulación en la pista. Empezar y terminar las frases de la música. Preveer el final para no quedar pagando. Pero si tenés la suerte de estar siguiendo, podés entregarte 100% a sentir a tu pareja de baile, que es lo más lindo del tango.&lt;br /&gt;Nos vemos en la milonga,&lt;br /&gt;Aureliano.&lt;br /&gt;PD: No, no doy clases de tango.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-535766945186729389?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/535766945186729389/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=535766945186729389' title='2 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/535766945186729389'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/535766945186729389'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2012/01/en-que-pensar-cuando-bailamos-tango.html' title='¿En qué pensar cuándo bailamos tango?'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-2529935072991064764</id><published>2011-12-13T01:20:00.002-03:00</published><updated>2011-12-13T01:29:21.586-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='humor'/><title type='text'>Que llore</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-9HkIKw8uGjo/TubSzOxA8eI/AAAAAAAAAJI/h9jAjeMnt-I/s1600/294067_255862474447874_191027897597999_824341_1593624159_n.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 300px;" src="http://1.bp.blogspot.com/-9HkIKw8uGjo/TubSzOxA8eI/AAAAAAAAAJI/h9jAjeMnt-I/s400/294067_255862474447874_191027897597999_824341_1593624159_n.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5685463357180670434" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-2529935072991064764?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/2529935072991064764/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=2529935072991064764' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/2529935072991064764'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/2529935072991064764'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2011/12/que-llore.html' title='Que llore'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-9HkIKw8uGjo/TubSzOxA8eI/AAAAAAAAAJI/h9jAjeMnt-I/s72-c/294067_255862474447874_191027897597999_824341_1593624159_n.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-2680466877394430438</id><published>2011-12-12T18:42:00.003-03:00</published><updated>2011-12-12T21:44:20.745-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='visualización'/><category scheme='http://www.blogger.com/atom/ns#' term='seguridad'/><category scheme='http://www.blogger.com/atom/ns#' term='aureliax'/><category scheme='http://www.blogger.com/atom/ns#' term='turbodiff'/><category scheme='http://www.blogger.com/atom/ns#' term='bindiff'/><title type='text'>El plagio es la forma más sincera de halago</title><content type='html'>Hoy salió la &lt;a href="http://blog.zynamics.com/2011/12/05/bindiff-4-0-available-today"&gt;versión 4.0 de bindiff&lt;/a&gt;, y le incluyeron un feature que se llama "Combined visualization of two flowgraphs" que se parece mucho a lo que &lt;a href="http://corelabs.coresecurity.com/index.php?module=Wiki&amp;action=view&amp;type=publication&amp;name=Showing_differences_between_disassembled_functions"&gt;presenté en Hack.lu 2010&lt;/a&gt; (y que presenté anteriormente &lt;a href="http://aurelianito.blogspot.com/2010/10/presentacion-en-hacklu.html"&gt;en este blog&lt;/a&gt;). De todas maneras, me parece que les faltó ir hasta el fondo y unir cada par de basic-blocks en uno solo (si alguien de Zynamics ve este blog, miren mi paper para ver cómo hacerlo).&lt;br /&gt;&lt;br /&gt;Happy hacking,&lt;br /&gt;Aureliano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-2680466877394430438?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/2680466877394430438/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=2680466877394430438' title='2 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/2680466877394430438'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/2680466877394430438'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2011/12/el-plagio-es-la-forma-mas-sincera-de.html' title='El plagio es la forma más sincera de halago'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-950678065808661028</id><published>2011-12-08T09:45:00.006-03:00</published><updated>2011-12-08T09:55:07.732-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='history channel'/><category scheme='http://www.blogger.com/atom/ns#' term='glorieta'/><category scheme='http://www.blogger.com/atom/ns#' term='dentista'/><category scheme='http://www.blogger.com/atom/ns#' term='bizarro'/><category scheme='http://www.blogger.com/atom/ns#' term='tango'/><title type='text'>Un día bizarro</title><content type='html'>Ayer fue un día bizarro. A la mañana participé de la grabación de un programa del History Channel que se llama "Super Humanos" o algo así. En el mismo estuve con 2 amigos evaluando a &lt;a href="http://www.jaimegarciaserrano.com/"&gt;Jaime García Serrano&lt;/a&gt;, que calculó raíces cuadradas, logaritmos, funciones trigonométricas, las inversas de las trigonométricas y factoriales, mientras nosotros teníamos que decir si lo calculaba bien o no, mirando los resultados en una compu.&lt;br /&gt;Salí corriendo porque a la tarde tenía otro compromiso. A las 14.15 tenía turno para que me saquen una muela de juicio. Me sacaron la muela y ahora estoy tomando antibióticos y analgésicos, y el helado es mi principal alimento.&lt;br /&gt;A la noche fui a La Glorieta, donde bailé algunos tangos y me encontré con amigos.&lt;br /&gt;Al final, me fui a dormir.&lt;br /&gt;PD: Me dijeron que el programa sale en abril.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-950678065808661028?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/950678065808661028/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=950678065808661028' title='1 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/950678065808661028'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/950678065808661028'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2011/12/un-dia-bizarro.html' title='Un día bizarro'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-2775018449953472051</id><published>2011-11-21T20:43:00.003-03:00</published><updated>2011-11-21T20:52:46.202-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bash'/><category scheme='http://www.blogger.com/atom/ns#' term='zip'/><category scheme='http://www.blogger.com/atom/ns#' term='svn'/><title type='text'>Zipeando working directories</title><content type='html'>Para zippear un directorio controlado por svn sin poner la info administrativa de svn podés ejecutar este comando en bash y va a andar:&lt;br /&gt;&lt;pre&gt;find . -not \( -type d -name ".svn" -prune \) -type f -print | zip -@ ~/zip_file_name&lt;/pre&gt;&lt;br /&gt;Happy hacking,&lt;br /&gt;Aureliano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-2775018449953472051?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/2775018449953472051/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=2775018449953472051' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/2775018449953472051'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/2775018449953472051'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2011/11/para-zippear-un-directorio-controlado.html' title='Zipeando working directories'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-8448338264030506969</id><published>2011-11-17T20:08:00.001-03:00</published><updated>2011-11-17T20:09:44.067-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='calefón'/><category scheme='http://www.blogger.com/atom/ns#' term='biblia'/><category scheme='http://www.blogger.com/atom/ns#' term='tango'/><title type='text'>La biblia y el calefón</title><content type='html'>EXPLICACIÓN DE UNA COMPARACIÓN EN LA LETRA CAMBALACHE&lt;br /&gt;&lt;br /&gt;¡EXACTA REAL DEMOSTRABLE Y CREIBLE;PARECE MENTIRA QUE JAMAS LO EXPLICARAN LOS MILES DE ESCRIBAS, LITERATOS E INTELECTUALOIDES QUE DICEN " ESTUDIAR EL TANGO"&lt;br /&gt; &lt;br /&gt;La Biblia y el Calefón –&lt;br /&gt;Se habla de ello y la mayoría no sabe de qué se trata:&lt;br /&gt;He aquí la historia de un hecho de la vida cotidiana, que acontecía en la ciudad de Buenos Aires –no sé si en otros lugares pasaba o no–, y que explica el porqué de la aparentemente surrealista asociación de la Biblia junto al calefón que aparece en el tango "Cambalache", cuyas letra y música fueron compuestas por Enrique Santos Discépolo en 1935.&lt;br /&gt;&lt;br /&gt;La historia tiene relación con los baños, la higiene personal y la forma de realizarla; y como no se me escapa que algunos lectores pueden ser jóvenes y pueden no haber conocido otro tipo de baños que los que se estila usar en la actualidad al menos en el mundo occidental y cristiano, voy a recordar primero un par de datos que considero necesario sean tenidos en cuenta.&lt;br /&gt;&lt;br /&gt;Los baños que conocemos y que en algunos lugares son llamados 'completos', es decir, los que constan como mínimo de retrete inodoro, lavabo y ducha (algunos exquisitos, como el irresponsable que escribe, exigen que además tenga bidet –artefacto desconocido en muchos sitios–) son relativamente nuevos.&lt;br /&gt;&lt;br /&gt;Hasta finales del siglo XIX se utilizaban bacinillas (también llamadas ‘tazas de noche’), cuyos contenidos eran arrojados por las ventanas al grito de "agua va"; y antes aún, letrinas, que solían estar en los fondos de las casas.&lt;br /&gt;&lt;br /&gt;En Buenos Aires coexistieron bacinillas y letrinas hasta principios del siglo XX, época en que las familias ‘acomodadas’ comenzaron a instalar baños.&lt;br /&gt;&lt;br /&gt;Luego el uso de baños se generalizó y se empezó a construirlos en todas las viviendas, aun en las más modestas. El sencillo 'miniambiente' constaba al menos de retrete y lavabo y si los lujuriosos dueños de casa gustaban de practicar la morisca costumbre de lavarse todo el cuerpo más o menos seguido, y si además tenían medios económicos suficientes como para costearse ese capricho, los baños también tenían una ducha. Claro, si había una ducha era necesario calentar el agua, así que al lado de la ducha se instalaba un calefón.&lt;br /&gt;&lt;br /&gt;Sin embargo, el papel higiénico tardó en obtener su carta de ciudadanía &lt;br /&gt;&lt;br /&gt;para poder trabajar en limpio en estas sucias tierras y aun cuando apareció era bastante caro y no estaba al alcance de todas las familias, las cuales se veían obligadas a utilizar para esos fines sanitarios el vulgar papel de diario o, en su defecto, cualquier otro.&lt;br /&gt;&lt;br /&gt;Por supuesto, eran muy estimados los papeles más sedosos, así que los sufridos usuarios trataban de conseguir en las verdulerías y fruterías los papeles con los que venían envueltas las manzanas y otros productos de campo.&lt;br /&gt;&lt;br /&gt;Otro muy apreciado era el llamado ‘papel biblia’, especialmente delgado y suave.&lt;br /&gt;&lt;br /&gt;Ahora bien, ya por entonces existía la Sociedad Bíblica, una de cuyas misiones parece ser la de difundir la Biblia protestante, para lo cual regalaba ejemplares del sagrado libro –en la actualidad, lo sigue haciendo–.&lt;br /&gt;&lt;br /&gt;Pues, muchos de los habitantes de Buenos Aires deben de haber parecido devotos creyentes, ya que aceptaban de continuo esas gentilezas, y que siendo mayoría la grey católica, lo mismo pasaban y retiraban la biblia protestante tantas veces como sabían que la Sociedad las tenía en obsequio en las calles, plazas o en su sede central .&lt;br /&gt;LA BIBLIA Y EL CALEFÓN&lt;br /&gt;&lt;br /&gt;Sin embargo, cuentan los hombres dignos de fe (aunque Alá sabe más) que quienes obtenían esas Biblias les perforaban una tapa y las colgaban de un gancho de alambre, al lado del calefón, cerca del retrete, e iban arrancando las suaves hojas para usarlas como papel higiénico.&lt;br /&gt;&lt;br /&gt;En este hecho se habría inspirado Enrique Santos Discépolo para decir con elegancia propia de un grande autor:&lt;br /&gt;&lt;br /&gt;Igual que en la vidriera&lt;br /&gt;irrespetuosa&lt;br /&gt;de los cambalaches&lt;br /&gt;se ha mezclao la vida,&lt;br /&gt;&lt;br /&gt;Y HERIDA POR UN SABLE SIN REMACHE&lt;br /&gt;VES LLORAR LA BIBLIA&lt;br /&gt;JUNTO AL CALEFÓN.&lt;br /&gt;&lt;br /&gt;Edgardo G. Maggiora&lt;br /&gt;BARILOCHE&lt;br /&gt;&lt;br /&gt;Gracias Mayca por este material!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-8448338264030506969?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/8448338264030506969/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=8448338264030506969' title='2 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/8448338264030506969'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/8448338264030506969'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2011/11/la-biblia-y-el-calefon.html' title='La biblia y el calefón'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-9123435395189406698</id><published>2011-11-17T17:49:00.001-03:00</published><updated>2011-11-17T17:50:46.794-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ingenio'/><title type='text'>Cómo, esto también es matemática?</title><content type='html'>Un post de este blog se va para arriba. Los &lt;a href="http://aurelianito.blogspot.com/2008/12/nmeros-de-aure.html"&gt;números de Aure&lt;/a&gt; aparecen en el &lt;a href="http://cms.dm.uba.ar/material/paenza/libro6"&gt;último libro de Paenza&lt;/a&gt;. Mirá la página 224.&lt;br /&gt;&lt;br /&gt;Happy hacking,&lt;br /&gt;Aureliano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-9123435395189406698?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/9123435395189406698/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=9123435395189406698' title='2 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/9123435395189406698'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/9123435395189406698'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2011/11/como-esto-tambien-es-matematica.html' title='Cómo, esto también es matemática?'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-5521534195203863205</id><published>2011-11-07T19:08:00.001-03:00</published><updated>2011-11-07T19:10:05.999-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='video'/><title type='text'>Cortando video con ffmpeg</title><content type='html'>Para cortar video usando ffmpeg hay un comando que me resultó re-práctico. Lo pongo acá para acordarme.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;ffmpeg -sameq -ss [start_seconds] -t [duration_seconds] -i [input_file] [outputfile]&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Fuente: &lt;a href="http://www.joeldare.com/wiki/video:cut_video_with_ffmpeg"&gt;joeldare&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-5521534195203863205?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/5521534195203863205/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=5521534195203863205' title='3 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/5521534195203863205'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/5521534195203863205'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2011/11/cortando-video-con-ffmpeg.html' title='Cortando video con ffmpeg'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-5508252632094270818</id><published>2011-09-13T09:01:00.002-03:00</published><updated>2011-09-13T09:01:56.460-03:00</updated><title type='text'>Feliz día</title><content type='html'>Feliz &lt;a href="http://es.wikipedia.org/wiki/D%C3%ADa_de_los_Programadores"&gt;día del programador&lt;/a&gt;!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-5508252632094270818?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/5508252632094270818/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=5508252632094270818' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/5508252632094270818'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/5508252632094270818'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2011/09/feliz-dia.html' title='Feliz día'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-3364759832599739546</id><published>2011-08-28T09:48:00.001-03:00</published><updated>2011-08-28T09:50:39.835-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='caricaturas'/><category scheme='http://www.blogger.com/atom/ns#' term='humor'/><title type='text'>Analogías</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://ano.lolcathost.org/pics/comprension.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 540px;" src="http://ano.lolcathost.org/pics/comprension.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Vía: &lt;a href="http://ano.lolcathost.org/finger.mhtml?id=comprension.png"&gt;http://ano.lolcathost.org/finger.mhtml?id=comprension.png&lt;/a&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-3364759832599739546?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/3364759832599739546/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=3364759832599739546' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/3364759832599739546'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/3364759832599739546'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2011/08/analogias.html' title='Analogías'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-1043621116465789674</id><published>2011-08-25T16:52:00.002-03:00</published><updated>2011-08-25T16:55:51.302-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='música'/><category scheme='http://www.blogger.com/atom/ns#' term='paloma'/><category scheme='http://www.blogger.com/atom/ns#' term='server room'/><category scheme='http://www.blogger.com/atom/ns#' term='servers'/><category scheme='http://www.blogger.com/atom/ns#' term='canción'/><title type='text'>Por si alguna vez entran palomas en su server room.....</title><content type='html'>adapté una conocida canción para conmemorarlo. Pongo acá abajo letra y acordes.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Mim                  Sim         Mim&lt;br /&gt;Se equivocó la paloma, se equivocaba,&lt;br /&gt;en vez de al norte, al server room&lt;br /&gt;Do                           Sim       MIm&lt;br /&gt;pensó que el cable era paja, se equivocaba&lt;br /&gt;&lt;br /&gt;          Sol&lt;br /&gt;Pensó que Sun era el cielo,&lt;br /&gt;               Mim&lt;br /&gt;la mudanza era mañana,&lt;br /&gt; Do         Lam      MIm&lt;br /&gt;se equivocaba, se equivocaba&lt;br /&gt;           Lam    Si7  Mim&lt;br /&gt;que las bandejas manzanas,&lt;br /&gt;       Lam Si7   Mim   Re&lt;br /&gt;que la calor la nevada,&lt;br /&gt;        Sol              Si7  Lam&lt;br /&gt;se equivocaba, se equivocaba.&lt;br /&gt;&lt;br /&gt;        Si7      MIm&lt;br /&gt;Que tu CAT,era tu blusa,&lt;br /&gt;Do     Si7      Do      Re&lt;br /&gt;que tu bandeja, su casa,&lt;br /&gt;          Mim Re        Mim   Mi7-Lam&lt;br /&gt;se equivocaba, se equivocaba,&lt;br /&gt;     Re7          Sol    Mim  Lam&lt;br /&gt;ella se durmio en la silla,&lt;br /&gt;         Si7        Mim&lt;br /&gt;tu en la cumbre de un ra-ack.&lt;br /&gt;&lt;br /&gt;        Si7      MIm&lt;br /&gt;Que tu CAT,era tu blusa,&lt;br /&gt;Do     Si7      Do      Re&lt;br /&gt;que tu bandeja, su casa,&lt;br /&gt;       Do                Mim&lt;br /&gt;se equivocaba, se equivocaba.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Enjoy!,&lt;br /&gt;Aureliano&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-1043621116465789674?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/1043621116465789674/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=1043621116465789674' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/1043621116465789674'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/1043621116465789674'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2011/08/por-si-alguna-vez-entran-palomas-en-su.html' title='Por si alguna vez entran palomas en su server room.....'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-4058895227361213742</id><published>2011-08-04T18:09:00.004-03:00</published><updated>2011-08-04T18:26:18.564-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fiebre'/><category scheme='http://www.blogger.com/atom/ns#' term='angina'/><category scheme='http://www.blogger.com/atom/ns#' term='diarrea'/><category scheme='http://www.blogger.com/atom/ns#' term='conducto'/><title type='text'>Qué semana de mierda!</title><content type='html'>&lt;ul&gt;&lt;li&gt;El domingo me levanté con 38 grados de fiebre. Como estaba enfermo no pude ver a mi hijo. A la noche tenía casi 39 de fiebre.&lt;/li&gt;&lt;li&gt;El lunes seguía con fiebre, así que falté al laburo. Como no me mejoraba, llamé al médico. El médico vino, me dijo que tenía una angina, me recetó un antibiótico y me dijo que tomara ibuprofeno para bajar la fiebre. Fui a la farmacia, compré todo, volví a casa, tomé el antibiótico y el ibuprofeno. Me bajó la temperatura y me fui a dormir.&lt;/li&gt;&lt;li&gt;Me desperté el martes a las 2 AM todo sudado y cagado de frío. Cuando vi que no podía dormirme del frío me levanté para sacarme la ropa toda mojada y me agarraron unos espasmos impresionantes. No podía dejar de temblar. Así que me cambié la remera y me volví a acostar. Seguía cagandome de frío.&lt;/li&gt;&lt;li&gt;Pasó como una hora y se me pasó el tembleque. Así que agarré el termómetro. Marcó 39.3. Me tomé otro ibuprofeno y me fui a dormir.&lt;/li&gt;&lt;li&gt;El martes me desperté sin fiebre, pero al mediodía ya estaba con fiebre de nuevo. A la noche me tomé otro ibuprofeno y el antibiótico. Como seguía hecho mierda, de nuveo no vi a mi hijo.&lt;/li&gt;&lt;li&gt;El miércoles me desperté un poco mejor, sin fiebre. Pero después del mediodía me agarró diarrea. Por suerte había tomado mucha agua y me la pude bancar. A la noche no tomé el ibuprofeno y me fui a dormir.&lt;/li&gt;&lt;li&gt;El jueves (hoy) me sentí un poco mejor, así que ¡fui a hacerme un tratamiento de conducto!. Ahora estoy bajo los efectos de los analgésicos recetados por la dentista.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Así que sumarizando mi semana queda así: angina, fiebre, diarrea y conducto.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Hasta la próxima,&lt;/div&gt;&lt;div&gt;Aureliano.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-4058895227361213742?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/4058895227361213742/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=4058895227361213742' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/4058895227361213742'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/4058895227361213742'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2011/08/que-semana-de-mierda.html' title='Qué semana de mierda!'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-31675681631065757</id><published>2011-07-23T11:46:00.003-03:00</published><updated>2011-07-23T11:49:21.507-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='humor'/><title type='text'>El mundo según San Francisco</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://s3.amazonaws.com/data.tumblr.com/tumblr_l9twmfBGN81qzbemso1_1280.png?AWSAccessKeyId=AKIAJ6IHWSU3BX3X7X3Q&amp;Expires=1311518592&amp;Signature=88MIt45XSQHckEBzqOxoQCyZcSA%3D"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 611px; " src="http://s3.amazonaws.com/data.tumblr.com/tumblr_l9twmfBGN81qzbemso1_1280.png?AWSAccessKeyId=AKIAJ6IHWSU3BX3X7X3Q&amp;Expires=1311518592&amp;Signature=88MIt45XSQHckEBzqOxoQCyZcSA%3D" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Fuente: &lt;a href="http://generic1.tumblr.com/post/1250019294/the-world-according-to-san-francisco-i-was"&gt;acá&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-31675681631065757?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/31675681631065757/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=31675681631065757' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/31675681631065757'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/31675681631065757'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2011/07/el-mundo-segun-san-francisco.html' title='El mundo según San Francisco'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-1043690729326729574</id><published>2011-06-17T11:23:00.004-03:00</published><updated>2011-06-18T14:28:59.654-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fabric'/><category scheme='http://www.blogger.com/atom/ns#' term='paver'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Integración paver fabric</title><content type='html'>&lt;span style="font-weight:bold;"&gt;Update:&lt;/span&gt; Parece que se viene esto como &lt;a href="http://groups.google.com/group/paver/browse_thread/thread/6800bcf91044aceb?hl=en&amp;pli=1"&gt;parte de paver 1.1&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Hice un pequeño hack y ahora puedo usar el API de &lt;a href="http://fabfile.org"&gt;fabric&lt;/a&gt; cuando escribo tasks de &lt;a href="http://paver.github.com"&gt;paver&lt;/a&gt; y que la tarea se ejecute una vez para cada host.&lt;br /&gt;&lt;br /&gt;Para hacer eso, hice un decorator, que se llama multihost y es así:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;from fabric import state, network&lt;br /&gt;&lt;br /&gt;def multi_host(f):&lt;br /&gt;    """\&lt;br /&gt;Run the decorated function for each host in options.get("host_strings").&lt;br /&gt;&lt;br /&gt;Will use the private key set in options.pk if set.&lt;br /&gt;"""&lt;br /&gt;    def decoratee(options):&lt;br /&gt;        for host_string in options.get("host_strings"):&lt;br /&gt;            network.interpret_host_string(host_string)&lt;br /&gt;            pk = options.get("pk", None) &lt;br /&gt;            state.env.key_filename = [pk] if pk else None&lt;br /&gt;            f(options)&lt;br /&gt;            &lt;br /&gt;    decoratee.func_name = f.func_name&lt;br /&gt;            &lt;br /&gt;    return cmdopts((&lt;br /&gt;        ("pk=", None, "Private key file"),&lt;br /&gt;    ))(decoratee)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;El uso es así:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;from paver.easy import task, needs&lt;br /&gt;from fabric import api&lt;br /&gt;&lt;br /&gt;@task&lt;br /&gt;def find_hosts(options):&lt;br /&gt;  options["host_strings"] = ["host1", "user@host2", "user2@host3:2222"]&lt;br /&gt;&lt;br /&gt;@task&lt;br /&gt;@needs("find_hosts")&lt;br /&gt;@multi_host&lt;br /&gt;def remote_hello_world(options):&lt;br /&gt;  api.run("echo hello world")&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Happy hacking,&lt;br /&gt;Aureliano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-1043690729326729574?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/1043690729326729574/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=1043690729326729574' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/1043690729326729574'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/1043690729326729574'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2011/06/integracion-paver-fabric.html' title='Integración paver fabric'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-524330626778001266</id><published>2011-06-14T11:13:00.007-03:00</published><updated>2011-06-14T11:44:30.881-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='x11'/><category scheme='http://www.blogger.com/atom/ns#' term='x'/><category scheme='http://www.blogger.com/atom/ns#' term='eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='pydev'/><category scheme='http://www.blogger.com/atom/ns#' term='hack'/><title type='text'>Tamaños de ventanas extraños en eclipse y workaround</title><content type='html'>En el laburo desde hace un tiempo estoy haciendo el experimento de correr varias VMs con los distintos proyectos en los que trabajo. Por lo tanto tengo varias VMs distintas (guests) corriendo que se conectan usando X a mi host.&lt;br /&gt;&lt;br /&gt;En una de ellas tengo eclipse instalado con pydev. Y como host tengo un Windows 7 con X-Ming como server X. Y anda todo bastante bien salvo porque algunas ventanas de diálogo se van agrandando de formas extrañas hasta que se vuelve imposible usarlas. Y aparte, no sé por qué, no se pueden resizear usando el mouse (que sí se puede si lo corrés en Windows, gnome o kde normalmente).&lt;br /&gt;&lt;br /&gt;Por lo tanto, busqué y encontré un workaround al problema, y edito a mano algunos archivos de configuración del workspace de eclipse para cambiar estos tamaños a una medida razonable para mi y para que quede documentado lo dejo anotado acá.&lt;br /&gt;&lt;br /&gt;En el archivo &lt;tt&gt;./org.eclipse.ui.ide/dialog_settings.xml&lt;/tt&gt; sección &lt;tt&gt;DialogBoundsSettings&lt;/tt&gt; setié:&lt;br /&gt;&lt;pre&gt;&amp;lt;item value="1024" key="DIALOG_WIDTH"/&gt;&lt;br /&gt;&amp;lt;item value="768" key="DIALOG_HEIGHT"/&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;En el archivo &lt;tt&gt;org.eclipse.ui.workbench.texteditor/dialog_settings.xml&lt;/tt&gt; sección &lt;tt&gt;org.eclipse.ui.texteditor.FindReplaceDialog_dialogBounds&lt;/tt&gt; setié:&lt;br /&gt;&lt;pre&gt;&amp;lt;item value="1024" key="DIALOG_WIDTH"/&gt;&lt;br /&gt;&amp;lt;item value="768" key="DIALOG_HEIGHT"/&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;En el archivo &lt;tt&gt;org.eclipse.search/dialog_settings.xml&lt;/tt&gt; sección &lt;tt&gt;DialogBounds_SearchDialog&lt;/tt&gt; setié:&lt;br /&gt;&lt;pre&gt;&amp;lt;item value="1024" key="DIALOG_WIDTH"/&gt;&lt;br /&gt;&amp;lt;item value="768" key="DIALOG_HEIGHT"/&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Y por último, en el archivo &lt;tt&gt;org.tigris.subversion.subclipse.ui/dialog_settings.xml&lt;/tt&gt; hice algo un toque distinto, seteando en la sección &lt;tt&gt;Workbench&lt;/tt&gt; esto:&lt;br /&gt;&lt;pre&gt;&amp;lt;item value="1280" key="CommitDialog.size.x"/&gt;&lt;br /&gt;&amp;lt;item value="768" key="CommitDialog.size.y"/&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Por supuesto, todos estos archivos hay que tocarlos con el eclipse &lt;span style="font-weight:bold;"&gt;apagado&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Happy hacking,&lt;br /&gt;Aureliano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-524330626778001266?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/524330626778001266/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=524330626778001266' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/524330626778001266'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/524330626778001266'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2011/06/tamanos-de-ventanas-extranos-en-eclipse.html' title='Tamaños de ventanas extraños en eclipse y workaround'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-4142031446254825364</id><published>2011-06-06T16:00:00.004-03:00</published><updated>2011-06-06T16:05:38.013-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cloud'/><category scheme='http://www.blogger.com/atom/ns#' term='pentest'/><category scheme='http://www.blogger.com/atom/ns#' term='seguridad'/><category scheme='http://www.blogger.com/atom/ns#' term='cloud computing'/><title type='text'>Sé lo que hiciste el verano pasado</title><content type='html'>Hola,&lt;br /&gt;&lt;br /&gt;estuve ocupado últimamente así que no pude darle mucha pelota a mi blog. Hoy suspendo este silencio para contarles que estuve haciendo en el laburo los últimos meses. Lo que hicimos es un servicio para pentestear instancias y páginas web que estén hosteadas en AWS. Aunque mucho el nombre no me gusta (lo eligió la gente de marketing), se llama Core CloudInspect y está &lt;a href="https://www.corecloudinspect.com"&gt;acá&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;La idea es hacer pentests en 5 clicks y 20 dólares y, los primeros 3 son gratarola!.&lt;br /&gt;&lt;br /&gt;Happy hacking,&lt;br /&gt;Aureliano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-4142031446254825364?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/4142031446254825364/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=4142031446254825364' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/4142031446254825364'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/4142031446254825364'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2011/06/se-lo-que-hiciste-el-verano-pasado.html' title='Sé lo que hiciste el verano pasado'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-2322265466705992161</id><published>2010-10-28T20:34:00.003-03:00</published><updated>2010-10-28T20:39:41.884-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='visualización'/><category scheme='http://www.blogger.com/atom/ns#' term='seguridad'/><category scheme='http://www.blogger.com/atom/ns#' term='hacklu'/><category scheme='http://www.blogger.com/atom/ns#' term='reversing'/><category scheme='http://www.blogger.com/atom/ns#' term='hack'/><title type='text'>Presentación en Hack.lu</title><content type='html'>Hace unas horas presenté en &lt;a href="http://2010.hack.lu"&gt;Hack.lu&lt;/a&gt; mi charla sobre &lt;a href="http://corelabs.coresecurity.com/index.php?module=Wiki&amp;action=view&amp;type=tool&amp;name=aureliax"&gt;aureliax&lt;/a&gt;. Aureliax es un software que sirve para mostrar diferencias entre diferentes versiones de una misma función, que es mostrada mediante un grafo de basic blocks. En cuanto pueda voy a poner on-line el white paper que explica cómo funciona y cuál es la base teórica que lo sustenta.&lt;br /&gt;Por ahora estoy contento y cansado (acá en Luxemburgo son las 2 menos 20), y mañana tengo un largo día por delante.&lt;br /&gt;&lt;br /&gt;Happy hacking,&lt;br /&gt;Aureliano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-2322265466705992161?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/2322265466705992161/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=2322265466705992161' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/2322265466705992161'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/2322265466705992161'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2010/10/presentacion-en-hacklu.html' title='Presentación en Hack.lu'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-41075933887077980</id><published>2010-09-21T14:26:00.004-03:00</published><updated>2010-09-21T14:30:40.658-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='música'/><title type='text'>Bajo el farol</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_vrWP6mUamXY/TJjrVc0gwaI/AAAAAAAAAII/WxILB-gzyhw/s1600/bajo+el+farol+caretas.jpg"&gt;&lt;img style="cursor: pointer; width: 266px; " src="http://4.bp.blogspot.com/_vrWP6mUamXY/TJjrVc0gwaI/AAAAAAAAAII/WxILB-gzyhw/s400/bajo+el+farol+caretas.jpg" alt="" id="BLOGGER_PHOTO_ID_5519420097088766370" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Les recomiendo que vayan a ver esto. Yo fui la vez anterior, en abril, estuvo buenísimo y voy a ir de nuevo.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-41075933887077980?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/41075933887077980/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=41075933887077980' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/41075933887077980'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/41075933887077980'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2010/09/bajo-el-farol.html' title='Bajo el farol'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_vrWP6mUamXY/TJjrVc0gwaI/AAAAAAAAAII/WxILB-gzyhw/s72-c/bajo+el+farol+caretas.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-1711781370265945265</id><published>2010-09-04T12:34:00.003-03:00</published><updated>2010-09-04T12:36:44.608-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pugliese'/><category scheme='http://www.blogger.com/atom/ns#' term='tango'/><title type='text'>Cómo trato de bailar a Pugliese</title><content type='html'>&lt;ul&gt;&lt;li&gt;Escuchando el fraseo y siguiendo su intensidad.&lt;/li&gt;&lt;li&gt;Escuchando el compás, que aunque no siempre se note siempre está ahí.&lt;/li&gt;&lt;li&gt;Variando estilo y distancia del abrazo, pasando desde un tango milonguero, al tango salón y a veces hasta con abrazos típicos del tango nuevo. Todo dentro de un mismo tema.&lt;/li&gt;&lt;li&gt;Dando tiempo a la mujer para que también pueda hacer su propia interpretación y lucirse. Generalmente esos tiempos se dan en las partes más piano, que generalmente son a cargo del violín y/o en el final de la frase musical.&lt;/li&gt;&lt;li&gt;Es muy raro que haga paradas y el sanguchito, aunque si me parece que mi pareja lo quiere puedo llegar a marcar uno. &lt;/li&gt;&lt;li&gt;Giro en la parte ligada y camino usando contratiempos en la parte marcada.&lt;/li&gt;&lt;li&gt;En las pausas no hay cambios de peso, pero trato de mantener un dejo del movimiento que veníamos haciendo justo antes.&lt;/li&gt;&lt;li&gt;La elección del paso y la intensidad depende de la música, la pareja y la pista.&lt;/li&gt;&lt;li&gt;El final generalmente incluye una corrida de 5 o 7 pasos hasta el acorde dominante y quitar toda la tensión cuando suena la tónica suavemente en el piano.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Happy dancing,&lt;/div&gt;&lt;div&gt;Aureliano.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-1711781370265945265?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/1711781370265945265/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=1711781370265945265' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/1711781370265945265'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/1711781370265945265'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2010/09/como-trato-de-bailar-pugliese.html' title='Cómo trato de bailar a Pugliese'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-3416934771321764131</id><published>2010-07-30T19:22:00.001-03:00</published><updated>2010-07-30T19:31:43.700-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='abstracto'/><category scheme='http://www.blogger.com/atom/ns#' term='arte'/><category scheme='http://www.blogger.com/atom/ns#' term='efímero'/><title type='text'>Arte efímero</title><content type='html'>&lt;a href="http://1.bp.blogspot.com/_vrWP6mUamXY/TFNSs6fYgOI/AAAAAAAAAH4/_HooH43BFFI/s1600/SANY0003.JPG"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 300px;" src="http://1.bp.blogspot.com/_vrWP6mUamXY/TFNSs6fYgOI/AAAAAAAAAH4/_HooH43BFFI/s400/SANY0003.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5499830501518115042" /&gt;&lt;/a&gt;&lt;br /&gt;Marcador al agua sobre pizarrón blanco&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-3416934771321764131?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/3416934771321764131/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=3416934771321764131' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/3416934771321764131'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/3416934771321764131'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2010/07/arte-efimero.html' title='Arte efímero'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_vrWP6mUamXY/TFNSs6fYgOI/AAAAAAAAAH4/_HooH43BFFI/s72-c/SANY0003.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-8879728795636873194</id><published>2010-07-12T00:42:00.003-03:00</published><updated>2010-07-12T00:46:25.682-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><title type='text'>Una pequeña delicia del JavaScript</title><content type='html'>Qué valor debería dar el siguiente código:&lt;br /&gt;&lt;pre&gt;"aDb".replace("D","$$")&lt;/pre&gt;&lt;br /&gt;Si pensaron "a$$b" se equivocaron. Da "a$b" (con un solo $).&lt;br /&gt;Para que de el valor que esperaba ("a$$b") hay que hacer este hack:&lt;br /&gt;&lt;pre&gt;"aDb".replace("D",function() { return "$$" })&lt;/pre&gt;&lt;br /&gt;¿Por qué?&lt;br /&gt;Ni idea, pero anda así en rhino y V8, así que debe estar en la especificación.&lt;br /&gt;&lt;br /&gt;Happy hacking,&lt;br /&gt;Aureliano&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-8879728795636873194?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/8879728795636873194/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=8879728795636873194' title='5 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/8879728795636873194'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/8879728795636873194'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2010/07/una-pequena-delicia-del-javascript.html' title='Una pequeña delicia del JavaScript'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-3551720283168513404</id><published>2010-06-01T11:59:00.004-03:00</published><updated>2010-06-01T12:35:02.669-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='svg'/><category scheme='http://www.blogger.com/atom/ns#' term='raphaeljs'/><title type='text'>Flechas con RaphaelJS</title><content type='html'>Me encontré con que no hay ningún método para dibujar flechas en raphaelJS, así que me puse las pilas y programé uno:&lt;pre&gt; /**&lt;br /&gt;   * Returns a path in form of an arrow&lt;br /&gt;   * @param arrowSize is the size of the arrow end. Defaults to 10 pixels.&lt;br /&gt;   */&lt;br /&gt; Raphael.fn.arrow = function(x1, y1, x2, y2, arrowSize) {&lt;br /&gt;  var arrowSize = arrowSize || 10&lt;br /&gt;  var l = Math.sqrt( Math.pow( x2 - x1, 2 ) + Math.pow( y2 - y1, 2 ) )  &lt;br /&gt;  var xStep = (x2 - x1) / l&lt;br /&gt;  var yStep = (y2 - y1) / l&lt;br /&gt;&lt;br /&gt;  // arrow point ends&lt;br /&gt;  var arrX1 = x2 + arrowSize * (yStep - xStep) / 2&lt;br /&gt;  var arrY1 = y2 + arrowSize * (-xStep - yStep) / 2 &lt;br /&gt;  var arrX2 = x2 + arrowSize * (-yStep - xStep) / 2&lt;br /&gt;  var arrY2 = y2 + arrowSize * (xStep - yStep) / 2&lt;br /&gt;        &lt;br /&gt;  var path = ["M", x1, y1, "L", x2, y2, //main line&lt;br /&gt;      "M", arrX1, arrY1, "L", x2, y2, "L", arrX2, arrY2] //arrow end&lt;br /&gt;  &lt;br /&gt;  return this.path(path.join(" ")) &lt;br /&gt; }&lt;/pre&gt;&lt;br /&gt;Para usarlo hay que hacer:&lt;pre&gt;&lt;br /&gt;var r = Raphael(....)&lt;br /&gt;.....&lt;br /&gt;var arrow = r.arrow(150,100,250,300)&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-3551720283168513404?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/3551720283168513404/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=3551720283168513404' title='2 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/3551720283168513404'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/3551720283168513404'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2010/06/flechas-con-raphaeljs.html' title='Flechas con RaphaelJS'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-6130315344149435658</id><published>2010-05-19T11:59:00.004-03:00</published><updated>2010-05-19T14:33:34.037-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='eclipse'/><title type='text'>Cambiando el context-root</title><content type='html'>Esto es lo que tuve que hacer para que la webapp en java que estoy desarrollando con eclipse 3.5 y web tools platform ande en el context-path root:&lt;div&gt;&lt;ul&gt;&lt;li&gt;Abrir el archivo &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;.settings/org.eclipse.wst.common.component&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Cambiar la entrada &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&amp;lt;property name="context-root" value="risky"&gt;&lt;/property&gt;&lt;/span&gt; por &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&amp;lt;property name="context-root" value="/"&gt;&lt;/property&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Happy hacking,&lt;/div&gt;&lt;div&gt;Aureliano&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-6130315344149435658?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/6130315344149435658/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=6130315344149435658' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/6130315344149435658'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/6130315344149435658'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2010/05/cambiando-el-context-root.html' title='Cambiando el context-root'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-601687090833504838</id><published>2010-04-27T22:25:00.002-03:00</published><updated>2010-04-27T22:28:51.172-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='twitter'/><title type='text'>Ahora tengo twitter</title><content type='html'>Saqué cuenta en twitter y voy a empezar a twittear (¿se escribe así?). Si quieren seguirme mi usuario es &lt;a href="http://www.twitter.com/aurelianito"&gt;aurelianito&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;En cuanto tenga alguna idea de lo que opino de twitter la mando por acá.&lt;br /&gt;&lt;br /&gt;Happy hacking,&lt;br /&gt;Aureliano&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-601687090833504838?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/601687090833504838/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=601687090833504838' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/601687090833504838'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/601687090833504838'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2010/04/ahora-tengo-twitter.html' title='Ahora tengo twitter'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-8968860727365244047</id><published>2010-04-06T23:45:00.005-03:00</published><updated>2010-04-07T16:43:21.018-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='música'/><title type='text'>Bajo el farol</title><content type='html'>Update: si quieren pueden escuchar algunas canciones del show en su &lt;a href="http://www.myspace.com/bajoelfarol"&gt;página de myspace&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Este sábado 10 de abril a las 23:30 hs mi amiga y gran cantante Natalia Iñón presenta su espectáculo "Bajo el farol" en la Casona del Teatro, que queda en Corrientes 1975 (Ciudad de Buenos Aires). El repertorio está compuesto por canciones de Edith Piaf, Marlene Dietrich y algunos tangos. Les sugiero que vayan a escucharla ya que es una cantante exquisita.&lt;div&gt;Nos vemos allá,&lt;/div&gt;&lt;div&gt;Aureliano&lt;/div&gt;&lt;br /&gt;&lt;img src="http://2.bp.blogspot.com/_vrWP6mUamXY/S7vzybdnQnI/AAAAAAAAAHw/Ux_uBkyo3sc/s1600/bajo+el+farol+casona.jpg" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-8968860727365244047?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/8968860727365244047/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=8968860727365244047' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/8968860727365244047'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/8968860727365244047'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2010/04/bajo-el-farol.html' title='Bajo el farol'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_vrWP6mUamXY/S7vzybdnQnI/AAAAAAAAAHw/Ux_uBkyo3sc/s72-c/bajo+el+farol+casona.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-3513826943408849448</id><published>2010-04-04T08:45:00.003-03:00</published><updated>2010-04-04T08:49:31.785-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ratzinger'/><category scheme='http://www.blogger.com/atom/ns#' term='reflexión'/><category scheme='http://www.blogger.com/atom/ns#' term='papa'/><category scheme='http://www.blogger.com/atom/ns#' term='marketing'/><category scheme='http://www.blogger.com/atom/ns#' term='política'/><category scheme='http://www.blogger.com/atom/ns#' term='benedicto xvi'/><title type='text'>Que la maquinaria de marketing del Vaticano no nos haga olvidar</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_vrWP6mUamXY/S7h8O35Yv9I/AAAAAAAAAHg/UstTvB_5MIE/s1600/ratzinger-palpatine.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 203px;" src="http://2.bp.blogspot.com/_vrWP6mUamXY/S7h8O35Yv9I/AAAAAAAAAHg/UstTvB_5MIE/s320/ratzinger-palpatine.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5456247543524016082" /&gt;&lt;/a&gt;&lt;br /&gt;Recordemos: "El Papa Ratzinger es Palpatine"&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Vía: &lt;a href="http://rinzewind.org/archives/2005/04/19/parecidos-razonables-2/"&gt;rinzewind.org&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-3513826943408849448?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/3513826943408849448/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=3513826943408849448' title='2 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/3513826943408849448'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/3513826943408849448'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2010/04/que-la-maquinaria-de-marketing-del.html' title='Que la maquinaria de marketing del Vaticano no nos haga olvidar'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_vrWP6mUamXY/S7h8O35Yv9I/AAAAAAAAAHg/UstTvB_5MIE/s72-c/ratzinger-palpatine.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-8273733477078130370</id><published>2010-03-08T01:26:00.004-03:00</published><updated>2010-03-08T01:38:44.981-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ocd'/><category scheme='http://www.blogger.com/atom/ns#' term='reflexión'/><title type='text'>Pequeñas cosas que me molestan</title><content type='html'>&lt;div&gt;Un compañero de laburo dice que las personas que nos dedicamos a la programación y aledaños generalmente tenemos alguna tendencia al desorden obsesivo-compulsivo. Yo hice mi mea-culpa y acá escribo una lista de pequeñas cosas que creo que me molestan por tener algo de esa tendencia:&lt;/div&gt;&lt;ul&gt;&lt;li&gt;Salir a comer y que algunos pidan postre y otros no.&lt;/li&gt;&lt;li&gt;Salir a comer y que algunos pidan entrada y otros no.&lt;/li&gt;&lt;li&gt;Jugar fútbol en cantidades impares (ej: 5 contra 4)&lt;/li&gt;&lt;li&gt;Que los platos colocados en el escurridor no estén cada uno en una rendija y ocupando rendijas consecutivas desde el extremo más lejano del mismo.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;¿Qué cosas equivalentes les molestan a ustedes?,&lt;/div&gt;&lt;div&gt;Aureliano&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-8273733477078130370?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/8273733477078130370/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=8273733477078130370' title='2 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/8273733477078130370'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/8273733477078130370'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2010/03/pequenas-cosas-que-me-molestan.html' title='Pequeñas cosas que me molestan'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-5539210154815775396</id><published>2010-03-03T17:21:00.003-03:00</published><updated>2010-03-03T17:38:02.651-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='latex'/><category scheme='http://www.blogger.com/atom/ns#' term='proceedings'/><category scheme='http://www.blogger.com/atom/ns#' term='acm'/><category scheme='http://www.blogger.com/atom/ns#' term='lyx'/><title type='text'>Configurando lyx para escribir proceedings de ACM</title><content type='html'>Hoy configuré el &lt;a href="http://www.lyx.org/"&gt;lyx&lt;/a&gt; para que use la &lt;a href="http://www.acm.org/sigs/publications/proceedings-templates"&gt;clase de LaTeX que piden para los proceedings de ACM&lt;/a&gt; y fue bastante más molesto de lo que esperaba. Esto lo hice en un ubuntu  9.10 casi pelado (con lyx y no mucho más). Acá les cuento los pasos:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Copiá &lt;a href="http://www.acm.org/sigs/publications/acm_proc_article-sp.cls"&gt;acm_proc_article-sp.cls&lt;/a&gt; a $HOME/texmf/tex/latex&lt;/li&gt;&lt;li&gt;Corré "texhash ." en $HOME/texmf/tex/latex&lt;/li&gt;&lt;li&gt;Poné en ./lyx/layouts el archivo &lt;a href="http://pastie.org/852352"&gt;acm_proc_article-sp.layout&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Arrancá lyx, andá a Tools-&gt;Reconfigure y volvé a arrancar lyx.&lt;/li&gt;&lt;li&gt;Ahora en Document-&gt;Settings-&gt;Document Class está disponible la clase de los proceedings de ACM bajo el nombre "ACM Sig Proceedings".&lt;/li&gt;&lt;/ol&gt;Happy hacking,&lt;br /&gt;Aureliano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-5539210154815775396?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/5539210154815775396/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=5539210154815775396' title='1 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/5539210154815775396'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/5539210154815775396'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2010/03/configurando-lyx-para-escribir.html' title='Configurando lyx para escribir proceedings de ACM'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-8821387744141460043</id><published>2010-02-22T22:37:00.001-03:00</published><updated>2010-02-22T22:39:55.452-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='facebook'/><category scheme='http://www.blogger.com/atom/ns#' term='público'/><category scheme='http://www.blogger.com/atom/ns#' term='privado'/><title type='text'>Una reflexión sobre facebook</title><content type='html'>&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', Verdana, Arial, sans-serif; font-size: small; color: rgb(51, 51, 51); line-height: 18px; "&gt;El otro día estaba cenando con unos amigos y estabamos hablando de &lt;a href="http://aurelianito.blogspot.com/2009/12/como-me-echaron-de-facebook.html"&gt;como me echaron de FB&lt;/a&gt;. Y &lt;a href="http://estudiodenoche.blogspot.com/"&gt;un amigo&lt;/a&gt; hizo una analogía re-buena.&lt;br /&gt;¿Qué pasa si te ponés a bailar en los pasillos de un shopping? Lo más probable es que venga alguien de seguridad y te pida "amablemente" que te retires del lugar. En cambio si te ponés a bailar en el medio de una plaza, más allá de algunas miradas raras no debería pasarte nada.&lt;br /&gt;¿Y por qué? El asunto es que nos olvidamos que el shopping &lt;b&gt;no es&lt;/b&gt; un espacio público sino un espacio privado al que te dejan entrar cuando quieren, como quieren y en el que pueden aplicar toda clase de reglas arbitrarias. En cambio, una plaza es un lugar mucho más público.&lt;br /&gt;Y con facebook pasa lo mismo. Es un espacio que nos olvidamos que es privado, pero lo es. Entonces nos molesta que nos apliquen reglas raras.&lt;br /&gt;Ojalá estas cosas que me pasaron a mi (y a otros) sirvan para que entendamos la diferencia.&lt;/span&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', Verdana, Arial, sans-serif; font-size: small; color: rgb(51, 51, 51); line-height: 18px; "&gt;Happy hacking,&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', Verdana, Arial, sans-serif; font-size: small; color: rgb(51, 51, 51); line-height: 18px; "&gt;Aureliano.&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-8821387744141460043?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/8821387744141460043/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=8821387744141460043' title='2 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/8821387744141460043'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/8821387744141460043'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2010/02/una-reflexion-sobre-facebook.html' title='Una reflexión sobre facebook'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-5018185068261501545</id><published>2010-02-09T16:30:00.003-03:00</published><updated>2010-02-09T16:40:43.906-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pdflatex'/><category scheme='http://www.blogger.com/atom/ns#' term='latex'/><category scheme='http://www.blogger.com/atom/ns#' term='dia'/><category scheme='http://www.blogger.com/atom/ns#' term='gpf'/><title type='text'>Exportando gráficos en dia a pdflatex</title><content type='html'>&lt;ol&gt;&lt;li&gt;Hacé tu gráfico en &lt;a href="http://live.gnome.org/Dia"&gt;dia&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Exportarlo como "LaTeX PGF macros"&lt;/li&gt;&lt;li&gt;En el principio de tu .tex poné:&lt;/li&gt;&lt;pre&gt;\usepackage{tikz}&lt;/pre&gt;&lt;li&gt;En el lugar donde quieras poner tu caption poné&lt;pre&gt;\begin{figure}&lt;br /&gt;\centering&lt;br /&gt;\input{archivo_exportado_de_dia.tex}&lt;br /&gt;\caption{Acá va el caption}&lt;br /&gt;\label{aca_va_la_label}&lt;br /&gt;\end{figure}&lt;br /&gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Compilá el .tex principal con pdflatex&lt;/li&gt;&lt;li&gt;Miralo con tu visor de pdfs favorito&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;Happy hacking,&lt;/div&gt;&lt;div&gt;Aureliano.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-5018185068261501545?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/5018185068261501545/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=5018185068261501545' title='3 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/5018185068261501545'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/5018185068261501545'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2010/02/exportando-graficos-en-dia-pdflatex.html' title='Exportando gráficos en dia a pdflatex'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-2158408036508308767</id><published>2010-02-07T00:40:00.008-03:00</published><updated>2010-02-07T00:52:30.588-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='gracioso'/><category scheme='http://www.blogger.com/atom/ns#' term='lenguajes'/><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><category scheme='http://www.blogger.com/atom/ns#' term='c'/><title type='text'>Como ven los fanas de un lenguaje a los otros</title><content type='html'>Mirar lambda the ultimate es siempre interesante. Y esta vez me crucé con una perlita que quiero compartir con ustedes:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://i.imgur.com/1gF1j.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 800px;" src="http://i.imgur.com/1gF1j.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-2158408036508308767?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/2158408036508308767/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=2158408036508308767' title='2 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/2158408036508308767'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/2158408036508308767'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2010/02/como-ven-los-fanas-de-un-lenguaje-los.html' title='Como ven los fanas de un lenguaje a los otros'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-6742344875752128150</id><published>2010-02-05T13:02:00.003-03:00</published><updated>2010-02-05T13:21:23.999-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='csrf'/><category scheme='http://www.blogger.com/atom/ns#' term='command_injection'/><category scheme='http://www.blogger.com/atom/ns#' term='advisory'/><category scheme='http://www.blogger.com/atom/ns#' term='xss'/><category scheme='http://www.blogger.com/atom/ns#' term='seguridad'/><title type='text'>Segundo advisory</title><content type='html'>Ayer salió mi &lt;a href="http://www.coresecurity.com/content/landesk-csrf-vulnerability"&gt;segundo advisory&lt;/a&gt;. Lo que encontramos con Manuk es que parte administrativa de la aplicación LanDesk Manager tiene un &lt;a href="http://cwe.mitre.org/data/definitions/352.html"&gt;cross-site request forgery&lt;/a&gt; que hace que si enganchás a un administrador se pueda hacer un &lt;a href="http://cwe.mitre.org/data/definitions/79.html"&gt;cross-site scripting&lt;/a&gt; no persistente y, aún más divertido, hacer un &lt;a href="http://cwe.mitre.org/data/definitions/78.html"&gt;OS command injection&lt;/a&gt;.&lt;br /&gt;Aún más divertido, es que se puede usar &lt;a href="http://en.wikipedia.org/wiki/Modprobe"&gt;modprobe&lt;/a&gt; y cargar módulos de kernel de linux que uplodee usando el command injection.&lt;br /&gt;Más detalles &lt;a href="http://www.coresecurity.com/content/landesk-csrf-vulnerability"&gt;en la página de Core&lt;/a&gt;.&lt;br /&gt;Happy hacking,&lt;br /&gt;Aureliano&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-6742344875752128150?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/6742344875752128150/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=6742344875752128150' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/6742344875752128150'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/6742344875752128150'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2010/02/segundo-advisory.html' title='Segundo advisory'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-3034821659115607343</id><published>2010-01-27T23:27:00.004-03:00</published><updated>2010-01-27T23:39:09.230-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='rhino'/><title type='text'>Simplificando</title><content type='html'>Ayer me di cuenta que no necesito rehacer los classloaders de java para cargar scripts de JavaScript, ya que puedo usarlos y son todo lo flexibles que necesito (y más). Inclusive, si por una de esas casualidades llegara a hace falta, creo que puedo hacer uno en rhino y todo. Por lo tanto decidí que mi lógica para cargar módulos tenía una indirección de más (la lista de loaders) y lo cambié para que use el classloader y listo. Fíjense en la nueva implementación de loadMod y como se simplificó el uso de los loaders.&lt;br /&gt;En la versión del código que estoy usando ahora, también hice que los módulos se carguen un toque distintos para que haya mejores stack-traces (ese cambio está en la función require). Bueno, abajo pongo el código:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;/*  &lt;br /&gt; * Does not support relative paths (yet?).&lt;br /&gt; * Can be invoked by several threads.&lt;br /&gt; * &lt;br /&gt; * Uses the classloader to fetch js modules.&lt;br /&gt; */&lt;br /&gt;var require = function (id) {&lt;br /&gt; &lt;br /&gt; try {&lt;br /&gt;&lt;br /&gt;  require.lock.lock() // Avoid threading issues while loading modules.&lt;br /&gt;  &lt;br /&gt;  if (!require.modules[id]) {&lt;br /&gt;&lt;br /&gt;   var modCode = require.loadMod(id)&lt;br /&gt;&lt;br /&gt;   var exports = {}&lt;br /&gt;   require.modules[id] = exports&lt;br /&gt;   var module = {&lt;br /&gt;    id : id&lt;br /&gt;   }&lt;br /&gt;   &lt;br /&gt;   var context = {&lt;br /&gt;    exports: exports,&lt;br /&gt;    module: module,&lt;br /&gt;   }&lt;br /&gt;   &lt;br /&gt;   if(!modCode) {&lt;br /&gt;    throw new require.RequireError(id, "module not found")&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   org.mozilla.javascript.Context.getCurrentContext().evaluateString(&lt;br /&gt;    context, &lt;br /&gt;    modCode,&lt;br /&gt;    id,&lt;br /&gt;    1,&lt;br /&gt;    null&lt;br /&gt;   )&lt;br /&gt;   /*&lt;br /&gt;   Old style invocation, should work in the browser but has worst error messages.&lt;br /&gt;   &lt;br /&gt;   var f = new Function("require", "exports", "module", modCode)&lt;br /&gt;   f.call(context, require, exports, module) */&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  return require.modules[id]&lt;br /&gt; } catch (x) {&lt;br /&gt;  if (x instanceof require.RequireError) {&lt;br /&gt;   throw x&lt;br /&gt;  } else {&lt;br /&gt;   throw new require.RequireError(id, x)&lt;br /&gt;  }&lt;br /&gt; } finally {&lt;br /&gt;  require.lock.unlock()&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;require.loaders = []&lt;br /&gt;require.modules = {}&lt;br /&gt;require.lock = new java.util.concurrent.locks.ReentrantLock()&lt;br /&gt;&lt;br /&gt;var RequireErrorProto = {}&lt;br /&gt;&lt;br /&gt;require.RequireError = function(moduleId, cause) {&lt;br /&gt; this.moduleId = moduleId&lt;br /&gt; this.cause = cause&lt;br /&gt; &lt;br /&gt;}&lt;br /&gt;require.RequireError.prototype = RequireErrorProto&lt;br /&gt;require.RequireError.prototype.toString = function() {&lt;br /&gt; return "Error loading " + this.moduleId + ( this.cause ? ". Cause: " + this.cause : "" )&lt;br /&gt;}&lt;br /&gt;require.RequireError.prototype.name = "RequireError"&lt;br /&gt;&lt;br /&gt;require.load = function(path) {&lt;br /&gt; return java.lang.Class.forName("java.lang.String").getResourceAsStream(path)&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;require.loadMod = function(id) {&lt;br /&gt; function path(id) {&lt;br /&gt;  return "/" + id + ".js"&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; function readFromStream(stream) {&lt;br /&gt;  var io = java.io&lt;br /&gt;  var reader = new io.BufferedReader( new io.InputStreamReader(stream) )&lt;br /&gt;  try {&lt;br /&gt;   var stringBuffer = new java.lang.StringBuffer()&lt;br /&gt;   &lt;br /&gt;   var line = ""&lt;br /&gt;   while( line = reader.readLine()) {&lt;br /&gt;    stringBuffer.append(line)&lt;br /&gt;    stringBuffer.append("\n")&lt;br /&gt;   }&lt;br /&gt;   &lt;br /&gt;   return stringBuffer.toString()&lt;br /&gt;  } finally {&lt;br /&gt;   reader.close()&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; var stream = require.load(path(id))&lt;br /&gt; if (!stream) { return null }&lt;br /&gt; &lt;br /&gt; return readFromStream(stream)&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * Resets the module cache. &lt;br /&gt; * &lt;br /&gt; * It will reload all the modules. Old modules referenced will still be working.&lt;br /&gt; */&lt;br /&gt;require.reset = function() {&lt;br /&gt; try {&lt;br /&gt;  require.lock.lock()&lt;br /&gt;  require.modules = {}&lt;br /&gt; } finally {&lt;br /&gt;  require.lock.unlock()&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Este cambio también simplifico el RhinoServlet, y ahora toma sus scripts del classpath también.&lt;br /&gt;&lt;br /&gt;Happy hacking,&lt;br /&gt;Aureliano&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-3034821659115607343?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/3034821659115607343/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=3034821659115607343' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/3034821659115607343'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/3034821659115607343'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2010/01/simplificando.html' title='Simplificando'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-4567527058396444047</id><published>2010-01-25T00:16:00.003-03:00</published><updated>2010-01-25T00:24:49.868-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='csv'/><title type='text'>Parseando CSVs con una expresión de JavaScript</title><content type='html'>Para parsear un CSV con datos numéricos hay que hacer esto:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;text.split("\n").map( function(r){ &lt;br /&gt;  return r.split(",").map( function(d) { &lt;br /&gt;    return parseFloat(d)&lt;br /&gt;  } ) &lt;br /&gt;} )&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Esto solo anda si tu intérprete de JavaScript tiene Array.prototype.map definido. Sino antes de eso tenés que definirlo así:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Array.prototype.map = Array.prototype.map || function( f ) {&lt;br /&gt;  var r = []&lt;br /&gt;  for (var i=0; i&amp;lt;this.length; i++) {&lt;br /&gt;    r[i] = f(this[i])&lt;br /&gt;  }&lt;br /&gt;  return r&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-4567527058396444047?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/4567527058396444047/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=4567527058396444047' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/4567527058396444047'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/4567527058396444047'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2010/01/parseando-csvs-con-una-expresion-de.html' title='Parseando CSVs con una expresión de JavaScript'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-8513980390369129706</id><published>2010-01-18T19:58:00.001-03:00</published><updated>2010-01-18T19:59:50.863-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='video'/><category scheme='http://www.blogger.com/atom/ns#' term='youtube'/><title type='text'>Aure x 8</title><content type='html'>&lt;object width="640" height="505"&gt;&lt;param name="movie" value="http://www.youtube.com/v/OlsxKh8fsYQ&amp;hl=en_US&amp;fs=1&amp;rel=0"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/OlsxKh8fsYQ&amp;hl=en_US&amp;fs=1&amp;rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="505"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;By Futo &amp; Albinoni.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-8513980390369129706?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/8513980390369129706/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=8513980390369129706' title='2 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/8513980390369129706'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/8513980390369129706'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2010/01/aure-x-8.html' title='Aure x 8'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-5799856819480444399</id><published>2010-01-17T20:40:00.003-03:00</published><updated>2010-01-17T20:45:26.070-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='e4x'/><category scheme='http://www.blogger.com/atom/ns#' term='rhino'/><title type='text'>Generando xhtml con e4x</title><content type='html'>Primero hay que setear el namespace por default:&lt;br /&gt;&lt;pre&gt;default xml namespace = "http://www.w3.org/1999/xhtml"&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Para generar elementos, uso esta función:&lt;br /&gt;&lt;pre&gt;function elem(name) { return &lt;{name} /&gt; }&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Para setear un attributo cualquiera esta función:&lt;br /&gt;&lt;pre&gt;function attr(elem, key, value) { elem["@"+key] = value }&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Y puedo usar elem.appendChild para agregar como hijo de un elemento otro o un texto como string que es escapado.&lt;br /&gt;&lt;br /&gt;Happy hacking,&lt;br /&gt;Aureliano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-5799856819480444399?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/5799856819480444399/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=5799856819480444399' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/5799856819480444399'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/5799856819480444399'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2010/01/generando-xhtml-con-e4x.html' title='Generando xhtml con e4x'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-5934373164343787442</id><published>2010-01-12T13:53:00.003-03:00</published><updated>2010-01-12T13:57:44.910-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='latex'/><category scheme='http://www.blogger.com/atom/ns#' term='scholar'/><category scheme='http://www.blogger.com/atom/ns#' term='bibtex'/><title type='text'>Entrada de BibTeX en Google Scholar</title><content type='html'>Si estás logueado en Google, podés setear Google Scholar para que te muestre las entradas de bibtex.&lt;br /&gt;Para eso tenés que ir a Scholar Preferences -&gt; Bibliography Manager y elegir Show links to import citations into BibTeX.&lt;br /&gt;&lt;br /&gt;Happy hacking,&lt;br /&gt;Aureliano&lt;br /&gt;&lt;br /&gt;(Sacado de &lt;a href="http://sftc.wordpress.com/2007/03/08/bibtex-straight-from-google-scholar/"&gt;acá&lt;/a&gt;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-5934373164343787442?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/5934373164343787442/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=5934373164343787442' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/5934373164343787442'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/5934373164343787442'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2010/01/entrada-de-bibtex-en-google-scholar.html' title='Entrada de BibTeX en Google Scholar'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-3688036035591783584</id><published>2010-01-10T21:14:00.004-03:00</published><updated>2010-01-10T21:36:35.735-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='commonjs'/><category scheme='http://www.blogger.com/atom/ns#' term='servlet'/><category scheme='http://www.blogger.com/atom/ns#' term='rhino'/><category scheme='http://www.blogger.com/atom/ns#' term='appengine'/><title type='text'>Implementación de require en Rhino</title><content type='html'>Hoy estuve hackeando un toque y modifiqué el RhinoServlet que les mostré en &lt;a href="http://aurelianito.blogspot.com/2010/01/2-servlets-para-correr-javascript.html"&gt;este post&lt;/a&gt; para poder tener módulos en Javascript. El API que hice es un subset de lo definido en &lt;a href="http://commonjs.org/specs/modules/1.0.html"&gt;CommonJS&lt;/a&gt;. En particular, soporta require pero no los paths relativos de módulos (o sea, los que empiezan con . o ..). También le puse a todo un lock para que pueda usarse en un entorno concurrente, pero si un módulo tarda mucho en cargarse puede llegar a ser un problema.&lt;br /&gt;Lo que me parece más interesante de mi prototipo es que se pueden agregar fácilmente nuevos loaders de módulos de JavasScript. Ya vienen por defecto loaders para cargar desde el classpath y desde la webapp, pero si quieren poder poner sus módulos en /WEB-INF/example, alcanza con agregar una línea en init.js:&lt;br /&gt;&lt;pre&gt;require.loaders.push( require.stdLoader(servlet.servletContext, "/WEB-INF/example/"))&lt;/pre&gt;&lt;br /&gt;Bueno, basta de cháchara, acá está la versión modificada del RhinoServlet:&lt;br /&gt;&lt;pre&gt;package aure.jslib;&lt;br /&gt;&lt;br /&gt;import java.io.IOException;&lt;br /&gt;import java.io.InputStream;&lt;br /&gt;import java.io.InputStreamReader;&lt;br /&gt;import java.io.Reader;&lt;br /&gt;&lt;br /&gt;import javax.servlet.ServletConfig;&lt;br /&gt;import javax.servlet.ServletException;&lt;br /&gt;import javax.servlet.http.HttpServlet;&lt;br /&gt;import javax.servlet.http.HttpServletRequest;&lt;br /&gt;import javax.servlet.http.HttpServletResponse;&lt;br /&gt;&lt;br /&gt;import org.mozilla.javascript.Context;&lt;br /&gt;import org.mozilla.javascript.Scriptable;&lt;br /&gt;import org.mozilla.javascript.ScriptableObject;&lt;br /&gt;&lt;br /&gt;public class RhinoServlet extends HttpServlet {&lt;br /&gt; private static final long serialVersionUID = 1L;&lt;br /&gt; private Scriptable initialScope = null;&lt;br /&gt; &lt;br /&gt; public void runJs(Context cx, String scriptLocation, Scriptable scope) throws IOException {&lt;br /&gt;  &lt;br /&gt;  InputStream is = this.getClass().getResourceAsStream(scriptLocation);&lt;br /&gt;  if( is == null) {&lt;br /&gt;   is = this.getServletContext().getResourceAsStream("/WEB-INF/js/" + scriptLocation);&lt;br /&gt;  }&lt;br /&gt;  Reader jsReader = new InputStreamReader(is);&lt;br /&gt;  &lt;br /&gt;  cx.evaluateReader(scope, jsReader, scriptLocation, 1, null);&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; public static void addJavaObjectToScope(Scriptable scope, String name, Object obj) {&lt;br /&gt;  ScriptableObject.putProperty(scope, name, Context.javaToJS(obj, scope) );&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; @Override&lt;br /&gt; public void init(ServletConfig config) throws ServletException {&lt;br /&gt;  super.init(config);&lt;br /&gt;  Context cx = Context.enter();&lt;br /&gt;  try {&lt;br /&gt;   Scriptable scope = cx.initStandardObjects();&lt;br /&gt;   addJavaObjectToScope(scope, "servlet", this);&lt;br /&gt;   addJavaObjectToScope(scope, "config", config);&lt;br /&gt;   &lt;br /&gt;   this.runJs(cx, "initRequire.js", scope);&lt;br /&gt;   this.runJs(cx, "init.js", scope);&lt;br /&gt;   &lt;br /&gt;   this.initialScope = scope;&lt;br /&gt;  } catch (IOException e) {&lt;br /&gt;   throw new ServletException(e);&lt;br /&gt;  } finally {&lt;br /&gt;   Context.exit();&lt;br /&gt;  } &lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; @Override&lt;br /&gt; protected void service(HttpServletRequest request, HttpServletResponse response)&lt;br /&gt;   throws ServletException, IOException {&lt;br /&gt;  Context cx = Context.enter();&lt;br /&gt;  try {&lt;br /&gt;   Scriptable scope = cx.initStandardObjects();&lt;br /&gt;   scope.setParentScope(this.initialScope);&lt;br /&gt;   &lt;br /&gt;   addJavaObjectToScope(scope, "request", request);&lt;br /&gt;   addJavaObjectToScope(scope, "response", response);&lt;br /&gt;   &lt;br /&gt;   this.runJs(cx, "start.js", scope);&lt;br /&gt;  } finally {&lt;br /&gt;   Context.exit();&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Noten que toqué el init para que agregue el require y cambié la forma de levantar javascript. Por otro lado este es el javascript en initRequire.js, que tiene la implementación del require:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;/* Based on http://www.davidflanagan.com/demos/require.js&lt;br /&gt; * but heavily modified.&lt;br /&gt; *  &lt;br /&gt; * Does not support relative paths (yet?).&lt;br /&gt; * Can be invoked by several threads.&lt;br /&gt; * &lt;br /&gt; * Uses the servletContext and the classloader to fetch js modules.&lt;br /&gt; */&lt;br /&gt;var logger = java.util.logging.Logger.getLogger("sarasa")&lt;br /&gt;&lt;br /&gt;var require = function (id) {&lt;br /&gt; &lt;br /&gt; try {&lt;br /&gt;&lt;br /&gt;  require.lock.lock() // Avoid threading issues while loading modules.&lt;br /&gt;  &lt;br /&gt;  if (!require.modules[id]) {&lt;br /&gt;&lt;br /&gt;   var modText = require.loadMod(id)&lt;br /&gt;&lt;br /&gt;   var context = {}&lt;br /&gt;   var exports = {}&lt;br /&gt;   require.modules[id] = exports&lt;br /&gt;   var module = {&lt;br /&gt;    id : id&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   var f = new Function("require", "exports", "module", modText)&lt;br /&gt;   f.call(context, require, exports, module)&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  return require.modules[id]&lt;br /&gt; } catch (x) {&lt;br /&gt;  throw new Error("Can't load module: " + id + ": " + x)&lt;br /&gt; } finally {&lt;br /&gt;  require.lock.unlock()&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;require.loaders = []&lt;br /&gt;require.modules = {}&lt;br /&gt;require.lock = new java.util.concurrent.locks.ReentrantLock()&lt;br /&gt;require.loadMod = function(id) {&lt;br /&gt; var modText = null&lt;br /&gt; var i = 0&lt;br /&gt; while (modText == null &amp;&amp; i &lt; require.loaders.length) {&lt;br /&gt;  modText = require.loaders[i](id)&lt;br /&gt;  i++&lt;br /&gt; }&lt;br /&gt; return modText&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Setup loaders for files in the classpath, files in WEB-INF and files in the&lt;br /&gt;// web-app (usually served to the client)&lt;br /&gt;require.stdLoader = function(source, prepend) {&lt;br /&gt; // Support functions&lt;br /&gt; function readFromStream(stream) {&lt;br /&gt;  var io = java.io&lt;br /&gt;  var reader = new io.BufferedReader( new io.InputStreamReader(stream) )&lt;br /&gt;  var stringBuffer = new java.lang.StringBuffer()&lt;br /&gt;  &lt;br /&gt;  var line = ""&lt;br /&gt;  while( line = reader.readLine()) {&lt;br /&gt;   stringBuffer.append(line)&lt;br /&gt;   stringBuffer.append("\n")&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  return stringBuffer.toString()&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; function path(id) {&lt;br /&gt;  return prepend + id + ".js"&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; var f = function(id) {&lt;br /&gt;  var stream = source.getResourceAsStream(path(id))&lt;br /&gt;  return stream ? readFromStream(stream) : null&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; return f&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;require.initStdLoaders = function() {&lt;br /&gt; // classpath loader&lt;br /&gt; require.loaders.push( this.stdLoader(servlet["class"], "/") )&lt;br /&gt; &lt;br /&gt; // web-app context loader&lt;br /&gt; require.loaders.push( this.stdLoader(servlet.servletContext, "/") )&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;require.initStdLoaders()&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Empecé a hacer esto mirando el código en &lt;a href="http://www.davidflanagan.com/demos/require.js"&gt;http://www.davidflanagan.com/demos/require.js&lt;/a&gt; pero al final quedó bastante distinto, sobre todo porque tiene la opción de tener muchos loaders.&lt;br /&gt;Las cosas que me quedan para hacer son hacer que acepte paths relativos (que para que sea thread-safe hace falta que haga algunos truquitos) y hacer que en vez de usar&lt;br /&gt;&lt;pre&gt;   var f = new Function("require", "exports", "module", modText)&lt;br /&gt;   f.call(context, require, exports, module)&lt;/pre&gt;&lt;br /&gt;para invocar el módulo haga algo usando el API de rhino para poder tener errores donde aparezca el nombre del módulo y el número de línea si hubo algún problema.&lt;br /&gt;&lt;br /&gt;Escucho comentarios y sugerencias.&lt;br /&gt;&lt;br /&gt;Happy hacking,&lt;br /&gt;Aureliano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-3688036035591783584?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/3688036035591783584/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=3688036035591783584' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/3688036035591783584'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/3688036035591783584'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2010/01/implementacion-de-require-en-rhino.html' title='Implementación de require en Rhino'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-7540048233147808108</id><published>2010-01-10T18:59:00.001-03:00</published><updated>2010-01-10T19:02:55.339-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='catarsis'/><category scheme='http://www.blogger.com/atom/ns#' term='eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='appengine'/><title type='text'>Eclipse plug-in para app-engine</title><content type='html'>¿Por qué te negás a usar dependencias de otros proyectos de eclipse?&lt;br /&gt;¿Por qué no recompilás bien cuando está corriendo el web-server en modo debug y uso resources de adentro del classpath?&lt;br /&gt;&lt;br /&gt;Bueno, por ahora son 2 problemas que creo poder "workarroundear". &lt;br /&gt;&lt;br /&gt;Happy hacking,&lt;br /&gt;Aureliano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-7540048233147808108?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/7540048233147808108/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=7540048233147808108' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/7540048233147808108'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/7540048233147808108'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2010/01/eclipse-plug-in-para-app-engine.html' title='Eclipse plug-in para app-engine'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-7353307727169625290</id><published>2010-01-08T11:47:00.004-03:00</published><updated>2010-01-08T11:59:51.996-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='hack'/><title type='text'>2 placas y default gateway</title><content type='html'>Hoy estuve configurando una VM con ubuntu que tiene una placa en modo bridged por DHCP y otra host-only estática. El problema que tuve fue que no encontraba la forma que la ruta por default sea la ruta por default que informa el dhcp. La solución que encontré fue hacer que la métrica de la ruta por default de la ip estática sea más grande.&lt;br /&gt;&lt;br /&gt;Este es el archivo /etc/network/interfaces que terminé usando:&lt;br /&gt;&lt;pre&gt;auto lo eth1 eth0&lt;br /&gt;iface lo inet loopback&lt;br /&gt;&lt;br /&gt;iface eth0 inet dhcp&lt;br /&gt;&lt;br /&gt;iface eth1 inet static&lt;br /&gt;        address 172.17.17.16&lt;br /&gt;        netmask 255.255.255.0&lt;br /&gt;        network 172.17.17.0&lt;br /&gt;        broadcast 172.17.17.255&lt;br /&gt;        gateway 172.17.17.1&lt;br /&gt;        metric 200&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Y la posta está en la última línea.&lt;br /&gt;&lt;br /&gt;Probé sacar la entrada de gateway y agregar una entrada borrando la ruta que me sobraba (up route del default gw 172.17.17.1) y no funcionó.&lt;br /&gt;&lt;br /&gt;Se les ocurre alguna otra forma de arreglar esto?&lt;br /&gt;&lt;br /&gt;Happy hacking,&lt;br /&gt;Aureliano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-7353307727169625290?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/7353307727169625290/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=7353307727169625290' title='1 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/7353307727169625290'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/7353307727169625290'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2010/01/2-placas-y-default-gateway.html' title='2 placas y default gateway'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-5178749719441092070</id><published>2010-01-05T01:16:00.004-03:00</published><updated>2010-01-05T01:33:23.275-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='servlet'/><category scheme='http://www.blogger.com/atom/ns#' term='rhino'/><title type='text'>2 servlets para correr javascript</title><content type='html'>Estuve con algo de tiempo y me puse a probar como hacer para ejecutar JavaScript en el server. E hice 2 implementaciones (o sea, 2 servlets programados en Java). La primera que hice usa javax.script (que viene por defecto en Java 6) y me parece que el API es más cómoda pero tiene 2 limitaciones que no me gustaron, &lt;a href="http://java.sun.com/javase/6/webnotes/#scripting"&gt;no se puede heredar de clases Java en JavaScript&lt;/a&gt; y no encontré cómo hacer para bindear un método de Java a JavaScript. Este es el código:&lt;br /&gt;&lt;pre&gt;package aure;&lt;br /&gt;&lt;br /&gt;import java.io.IOException;&lt;br /&gt;import java.io.InputStreamReader;&lt;br /&gt;import java.io.Reader;&lt;br /&gt;&lt;br /&gt;import javax.script.Bindings;&lt;br /&gt;import javax.script.ScriptContext;&lt;br /&gt;import javax.script.ScriptEngine;&lt;br /&gt;import javax.script.ScriptEngineManager;&lt;br /&gt;import javax.script.ScriptException;&lt;br /&gt;import javax.servlet.ServletConfig;&lt;br /&gt;import javax.servlet.ServletException;&lt;br /&gt;import javax.servlet.http.HttpServlet;&lt;br /&gt;import javax.servlet.http.HttpServletRequest;&lt;br /&gt;import javax.servlet.http.HttpServletResponse;&lt;br /&gt;&lt;br /&gt;public class JsServlet extends HttpServlet {&lt;br /&gt; private static final long serialVersionUID = 1L;&lt;br /&gt;&lt;br /&gt; private ScriptEngine jsEng = new ScriptEngineManager()&lt;br /&gt;   .getEngineByName("js");&lt;br /&gt; private Bindings initBindings = this.jsEng&lt;br /&gt;   .getBindings(ScriptContext.ENGINE_SCOPE);&lt;br /&gt;&lt;br /&gt; public JsServlet() {&lt;br /&gt;  super();&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; public void init(ServletConfig config) throws ServletException {&lt;br /&gt;  try {&lt;br /&gt;   super.init(config);&lt;br /&gt;&lt;br /&gt;   this.initBindings.put("config", config);&lt;br /&gt;   this.initBindings.put("servlet", this);&lt;br /&gt;&lt;br /&gt;   this.runJs("init.js", this.initBindings);&lt;br /&gt;  } catch (ScriptException e) {&lt;br /&gt;   throw new ServletException("Error running init.js", e);&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public void runJs(String scriptLocation, Bindings bindings)&lt;br /&gt;   throws ScriptException {&lt;br /&gt;  Reader jsReader = new InputStreamReader(this.getServletContext()&lt;br /&gt;    .getResourceAsStream(scriptLocation));&lt;br /&gt;&lt;br /&gt;  this.jsEng.eval(jsReader, bindings);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; protected void service(HttpServletRequest request,&lt;br /&gt;   HttpServletResponse response) throws ServletException, IOException {&lt;br /&gt;&lt;br /&gt;  try {&lt;br /&gt;   Bindings bindings = jsEng.createBindings();&lt;br /&gt;   bindings.putAll(this.initBindings);&lt;br /&gt;   bindings.put("request", request);&lt;br /&gt;   bindings.put("response", response);&lt;br /&gt;   &lt;br /&gt;   this.runJs("start.js", bindings);&lt;br /&gt;  } catch (ScriptException e) {&lt;br /&gt;   throw new ServletException("Error running javascript", e);&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;La segunda usa &lt;a href="http://www.mozilla.org/rhino/"&gt;rhino bajado desde mozilla&lt;/a&gt; y por lo tanto no tiene esas limitaciones, pero el API para embeber JavaScript en Java es más fea. Acá está el código de la segunda versión:&lt;br /&gt;&lt;pre&gt;package aure;&lt;br /&gt;&lt;br /&gt;import java.io.IOException;&lt;br /&gt;import java.io.InputStreamReader;&lt;br /&gt;import java.io.Reader;&lt;br /&gt;&lt;br /&gt;import javax.servlet.ServletConfig;&lt;br /&gt;import javax.servlet.ServletException;&lt;br /&gt;import javax.servlet.http.HttpServlet;&lt;br /&gt;import javax.servlet.http.HttpServletRequest;&lt;br /&gt;import javax.servlet.http.HttpServletResponse;&lt;br /&gt;&lt;br /&gt;import org.mozilla.javascript.Context;&lt;br /&gt;import org.mozilla.javascript.Scriptable;&lt;br /&gt;import org.mozilla.javascript.ScriptableObject;&lt;br /&gt;&lt;br /&gt;public class RhinoServlet extends HttpServlet {&lt;br /&gt; private static final long serialVersionUID = 1L;&lt;br /&gt; private Scriptable initialScope = null;&lt;br /&gt; &lt;br /&gt; public void runJs(Context cx, String scriptLocation, Scriptable scope) throws IOException {&lt;br /&gt;  Reader jsReader = new InputStreamReader(this.getServletContext()&lt;br /&gt;    .getResourceAsStream("/WEB-INF/js" + scriptLocation));&lt;br /&gt;  &lt;br /&gt;  cx.evaluateReader(scope, jsReader, scriptLocation, 1, null);&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; public static void addJavaObjectToScope(Scriptable scope, String name, Object obj) {&lt;br /&gt;  ScriptableObject.putProperty(scope, name, Context.javaToJS(obj, scope) );&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; @Override&lt;br /&gt; public void init(ServletConfig config) throws ServletException {&lt;br /&gt;  super.init(config);&lt;br /&gt;  Context cx = Context.enter();&lt;br /&gt;  try {&lt;br /&gt;   Scriptable scope = cx.initStandardObjects();&lt;br /&gt;   addJavaObjectToScope(scope, "servlet", this);&lt;br /&gt;   addJavaObjectToScope(scope, "config", config);&lt;br /&gt;   &lt;br /&gt;   this.runJs(cx, "/init.js", scope);&lt;br /&gt;   &lt;br /&gt;   this.initialScope = scope;&lt;br /&gt;  } catch (IOException e) {&lt;br /&gt;   throw new ServletException(e);&lt;br /&gt;  } finally {&lt;br /&gt;   Context.exit();&lt;br /&gt;  } &lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; @Override&lt;br /&gt; protected void service(HttpServletRequest request, HttpServletResponse response)&lt;br /&gt;   throws ServletException, IOException {&lt;br /&gt;  Context cx = Context.enter();&lt;br /&gt;  try {&lt;br /&gt;   Scriptable scope = cx.initStandardObjects();&lt;br /&gt;   scope.setParentScope(this.initialScope);&lt;br /&gt;   &lt;br /&gt;   addJavaObjectToScope(scope, "request", request);&lt;br /&gt;   addJavaObjectToScope(scope, "response", response);&lt;br /&gt;   &lt;br /&gt;   this.runJs(cx, "/start.js", scope);&lt;br /&gt;  } finally {&lt;br /&gt;   Context.exit();&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Ambas versiones ejecutan WEB-INF/js/init.js cuando se carga el servlet (tiene bindeados el servlet y la configuración del servlet) y WEB-INF/js/start.js cuando se atiende un pedido (agrega a los bindings lo que se haya puesto en init.js, el servlet, la configuración, el request y el response.&lt;br /&gt;&lt;br /&gt;La idea de todo esto es ponerme las pilas e implementar las cosas que dije &lt;a href="http://aurelianito.blogspot.com/2007/02/los-lenguajes-de-la-web.html"&gt;en este post hace casi 3 años&lt;/a&gt;, ya que ahora parece que se está poniendo de moda usar JavaScript.&lt;br /&gt;&lt;br /&gt;Espero que les parezca interesante, me voy a dormir.&lt;br /&gt;&lt;br /&gt;Happy hacking,&lt;br /&gt;Aureliano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-5178749719441092070?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/5178749719441092070/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=5178749719441092070' title='2 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/5178749719441092070'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/5178749719441092070'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2010/01/2-servlets-para-correr-javascript.html' title='2 servlets para correr javascript'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-8668633026252182822</id><published>2010-01-04T20:47:00.001-03:00</published><updated>2010-01-04T20:48:53.048-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='dubai'/><title type='text'>En el Burj Dubai, arriba de todo</title><content type='html'>&lt;object width="660" height="525"&gt;&lt;param name="movie" value="http://www.youtube.com/v/oWVLzVhnYE0&amp;hl=en_US&amp;fs=1&amp;rel=0&amp;border=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/oWVLzVhnYE0&amp;hl=en_US&amp;fs=1&amp;rel=0&amp;border=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="660" height="525"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;Este video es increíble.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-8668633026252182822?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/8668633026252182822/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=8668633026252182822' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/8668633026252182822'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/8668633026252182822'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2010/01/en-el-burj-dubai-arriba-de-todo.html' title='En el Burj Dubai, arriba de todo'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-4027935493627695083</id><published>2009-12-07T23:28:00.005-03:00</published><updated>2010-01-05T22:09:39.021-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='facebook'/><title type='text'>Cómo me echaron de facebook</title><content type='html'>&lt;div&gt;Update: &lt;a href="http://translate.google.com/translate?js=y&amp;amp;prev=_t&amp;amp;hl=en&amp;amp;ie=UTF-8&amp;amp;layout=1&amp;amp;eotf=1&amp;amp;u=http://aurelianito.blogspot.com/2009/12/como-me-echaron-de-facebook.html&amp;amp;sl=es&amp;amp;tl=en"&gt;Automated english translation&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;Esta es la lista de eventos que pasaron hasta que me echaron de Facebook:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;2007-11-10&lt;/span&gt;: Primera invitación a facebook recibida por mail&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;2009-09-27&lt;/span&gt;: Me suscribo a facebook&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;2009-09-30&lt;/span&gt;: Creo el grupo "Destruyendo facebook desde adentro"&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;2009-10-04&lt;/span&gt;: Publicito el grupo&lt;a href="http://aurelianito.blogspot.com/2009/10/destruyendo-facebook-desde-adentro.html"&gt; en un post de mi blog&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;2009-10-17&lt;/span&gt;: Me linkea &lt;a href="http://vivalinux.com.ar/"&gt;vivalinux&lt;/a&gt;. Entran más de 500 personas al blog en 2 días. El &lt;a href="http://aurelianito.blogspot.com/2009/10/destruyendo-facebook-desde-adentro.html"&gt;post&lt;/a&gt; del punto anterior es trolleado.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;2009-10-18&lt;/span&gt;: Sin ningún tipo de aviso bloquean mi cuenta en facebook.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;2009-10-19&lt;/span&gt;: Empieza la seguidilla de mails de/a facebook. El primero es este: "I've checked out on the links of the &lt;a href="http://www.facebook.com/help.php?page=45" target="_blank"&gt;http://www.facebook.com/help.&lt;wbr&gt;php?page=45&lt;/a&gt; page and I didn't violate any rules.&lt;br /&gt;&lt;br /&gt;Can you inform me why the account was disabled?&lt;br /&gt;&lt;br /&gt;Thanks in advance,&lt;br /&gt;&lt;span style="color: rgb(136, 136, 136);"&gt;Aureliano Calvo."&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;2009-10-22&lt;/span&gt;: Contesta facebook (enfasis mío):"Hi Aureliano,&lt;br /&gt;&lt;br /&gt;Fake accounts are a violation of our Statement of Rights and Responsibilities. &lt;span style="font-weight: bold;"&gt;Facebook requires users to provide their real first and last names. Impersonating anyone or anything is prohibited.&lt;/span&gt;  Unfortunately, we will not be able to reactivate this account for any reason. This decision is final.&lt;br /&gt;&lt;br /&gt;Thanks for your understanding,&lt;br /&gt;&lt;br /&gt;Johanna&lt;br /&gt;User Operations&lt;br /&gt;Facebook"&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;2009-10-22&lt;/span&gt;: Contesto yo (enfasis mío):"Hi,&lt;br /&gt;I've been falsely accused of impersonating someone else and this is just not true. I'm Aureliano Calvo, this is my e-mail and you can google for me. &lt;span style="font-weight: bold;"&gt;I can also provide several proofs of my identity and I'm willing to send photographs of my driver license, my passport or my identity card.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Can you reactivate the account?&lt;br /&gt;&lt;span style="color: rgb(136, 136, 136);"&gt;&lt;br /&gt;Aureliano.&lt;/span&gt;"&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;2009-10-23&lt;/span&gt;: Vuelve facebook :"Hi Aureliano,&lt;br /&gt;&lt;br /&gt;Unfortunately, your account has been permanently disabled for violating Facebook's Statement of Rights and Responsibilities.&lt;span style="font-weight: bold;"&gt; We will not be able to reactivate it for any reason, nor will we provide further explanation of your violation or the systems we have in place. This decision is absolutely final.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Thanks,&lt;br /&gt;&lt;br /&gt;Johanna&lt;br /&gt;User Operations&lt;br /&gt;Facebook"&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;2009-11-21&lt;/span&gt;: Pido por mail que borren todos mis datos de facebook:"I would like to have removed all my data from the facebook servers (generated from the account asociated with this e-mail).&lt;br /&gt;&lt;br /&gt;Thank you very much in advance,&lt;br /&gt;&lt;span style="color: rgb(136, 136, 136);"&gt;Aureliano Calvo&lt;/span&gt;"&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;2009-11-25&lt;/span&gt;: Contesta facebook sobre la remoción de datos:"Hi Aureliano,&lt;br /&gt;&lt;br /&gt;Facebook users have the option to either deactivate or delete their accounts. The differences between the two options are described below.&lt;br /&gt;&lt;br /&gt;If you deactivate your account, your profile and all information associated with it are immediately made inaccessible to other Facebook users.  What this means is that you effectively disappear from the Facebook service.  However, we do save your profile information (friends, photos, interests, etc.), so if you want to reactivate at some point, your account will look just the way it did when you deactivated.  Many users deactivate their accounts for temporary reasons and expect their information to be there when they return to the service.  You can deactivate your account through the "Deactivate Account" link on the Account page.&lt;br /&gt;&lt;br /&gt;If you do not think you will use Facebook again and you would like to delete your account, you can do this yourself by navigating to the following page:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.facebook.com/help/contact.php?show_form=delete_account" target="_blank"&gt;http://www.facebook.com/help/&lt;wbr&gt;contact.php?show_form=delete_&lt;wbr&gt;account&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Please keep in mind that once your account is deleted, you will not be able to reactivate the account or retrieve any of the content or information you have added.&lt;br /&gt;&lt;br /&gt;If you are currently unable to access your account, you will need to reset your password in order to log in. In order to do so, click the "Forgot your password?" link that appears above the field where you would normally enter your password. Entering your login email address on the next page will cause a new password to be sent to that email address. Once you receive your new password and can log in, you can deactivate or delete your account using the steps outlined above. We apologize for any inconvenience this may cause.&lt;br /&gt;&lt;br /&gt;Thanks for contacting Facebook,&lt;br /&gt;&lt;br /&gt;Brett&lt;br /&gt;User Operations&lt;br /&gt;Facebook"&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;2009-11-25&lt;/span&gt;: Contesto que no puedo porque deshabilitaron la cuenta:"I've requested that all my data should be removed from the facebook servers by email because my account has been disabled.&lt;br /&gt;Please remove all my data from the facebook system.&lt;br /&gt;&lt;br /&gt;Thank you very much,&lt;br /&gt;&lt;span style="color: rgb(136, 136, 136);"&gt;Aureliano Calvo.&lt;/span&gt;"&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;2009-11-29&lt;/span&gt;: Me dicen que me joda que se quedan con todos los datos:"Hi Aureliano,&lt;br /&gt;&lt;br /&gt;When an account is disabled, the profile and all information associated with it are immediately made inaccessible to other Facebook users. What this means is that you effectively disappear from the Facebook service. In addition, Facebook does not use information associated with disabled accounts.&lt;br /&gt;&lt;br /&gt;Unfortunately, &lt;span style="font-weight: bold;"&gt;for safety and security reasons, we cannot delete from our servers information associated with disabled accounts&lt;/span&gt;. We also cannot grant you access to a disabled account to retrieve content from it, nor can we provide you with any content that was associated with this account. We apologize for any inconvenience this may cause. This decision is final.&lt;br /&gt;&lt;br /&gt;Thanks for your understanding,&lt;br /&gt;&lt;br /&gt;Brett&lt;br /&gt;User Operations&lt;br /&gt;Facebook"&lt;/li&gt;&lt;/ol&gt;Conclusiones:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Facebook contesta en tiempo y forma los pedidos por mail.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Facebook no identifica a las personas que contestan y no toma responsabilidades.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Facebook echa gente que no viola sus términos y condiciones (el punto que dicen que violé es mentira)&lt;/li&gt;&lt;li&gt;Facebook se niega a dar información sobre que hiciste mal (probablemente para cubrirse del punto uno) y encima lo hacen mal (como se ve en el punto anterior).&lt;/li&gt;&lt;li&gt;Facebook se niega a borrar los datos de la gente que echa (cosa que, hasta donde yo sé, es ilegal en Argentina).&lt;/li&gt;&lt;/ul&gt;O sea, mejor irse lo antes posible de ahí. No dejes que los mercaderes de relaciones te dominen.&lt;br /&gt;&lt;br /&gt;Happy hacking,&lt;br /&gt;Aureliano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-4027935493627695083?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/4027935493627695083/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=4027935493627695083' title='13 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/4027935493627695083'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/4027935493627695083'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2009/12/como-me-echaron-de-facebook.html' title='Cómo me echaron de facebook'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>13</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-6502717373514926539</id><published>2009-12-02T12:07:00.001-03:00</published><updated>2009-12-02T12:10:43.300-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='vim'/><category scheme='http://www.blogger.com/atom/ns#' term='indent'/><category scheme='http://www.blogger.com/atom/ns#' term='html'/><title type='text'>Deshabilitando autoindent de () en vim</title><content type='html'>Para editar html con javascript con algo más de onda en gvim adopté el siguiente seteo:&lt;br /&gt;&lt;pre&gt;:set inde=&lt;br /&gt;:set ai&lt;/pre&gt;&lt;br /&gt;Para más detalles mirá &lt;a href="http://vim.wikia.com/wiki/How_to_stop_auto_indenting#Disabling_auto_indent_for_the_current_file"&gt;acá&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Happy hacking,&lt;br /&gt;Aureliano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-6502717373514926539?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/6502717373514926539/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=6502717373514926539' title='3 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/6502717373514926539'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/6502717373514926539'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2009/12/deshabilitando-autoindent-de-en-vim.html' title='Deshabilitando autoindent de () en vim'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-5799323332345216845</id><published>2009-11-26T22:23:00.001-03:00</published><updated>2009-11-26T22:24:48.421-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='google'/><category scheme='http://www.blogger.com/atom/ns#' term='wave'/><title type='text'>Invitaciones para Google Wave</title><content type='html'>¿Querés una invitación para Google Wave?&lt;br /&gt;&lt;br /&gt;Avisame y te la mando (tengo 16 para repartir).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-5799323332345216845?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/5799323332345216845/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=5799323332345216845' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/5799323332345216845'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/5799323332345216845'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2009/11/invitaciones-para-google-wave.html' title='Invitaciones para Google Wave'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-7069461452940099364</id><published>2009-11-26T18:45:00.002-03:00</published><updated>2009-11-26T18:47:34.483-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='política'/><category scheme='http://www.blogger.com/atom/ns#' term='seguridad'/><title type='text'>Seguridad nacional</title><content type='html'>Esto le pasó ayer a un compañero de trabajo. Espero que sirva para que sepamos que no hay que creer todo lo que pasa en la tele:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;Ayer fue al super (disco)  a buscar la compra que habia hecho antes de&lt;br /&gt;ayer ya que me avisaron que los empleados del delivery estaban de paro&lt;br /&gt;por un reclamo sindical. cuando estoy llegando veo que en la esquina hay&lt;br /&gt;una especia de muchedumbre de 20-30 personas y una camara de TV. No doy&lt;br /&gt;bola y paso de largo hasta el super, que encuentro cerrado, en las&lt;br /&gt;puertas de vidrio habia pagadas que decia qu ella empres ales mando la&lt;br /&gt;policia a los que estaban reclamando para "apretarlos" y por ese se&lt;br /&gt;metieron adentro y cerraron. Digo.. "uh que mal" y me voy pensando que&lt;br /&gt;la muchedumbre de la esquina tendra algo que ver con eso. cuando llego a&lt;br /&gt;la esquina y presto atencion a lo que pasa me doy cuenta que en realidad&lt;br /&gt;hay 20-30 energumenos en chomba, camisa rosa+sweater al cuello y/o&lt;br /&gt;vestido largo y ollas de fondue gritandole a la camara "seguridad!&lt;br /&gt;seguridad!"  mientras esgrimen cartelitos escritos prolijamente con&lt;br /&gt;marcador con la palabra en cuestion ("seguridad"). Detras de todos&lt;br /&gt;ellos, sentado en el piso esta durmiendo  un señor de entre 50-60 años&lt;br /&gt;que vive en la calle en esa esquina desde hace una semanas. Los&lt;br /&gt;protestantes lo ignoran olimpicamente, pero el señor se despierta y&lt;br /&gt;percibe que hay algun quilombo y desde el piso se une a los canticos al&lt;br /&gt;tiempo que ademas aplaude (!?)&lt;br /&gt;&lt;br /&gt;Me abro paso vocifereando que son todos unos payasos mediaticos (como&lt;br /&gt;osvaldo pagani) pero a nadie parece importarle o molestarle lo que digo&lt;br /&gt;o hago (que lastima! ya que estan todos hipnotizados cantando su mantra&lt;br /&gt;a la camara.&lt;br /&gt;&lt;br /&gt;Minutos despues cuando llego a casa me dicen que en el noticiero de&lt;br /&gt;America transmitian en vivo una "protesta de los vecinos de palermo"&lt;br /&gt;demandando mas seguridad o algo asi.&lt;br /&gt;&lt;br /&gt;Media hora mas tarde cuando paso otra vez por la esquina paseando al&lt;br /&gt;perro "los vecinos de palermo" no estan mas (el noticiero de america ya&lt;br /&gt;termino) pero sigue estando el señor que vive en  la esquina condiciones&lt;br /&gt;de "seguridad" bastante precarias (hasta tanto no se entere la UZZEP).&lt;br /&gt;&lt;br /&gt;Alguien vio algo de esto en el noticiero de America ayer? que dijeron?&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Happy hacking,&lt;br /&gt;Aureliano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-7069461452940099364?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/7069461452940099364/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=7069461452940099364' title='1 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/7069461452940099364'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/7069461452940099364'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2009/11/seguridad-nacional.html' title='Seguridad nacional'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-2878223802008694185</id><published>2009-11-25T12:22:00.003-03:00</published><updated>2009-11-25T12:38:03.697-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='firewall'/><category scheme='http://www.blogger.com/atom/ns#' term='windows7'/><category scheme='http://www.blogger.com/atom/ns#' term='vmware'/><title type='text'>Firewall, Windows 7 y guests bridgeados de VMWare</title><content type='html'>Si dejo el firewall de Windows 7 activado filtra las conexiones entrantes a las VMs del VMWare Server que están conectadas en modo "bridged" a la red. No sé el ip del guest ya que se obtiene por DHCP. Si apago el firewall, las conexiones entrantes llegan hasta las VMs.&lt;br /&gt;&lt;br /&gt;Saben como hacer para dejar el firewall prendido pero que las conexiones que van a los guests en modo bridged pasen sin ser filtradas? Qué reglas tengo que agregar/sacar?&lt;br /&gt;&lt;br /&gt;Muchas gracias,&lt;br /&gt;Aureliano&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-2878223802008694185?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/2878223802008694185/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=2878223802008694185' title='2 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/2878223802008694185'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/2878223802008694185'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2009/11/firewall-windows-7-y-guests-bridgeados.html' title='Firewall, Windows 7 y guests bridgeados de VMWare'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-5403945447077460642</id><published>2009-11-22T20:05:00.003-03:00</published><updated>2009-11-22T20:08:56.321-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='facebook'/><title type='text'>Como facebook cuida tu privacidad</title><content type='html'>Vía &lt;a href="http://yro.slashdot.org/story/09/11/22/0125253/Facebook-Photos-Lead-To-Cancellation-of-Quebec-Womans-Insurance?art_pos=2"&gt;slashdot&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Una mina con tratamiento por depresión en Canadá le niegan el tratamiento porque tiene fotos en la playa y en una fiesta en facebook (en una cuenta "lockeada"). Más detalles ver &lt;a href="http://www.cbc.ca/canada/montreal/story/2009/11/19/quebec-facebook-sick-leave-benefits.html"&gt;acá&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;Esperemos que no se mate por esto,&lt;br /&gt;Aureliano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-5403945447077460642?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/5403945447077460642/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=5403945447077460642' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/5403945447077460642'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/5403945447077460642'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2009/11/como-facebook-cuida-tu-privacidad.html' title='Como facebook cuida tu privacidad'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-6389935426508165380</id><published>2009-11-20T22:38:00.002-03:00</published><updated>2009-11-20T22:46:40.222-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='visualización'/><title type='text'>Visualizando más</title><content type='html'>En &lt;a href="http://aurelianito.blogspot.com/2009/10/visualizando.html"&gt;este post&lt;/a&gt; prometí que iba a contar que cosas vi en VisWeek 2009. Y como lo prometí, aunque un poco tarde acá pongo mis notas de la conferencia (tienen mezcla con inglés):&lt;br /&gt;&lt;br /&gt;Domingo 11:&lt;br /&gt;&lt;br /&gt;8:30am&lt;br /&gt; * Keynote: Bill Cheswick&lt;br /&gt; *"Visualization is about coolness"&lt;br /&gt; * Lots of developments. But almost nothing in the industry&lt;br /&gt;&lt;br /&gt;Problemas:&lt;br /&gt;&lt;br /&gt; * Layout arbitrario&lt;br /&gt; * La evolución no es clara&lt;br /&gt; * Las cosas que se sacan no se muestran&lt;br /&gt; * Destruyen el contexto&lt;br /&gt;&lt;br /&gt;Usa minimum distance spanning trees todo el tiempo para mostrar cosas aunque descarta el 30-40% de las conexiones.&lt;br /&gt;&lt;br /&gt;How do you measure security?&lt;br /&gt; * Generals and CIOs want to know.&lt;br /&gt;Trusecure. Always and human in a step.&lt;br /&gt;&lt;br /&gt;Network Access Security: contar cantidad de puertos abiertos&lt;br /&gt;privilege scalation: programas que corren como root desde un usuario normal.&lt;br /&gt;&lt;br /&gt;Parte difícil, como hacer los reportes.&lt;br /&gt;&lt;br /&gt;2D sin tiempo -&gt; 3D para el tiempo?&lt;br /&gt;&lt;br /&gt;Ninguna buena visualización buena de IPv6&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;--------------------------------------------------------------------&lt;br /&gt;Sesión de visualización de redes&lt;br /&gt;10:30am&lt;br /&gt;&lt;br /&gt;Visualization of complex attacks.&lt;br /&gt; * Desde el pto de vista del sysadmin.&lt;br /&gt; * Ataque simple: Una acción&lt;br /&gt; * Ataque complejo: combinación de los anteriores&lt;br /&gt;   * DDNS&lt;br /&gt;   * "Multi-step"&lt;br /&gt;   * Worm propagation&lt;br /&gt; * Interesante: las líneas hacen un "fade-out" con el tiempo. Las cosas nuevas son menos transparentes.&lt;br /&gt; * El IDS informa que ataques simples pertenecen al mismo ataque complejo.&lt;br /&gt;&lt;br /&gt;OverFlow: An Overview Visualization for network analisis&lt;br /&gt;FloVis -&gt; http://www.flovis.net&lt;br /&gt;&lt;br /&gt;Security visualization tools and ipv6 addresses&lt;br /&gt; * Demasiadas direcciones (128 bits)&lt;br /&gt; * La mayoría de las visualizaciones no bancan ipv6&lt;br /&gt; * muestra cambios en headers 4-&gt;6&lt;br /&gt; * Se enfoca en "process and reformat" y "display"&lt;br /&gt; * Muestra las comunicaciones con un scatter plot&lt;br /&gt;   * Le da un índice ordenado a cada dirección&lt;br /&gt; * Usa la estructura de la dirección para agrupar direcciones&lt;br /&gt;   * Treemap (no me gusta, parece muy "cluttereado":&lt;br /&gt;     * Color: tipo de paquete (tcp, udp, etc)&lt;br /&gt;     * Tamaño: volumen de tráfico&lt;br /&gt;&lt;br /&gt;1:00p&lt;br /&gt;Malware and forensics&lt;br /&gt;A visual Analytic framework for Exploring Relationships in Textual Content of Digital Forensics Evidence&lt;br /&gt;Muestra como indexan el disco rígido y después filtran para ir buscando cosas en el disco rígido&lt;br /&gt;&lt;br /&gt;Visual Analysis of Malware Behaviour Using Treemaps and Thread Graphs&lt;br /&gt;CWSandbox.org&lt;br /&gt; * Analisis automático de malware porque les mandan como 4000 ejemplos todos los días.&lt;br /&gt; * Hacen un treemap con syscalls clasificados por tipo c/ color y cantidad de llamadas en el tamaño.&lt;br /&gt; * El análisis es dinámico (o sea, ejecutan el malware).&lt;br /&gt;   * Por eso no los jode tanto la ofuscación&lt;br /&gt; * Pueden detectar pdfs "malvados" mirando los treemaps (o clusterizando los datos).&lt;br /&gt;&lt;br /&gt;Visualizing Compiled Executables for Malware Analysis&lt;br /&gt;http://www.offensivetechnology.net (VERA)&lt;br /&gt; * Dibuja los basic blocks que se ejecutan (todos, también los que se generan dinámicamente)&lt;br /&gt; * Arma el grafo de los basic blocks&lt;br /&gt;   * les da más peso a los basic blocks que más se ejecutan&lt;br /&gt;     * por eso los loops que más se ejecutan quedan más grandes.&lt;br /&gt;   * pone diferentes colores a los basic blocks en función de cómo se generan&lt;br /&gt;     (ej: en el ejecutable en una sección de código,&lt;br /&gt;          en el ejecutable en una sección de datos,&lt;br /&gt;          generado dinamicamente,&lt;br /&gt;          etc)&lt;br /&gt;&lt;br /&gt;2:30p&lt;br /&gt;Users and Usability&lt;br /&gt;Visualizing Cyber Security: Usable Workspaces&lt;br /&gt; * Los analistas se quejan de que no pueden interactuar con los datos.&lt;br /&gt; * Usan muuuuuuuuuuucha definición (10240x3200) y pueden mostrar simultáneamente los datos y los patrones que se forman en&lt;br /&gt;   alto nivel.&lt;br /&gt; * History trees. Parecen como los branches en un control de versiones o algo así.&lt;br /&gt;&lt;br /&gt;Visualization is Better! A Comparative Evaluation&lt;br /&gt;http://tnv.sf.net vs ethereal en newbies&lt;br /&gt; * Controlled experiment comparing two tools&lt;br /&gt; * http://vizsec.org/datasets/&lt;br /&gt;&lt;br /&gt;4:45p&lt;br /&gt;Visualizing Keyboard Pattern Passwords&lt;br /&gt; * Muestra como mostrar que teclas apretaron con una secuencia de reglas sobre como dibujarlos.&lt;br /&gt; * Encontraron patrones mirando los passwds de a 25 (500 en total)&lt;br /&gt; * Generaron diccionario con algunos patrones (500K passwords)&lt;br /&gt;   * Con ese diccionario crackeron passwds de verdad que John The Ripper no encontró&lt;br /&gt;&lt;br /&gt;Visualizing Firewall Configurations Using Created Voids&lt;br /&gt;Espacio:&lt;br /&gt;5 dimensiones escalares (host1, port1, protocol, host2, port2) y un valor categorico (allow, deny).&lt;br /&gt;regla:&lt;br /&gt;(min_max de (host1, port1, protocol, host2, port2), (allow|deny))&lt;br /&gt;Usa paralell coordinates :( (problemas de oclusión)&lt;br /&gt;&lt;br /&gt;Panel (Visualization + Security = Science?):&lt;br /&gt;Fue una pedorrada&lt;br /&gt;&lt;br /&gt;Lunes 12:&lt;br /&gt;Keynote VAST.&lt;br /&gt;Storytelling.&lt;br /&gt;Contó como es la estructura de un cuento clásico (introducción, nudo y desenlace), el camino del héroe (los 12 pasos que siguen casi todos los libros y películas) y dio una heurística para darse cuenta si algo es una buena historia o no. La misma consiste en si es posible responder estas 4 preguntas facilmente:&lt;br /&gt; 1. Quién es el héroe?&lt;br /&gt; 2. Qué quiere el héroe?&lt;br /&gt; 3. Qué impide que el héroe lo consiga?&lt;br /&gt; 4. Qué hace el héroe para solucionar el problema?&lt;br /&gt;El chabón afirma que todos tenemos una habilidad natural para entender cuentos, y que por eso es bueno organizar las visualizaciones y presentaciones en forma de cuento.&lt;br /&gt;&lt;br /&gt;VAST&lt;br /&gt;Multidimentional Data session&lt;br /&gt;&lt;br /&gt;A framework for uncertainty-aware visual analytics&lt;br /&gt;Proponer manejar la incertidumbre todo a lo largo del pipeline de procesamiento de datos. Puede ser que los datos vengan con "incertidumbre" o que las transformaciones agreguen incertidumbre. Al final muestra la incertidumbre de varias maneras. Ej: color (segun que variable introduce mas incerteza), transparencia (para esconder datos menos confiables), o desagregando (pero solo para pocos datos)&lt;br /&gt;&lt;br /&gt;Combining automated analysis and visualization techniques for efective exploration of high-dimentional data&lt;br /&gt;Intenta detectar automáticamente que visualización de los datos es mejor. Creo que puede servir para mostrarle al usuario automáticamente vistas de datos que tengan algún sentido (muestran en scatter plots y paralell coordinates). También dicen que vistas muestran mejor una categorización dada.&lt;br /&gt;&lt;br /&gt;Two-stage framework for visualization of clustered high dimentional data.&lt;br /&gt;Hace algo parecido que la charla de arriba pero proyectando muchas dimensiones en 2 o 3. &lt;br /&gt;&lt;br /&gt;Model space visualization for multivariate linear trend discovery.&lt;br /&gt;Muestra una técnica manual para encontrar correlaciones lineales de dimensiones cuando hay muchas dimensiones&lt;br /&gt;&lt;br /&gt;Martes 13:&lt;br /&gt;Vast. Text analytics session.&lt;br /&gt;&lt;br /&gt;LSAView: A tool for visual exploration of latent semantic modelling.&lt;br /&gt;Sirve para clasificar documentos en función del tema. Visualiza el documento para que un analista decida si el clustering está bien.&lt;br /&gt;&lt;br /&gt;Parallel tag clouds to explore and analyze faceted text corpora.&lt;br /&gt;Analizan fallos de cortes EEUUenses. POnen las palabras que son más comunes en un documento y menos comunes en el resto (Dunning's log likehood). Ponen los tags con tamaño en gráfico de paralell coordinates. Parece interesante.&lt;br /&gt;&lt;br /&gt;Describing story evolution from dynamic information streams.&lt;br /&gt;No me gustó. Muestra como intentan detectar historias que se extienden a lo largo de diferentes artículos periodísticos.&lt;br /&gt;&lt;br /&gt;What's being said near "Martha"? Exploring name entities in literature.&lt;br /&gt;Muestra varias herramientas usando como ejemplo el análisis de literatura "rara":&lt;br /&gt; * FeatureLens&lt;br /&gt; * Wordle (Dunning's log likehood)&lt;br /&gt; * POSvis&lt;br /&gt;Necesitaban los Stop-words para analizar el texto.&lt;br /&gt;&lt;br /&gt;VAST contest dataset use in education.&lt;br /&gt;Hay un montón de datos de los diferentes VAST contest. Muestran como los usan para dar clases.&lt;br /&gt;&lt;br /&gt;VARIAS DE LAS PRESENTACIONES DESTACARON LA NECESIDAD DE PODER IR AL TEXTO ORIGINAL QUE GENERÓ LOS DATOS QUE ESTÁN MOSTRANDO LAS HERRAMIENTAS. Posiblemente pase lo mismo con gráficos sumarizados de ataques.&lt;br /&gt;&lt;br /&gt;Vast. Analysis Process &amp; Graph Analytics&lt;br /&gt;&lt;br /&gt;Connecting the dots in visual analysis.&lt;br /&gt;Integran notas y flujos de trabajo en el proceso de analisis de los datos. Hacen todo un manejo bastante complicado de los flujos de trabajo (action trails?) del analista. También sugiere a los analistas que miren cosas que ya hicieron. Les preguntaron a 2 analistas sobre si les gustó el enfoque y dijeron que sí.&lt;br /&gt;&lt;br /&gt;Capturing and supporting the analysis process.&lt;br /&gt;Otro paper que explica como soportar el proceso del analista. Ejemplo con data set del VAST challenge 2008.&lt;br /&gt;&lt;br /&gt;Evaluating visual analytics systems for interactive analysis: Deriving design principles from a case study.&lt;br /&gt;Estudian como un analista usa jigsaw y otras herramientas para hacer tareas de analisis de datos.&lt;br /&gt;&lt;br /&gt;A multi-level middle-out cross-zooming approach for large graph analytics.&lt;br /&gt;Muestra una parte del grafo con una "resolución" y otra parte con otra "resolución". Cuando hace zoom-in en algún lado hace zoom-out en otro para mantener + o - constante la cantidad de cosas que muestra. Sirve para grafos de tipo small-worlds (algo parecido a esparsos). La implementación es un bolonqui porque quieren que todo sea interactivo (quién no?). &lt;br /&gt;http://www.pnl.gov/wong&lt;br /&gt;&lt;br /&gt;Visual analytics of graphs with multiple connected components.&lt;br /&gt;Share-holder networks == Weighted directed acyclic graph.&lt;br /&gt;Buscan estructuras comunes en estos grafos. Para eso hacen un proceso iterativo donde buscan los componentes.&lt;br /&gt;&lt;br /&gt;Tutorial: Exploring design decisions for effective information visualization&lt;br /&gt;Usando datos de las últimas 8 elecciones norteamericanas hicimos un montón de treemaps distintos analizando que se ve en cada uno, que no se ve y buscando la mejor forma de mostrar cosas.&lt;br /&gt;&lt;br /&gt;Miércoles 14:&lt;br /&gt;8:30a Keynote: Visual thinking and visual thingking tools&lt;br /&gt;En esta charla Collin Ware estuvo hablando sobre como percibimos las cosas y como esto afecta como nos relacionamos con las herramientas de visualizacion. En particular mostró como se compara una interfase zoomeable con una que abre ventanitas para mostrar detalles y dio algunas formas muy simples de calcular que esfuerzo requiere hacer tareas en ambas interfaces. Usando el mismo ejemplo, también mostró porqué en otro estudio que él hizo convino usar imagenes en vez de video para mostrar movimiento. Esta charla también le da sustento teórico a la necesidad de tener más espacio disponible en el/los monitor(es).&lt;br /&gt;&lt;br /&gt;4:15p Models and theories&lt;br /&gt;A nested model for visualization design and validation&lt;br /&gt; * problem&lt;br /&gt;   * data/op abstraction&lt;br /&gt;     * enc/interact technique&lt;br /&gt;       * algorithm&lt;br /&gt;Intenta ordenar cómo saber si una visualización es "buena" o no. Divide en 4 diferentes "aspectos" a una visualización.&lt;br /&gt;&lt;br /&gt;Conjunctive visual form.&lt;br /&gt;Hace una especie de query by example pero en vez de poner un ejemplo pone un conjunto para cada dimensión (cross-filtered views, paper del año pasado).&lt;br /&gt;&lt;br /&gt;Jueves 15:&lt;br /&gt;Interaction Techniques for Selecting and Manipulating Subgraphs in Network Visualizations&lt;br /&gt;Explica un montón de diferentes formas de operar sobre conjuntos de nodos en un grafo y elegir que conjunto de nodos. Están buenos pero son un quilombo.&lt;br /&gt;Software: Navigator.&lt;br /&gt;&lt;br /&gt;ActiviTree: Interactive Visual Exploration of Sequences in Event-Based Data Using Graph Similarity&lt;br /&gt;Buscar patrones en eventos. ¿Puede servir para analizar logs?&lt;br /&gt;&lt;br /&gt;“Search, Show Context, Expand on Demand”: Supporting Large Graph Exploration with Degree-of-Interest&lt;br /&gt;Enfoque bottom-up para explorar grafos. Search, show context, expand on demand.&lt;br /&gt;cada nodo tiene un "interes". Con eso, la query que hace el usuario y la estructura del grafo hacen una cuenta y definen el "degree of interest" (DOI) de un nodo. El contexto es el subgrafo conexo que contiene a ese nodo y tiene mayor interés. Para hacer que ande mejor un algoritmo greedy "difunden" el interés en los nodos vecinos. Lo usan para buscar fallos judiciales y como se relacionan.&lt;br /&gt;&lt;br /&gt;A Comparison of User-Generated and Automatic Graph Layouts.&lt;br /&gt;Probaron layouts generados a mano por usuarios (usando Surface, de MS) para las tareas que iban a pedir a otros participantes. Después agarraron esos layouts y 3 layouts automáticos más e hicieron que otra gente haga esas cosas. Al final, el mejor fue el force directed layout.&lt;br /&gt;&lt;br /&gt;Smooth Graphs for Visual Exploration of Higher-Order State Transitions.&lt;br /&gt;En vez de tomar A-B como "edge" se fijan en secuencias más largas (A-B-C-D, por ejemplo). Usaron esto para analizar el comportamiento de pingüinos.&lt;br /&gt;&lt;br /&gt;Harnessing the Web Information Ecosystem with Wiki-based Visualization Dashboards.&lt;br /&gt;Muestra un wiki que sirve para armar dashboards con algunos tipos de visualizaciones.&lt;br /&gt;&lt;br /&gt;Viernes&lt;br /&gt;code swarm: A Design Study in Organic Software Visualization&lt;br /&gt;MOstró codeswarm.&lt;br /&gt;&lt;br /&gt;Towards Utilizing GPUs in Information Visualization: A Model and Implementation of Image-Space Operations&lt;br /&gt;Mostró un prototipo que usa la GPU para hacer visualizaciones (basado de shaders) y un programa que sirve para implementar los shaders uniendo cajas con flechas.&lt;br /&gt;&lt;br /&gt;A Multi-Threading Architecture to Support Interactive Visual Exploration&lt;br /&gt;Arquitectura para hacer visualizaciones:&lt;br /&gt;1 thread de eventos&lt;br /&gt;n threads para n visualizaciones&lt;br /&gt;Los threads de las visualizaciones son interrumpidos cuando los datos que usan para calcular cosas cambian.&lt;br /&gt;Hay un cache de cachos de dibujos y datos intermedios&lt;br /&gt;&lt;br /&gt;Protovis: A Graphical Toolkit for Visualization&lt;br /&gt;Toolkit para hacer visualizaciones en JavaScript de los autores de Flare y Prefuse&lt;br /&gt;http://protovis.org&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-6389935426508165380?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/6389935426508165380/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=6389935426508165380' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/6389935426508165380'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/6389935426508165380'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2009/11/visualizando-mas.html' title='Visualizando más'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-8946503822227688998</id><published>2009-10-30T14:38:00.002-03:00</published><updated>2009-10-30T14:43:08.175-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wipe'/><category scheme='http://www.blogger.com/atom/ns#' term='sh'/><category scheme='http://www.blogger.com/atom/ns#' term='bash'/><category scheme='http://www.blogger.com/atom/ns#' term='hack'/><title type='text'>Wipeando discos en el tercer mundo</title><content type='html'>Tuve que wipear un disco rígido y las herramientas de wipeo que tenía a mano no lo reconocían. &lt;br /&gt;La solución:&lt;br /&gt;&lt;pre&gt;# yes &gt; /dev/sda&lt;/pre&gt;&lt;br /&gt;¿Se les ocurre alguna solución más corta? (wipe-golfing)&lt;br /&gt;&lt;br /&gt;Happy hacking,&lt;br /&gt;Aureliano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-8946503822227688998?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/8946503822227688998/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=8946503822227688998' title='7 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/8946503822227688998'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/8946503822227688998'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2009/10/wipeando-discos-en-el-tercer-mundo.html' title='Wipeando discos en el tercer mundo'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-5782899638346788207</id><published>2009-10-15T17:06:00.002-03:00</published><updated>2009-10-15T17:17:37.104-03:00</updated><title type='text'>Reflexiones sobre las colas</title><content type='html'>Como les conté en el &lt;a href="http://aurelianito.blogspot.com/2009/10/visualizando.html"&gt;post anterior&lt;/a&gt;, estoy en VisWeek 2009. En esta conferencia hay gente de alrededor de todo el mundo, pero el grueso es de Europa y EEUU. Y hay algunas cosas que me llamaron la atención (positivamente) sobre el comportamiento de la gente por acá.&lt;br /&gt;La primera cosa es que las charlas empiezan y terminan en horario (cronométricamente). El primer día de la conferencia me fui a comer y pensé que la sesión de la tarde iba a empezar algo así como media hora más tarde y en vez de eso empezó en horario y me perdí una charla. Comparado con la laxitud de la &lt;a href="http://ekoparty.com.ar/"&gt;Eko&lt;/a&gt;, que terminó 2 horas y media después del horario planificado, es mucho mejor. Así que aprendí y empecé a llegar en horario. No como en Argentina que las cosas se van atrasando cada vez más y llegamos a situaciones ridículas donde el horario de entrada a un boliche es las 3 AM.&lt;br /&gt;Pero lo que más me asombró es como se arman colas automáticamente cuando se requiere acceso a un recurso escaso. Es en todos lados. Cuando hay que entrar a una sala grande y la puerta es un cuello de botella. Cuando sacamos comida de las mesas de la conferencia. Esperando el ascensor (!). Si prestás atención, se arman colas en todos lados y todo el mundo las respeta.&lt;br /&gt;¿Será realmente más eficiente hacer las cosas más ordenadamente?,&lt;br /&gt;Aureliano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-5782899638346788207?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/5782899638346788207/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=5782899638346788207' title='2 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/5782899638346788207'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/5782899638346788207'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2009/10/reflexiones-sobre-las-colas.html' title='Reflexiones sobre las colas'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-731691852273175998</id><published>2009-10-13T00:01:00.005-03:00</published><updated>2009-10-13T00:20:11.656-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='visualización'/><category scheme='http://www.blogger.com/atom/ns#' term='conferencia'/><category scheme='http://www.blogger.com/atom/ns#' term='new york'/><category scheme='http://www.blogger.com/atom/ns#' term='filadelfia'/><category scheme='http://www.blogger.com/atom/ns#' term='viaje'/><category scheme='http://www.blogger.com/atom/ns#' term='atlantic city'/><title type='text'>Visualizando</title><content type='html'>El viernes pasado partí a Atlantic City para participar de &lt;a href="http://vis.computer.org/VisWeek2009/"&gt;Visweek&lt;/a&gt;, enfocándome especialmente en &lt;a href="http://vizsec.org/vizsec2009/"&gt;Vizsec.&lt;/a&gt; Como el avión llegó a la mañana del sábado a Filadelfia y la conferencia empezó el domingo, dediqué parte del sábado a caminar por Filadelfia. Y me gustó bastante. Es una ciudad linda, con alma. A pesar de que me mojé porque llovía de a ratos y estaba bastante mareado porque el vuelo desde Washington fue en un avión diminuto que se movía mucho lo disfruté un montón.&lt;br /&gt;A las 13:47 me tomé el tren a Atlantic City, y colapsé por falta de sueño. Alrededor de las 16:30hs llegué a Atlantic City y fui al hotel. El hotel de Atlantic City es una mole gigantesca y el casino es increíblemente grande (no me creen, &lt;a href="http://www.ballysac.com/casinos/ballys-atlantic-city/hotel-casino/property-home.shtml"&gt;fíjense&lt;/a&gt;).&lt;br /&gt;Y la posta es que no me gusta, pero tiene todas las comodidades que hacen falta para la conferencia, que viene super-interesante. Estoy tomando notas de las charlas a las que voy, así que probablemente las ponga en el blog una vez que las muestre en &lt;a href="http://coresecurity.com"&gt;Core&lt;/a&gt; (ellos pagan el viaje así que me parece bien que las vean primero).&lt;br /&gt;Acá estoy empezando a conocer gente y hay un grupo de alemanes que son buena onda y me adoptaron. Estoy contento de que estoy aprendiendo un montón y que estoy conociendo gente super-interesante. Espero saber mucho más sobre visualización cuando termine la conferencia. En particular, estoy buscando herramientas para hacer visualizaciones que sean medianamente razonables (para una definición mía y absolutamente arbitraria de razonable). Por ahora no encontré nada :( y los investigadores con los que hablé todos implementaron sus propias herramientas para hacer visualizaciones.&lt;br /&gt;Por último, cuando termine la conferencia me voy 3 días a Nueva York. ¿Qué me sugieren que haga por allá? Lo que tengo pensado es ir al Central Park, subir al Empire State, cruzar caminando el puente de Brooklin, ir a Wall Street, ir a Broadway, ir a la Quinta Avenida (y quizás hacerme el muerto donde mataron a John Lennon), tomarme el ferry a Staten Island para ver la estatua de la Libertad e ir al Museo de Arte Moderno.&lt;br /&gt;Cuando pueda subo fotos de la conferencia, el viaje, etc.&lt;br /&gt;Happy hacking,&lt;br /&gt;Aureliano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-731691852273175998?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/731691852273175998/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=731691852273175998' title='2 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/731691852273175998'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/731691852273175998'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2009/10/visualizando.html' title='Visualizando'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-9141152372566585773</id><published>2009-10-06T17:17:00.002-03:00</published><updated>2009-10-06T17:21:10.453-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jetty'/><category scheme='http://www.blogger.com/atom/ns#' term='advisory'/><category scheme='http://www.blogger.com/atom/ns#' term='xss'/><title type='text'>Mi primer advisory</title><content type='html'>Encontré un XSS persistente en una aplicación de ejemplo de Jetty. Si quieren ver el advisory, pueden verlo &lt;a href="http://www.coresecurity.com/content/jetty-persistent-xss"&gt;acá&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Jetty es un container de servlets (como Tomcat) que mantiene la Apache foundation (como Tomcat) pero que intenta ser liviano (no como Tomcat).&lt;br /&gt;&lt;br /&gt;Happy hacking,&lt;br /&gt;Aureliano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-9141152372566585773?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/9141152372566585773/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=9141152372566585773' title='2 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/9141152372566585773'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/9141152372566585773'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2009/10/mi-primer-advisory.html' title='Mi primer advisory'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-8106226841705103212</id><published>2009-10-04T21:02:00.006-03:00</published><updated>2010-03-08T01:19:25.936-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='facebook'/><title type='text'>Destruyendo facebook desde adentro</title><content type='html'>&lt;span style="font-weight: bold;"&gt;&lt;div&gt;&lt;span style="font-weight: bold;"&gt;Update:&lt;/span&gt;&lt;span&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt; Estuve refleccionando sobre todos estos eventos &lt;a href="http://aurelianito.blogspot.com/2010/02/una-reflexion-sobre-facebook.html"&gt;en este post&lt;/a&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;Update:&lt;/span&gt; Puse todos los eventos sobre como me echaron de facebook y se niegan a borrar mis datos &lt;a href="http://aurelianito.blogspot.com/2009/12/como-me-echaron-de-facebook.html"&gt;en este post&lt;/a&gt;.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Update:&lt;/span&gt; Mi cuenta de facebook está deshabilitada. Mandé un mail para preguntar porqué la deshabilitaron, porque hasta donde yo sé no violé ninguna de las reglas del servicio. Los voy a mantener al tanto de la respuesta.&lt;br /&gt;&lt;br /&gt;Hola a tod@s,&lt;br /&gt;quería contarles que tengo un nuevo proyecto. El mismo se llama "&lt;a href="http://www.facebook.com/group.php?gid=141856259260"&gt;Destruyendo facebook desde adentro&lt;/a&gt;" y consiste en ver cómo hacer para que en vez de que haya una sola empresa que maneje la red social de amigos y conocidos cada persona pueda tener sus datos donde quiera e igualmente pueda relacionarse con otra gente. Un poco como el mail, se puede mandar correos a personas que tienen un proveedor de correo distinto del tuyo.&lt;br /&gt;Para eso, hay algunas actividades que pueden hacer:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;sacar la propaganda con greasemonkey (&lt;a href="http://userscripts.org/scripts/show/13787" onmousedown="'UntrustedLink.bootstrap($(this)," target="_blank" rel="nofollow"&gt;&lt;span&gt;http://userscripts.org/scr&lt;/span&gt;&lt;wbr&gt;&lt;span class="word_break"&gt;&lt;/span&gt;ipts/show/13787&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;taggear mal las fotos&lt;/li&gt;&lt;li&gt;hacer apps que hagan cagadas&lt;/li&gt;&lt;li&gt;hacer bots que molesten en facebook (¿convendrá greasemonkey o WATiR para esto?)&lt;/li&gt;&lt;li&gt;hacer una red social distribuida que use cripto de clave pública para autenticar a las personas (tipo PGP).&lt;/li&gt;&lt;/ul&gt;Si quieren adherir a mi causa, pueden hacer todo esto (o alguna otra cosa que les parezca conducente) y unirse al grupo en &lt;a href="http://www.facebook.com/group.php?gid=141856259260"&gt;http://www.facebook.com/group.php?gid=141856259260&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Happy hacking,&lt;br /&gt;Aureliano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-8106226841705103212?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/8106226841705103212/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=8106226841705103212' title='39 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/8106226841705103212'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/8106226841705103212'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2009/10/destruyendo-facebook-desde-adentro.html' title='Destruyendo facebook desde adentro'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>39</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-9177518259235525604</id><published>2009-08-06T14:53:00.002-03:00</published><updated>2009-08-06T14:57:43.244-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='phishing'/><category scheme='http://www.blogger.com/atom/ns#' term='seguridad'/><title type='text'>¡Me atacó el phishing gallego!</title><content type='html'>Leanlo, ¡no tiene desperdicio!&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;from Phanida_Roidoung &lt;phanida@pdmo.mof.go.th&gt;&lt;br /&gt;reply-to allaccountuser@live.com&lt;br /&gt;to &lt;br /&gt;date Thu, Aug 6, 2009 at 2:20 PM&lt;br /&gt;subject Dear dc.uba.ar Owner&lt;br /&gt; &lt;br /&gt;hide details 2:20 PM (34 minutes ago)&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;Reply&lt;br /&gt; &lt;br /&gt; Follow up message&lt;br /&gt;Dear dc.uba.ar Owner,&lt;br /&gt;&lt;br /&gt;We are currently carrying-out a mentaiance&lt;br /&gt;process to your dc.uba.ar account, to&lt;br /&gt;complete this process you must reply to&lt;br /&gt;this email immediately,and enter your User&lt;br /&gt;Name here (******) And Password here(*****)&lt;br /&gt;if you are the rightful owner of this account.&lt;br /&gt;&lt;br /&gt;This process we help us to fight against&lt;br /&gt;SPAM MAILS.&lt;br /&gt;Failure to summit your password, will render&lt;br /&gt;your email address n-active from our database.&lt;br /&gt;You can also confirm your email address by&lt;br /&gt;logging into your dc.uba.ar&lt;br /&gt;account at:http://dc.uba.ar&lt;br /&gt;&lt;br /&gt;NOTE: You will be send a password reset&lt;br /&gt;messenge in next two (2)&lt;br /&gt;working days after undergoing this process&lt;br /&gt;for security reasons.&lt;br /&gt;&lt;br /&gt;Thank you form dc.uba.ar!&lt;br /&gt;THE dc.uba.ar TEAM&lt;/pre&gt;&lt;br /&gt;En particular, me hace cagar de risa esta parte:&lt;br /&gt;&lt;pre&gt;to&lt;br /&gt;complete this process you must reply to&lt;br /&gt;this email immediately,and enter your User&lt;br /&gt;Name here (******) And Password here(*****)&lt;br /&gt;if you are the rightful owner of this account.&lt;/pre&gt;&lt;br /&gt;Es la versión de mails de phishing del &lt;a href="http://www.paridotas.com/ve.php?id=153"&gt;virus gallego&lt;/a&gt;.&lt;br /&gt;Happy hacking,&lt;br /&gt;Aureliano&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-9177518259235525604?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/9177518259235525604/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=9177518259235525604' title='1 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/9177518259235525604'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/9177518259235525604'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2009/08/me-ataco-el-phishing-gallego.html' title='¡Me atacó el phishing gallego!'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-48948010627278843</id><published>2009-08-01T15:45:00.005-03:00</published><updated>2009-08-01T16:07:31.269-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Algunas cosas buenas y malas de python (para mi)</title><content type='html'>Cosas buenas:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Duck-typing&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Los espacios sirven para marcar bloques de código&lt;/li&gt;&lt;li&gt;Los bloques de código son elementos de primer orden del lenguaje&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Soporte para un montón de cosas (por ejemplo pyCUDA)&lt;/li&gt;&lt;li&gt;Matches por nombre en expresiones regulares&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Cosas malas:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Los objetos no son más que un mejunje de 2 diccionarios (el de la clase y el del objeto, sin orden)&lt;/li&gt;&lt;li&gt;Un montón de cosas están sacadas de los objetos, pero otras no. Esto lo deja inconsistente y molesto (teniendo que definir un montón de métodos mágicos de la forma __magic__)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Sin sintaxis buena para llamar al método de la clase padre (super, ¿dónde estás?)&lt;/li&gt;&lt;li&gt;"There is only one way to do it" salvo por las reglas para poner nombres de métodos ni clases. Por ejemplo, no queda claro si debe ser method_name, methodName o methodname (hay de los 3 en las biliotecas estándares)&lt;/li&gt;&lt;li&gt;No hay forma de definir bloques de código sin nombre (aunque con el agregado del with_statement, están bastante cerca del manejo de bloques de ruby). Los lambdas son una cosa que se queda muy corta.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Sintaxis especiales para demasiadas cosas (ejemplo: list comprehensions, for, while, decorators, etc)&lt;/li&gt;&lt;li&gt;Falta de separación entre strings y listas de bytes (¿Python 3000 lo arregla?, no sé)&lt;/li&gt;&lt;li&gt;Metaprogramar es complicado porque no hay bloques sin nombre y hay que definir/ llamar un montón de métodos __mágicos__.&lt;/li&gt;&lt;li&gt;Separación entre comandos y expresiones.&lt;/li&gt;&lt;/ul&gt;Happy hacking,&lt;br /&gt;Aureliano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-48948010627278843?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/48948010627278843/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=48948010627278843' title='6 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/48948010627278843'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/48948010627278843'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2009/08/algunas-cosas-buenas-y-malas-de-python.html' title='Algunas cosas buenas y malas de python (para mi)'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-7212802581426254880</id><published>2009-07-25T19:38:00.002-03:00</published><updated>2009-07-25T19:49:25.145-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='rapidito'/><category scheme='http://www.blogger.com/atom/ns#' term='rack-test'/><category scheme='http://www.blogger.com/atom/ns#' term='sinatra'/><title type='text'>Tests en rapidito</title><content type='html'>En &lt;a href="http://aurelianito.blogspot.com/search/label/rapidito"&gt;rapidito&lt;/a&gt; los tests siguen creciendo. Ahora le agregué un test al modelo de la base de datos (que por ahora tiene una sola tabla, pero espero que crezca bastante) y otro a los views y controllers (que también tienen que crecer).&lt;br /&gt;Todo está agregado en el &lt;tt&gt;rakefile&lt;/tt&gt;:&lt;br /&gt;&lt;pre&gt;$ rake -T&lt;br /&gt;(in /home/aure/devel/rapidito)&lt;br /&gt;rake db:initial       # Generate the initial pages for the wiki&lt;br /&gt;rake db:migrate       # Migrate the database&lt;br /&gt;rake default          # Run all tests&lt;br /&gt;rake test             # All tests&lt;br /&gt;rake test:functional  # Test controllers and views&lt;br /&gt;rake test:lib         # Library tests&lt;br /&gt;rake test:model       # Model tests&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Sigo usando una sqlite3 en memoria para todos los tests (parece que esto paga) y para hacer los tests funcionales usé la gem &lt;tt&gt;rack-test&lt;/tt&gt; como dice en la documentación de sinatra. Es impresionante como sirve esa lib tan chiquitita.&lt;br /&gt;Y los tests siguen creciendo, ya van 651 líneas de código&lt;br /&gt;&lt;pre&gt;~/devel/rapidito$ find test -name "*.rb" | xargs wc -l&lt;br /&gt;   26 test/lib/test_lang_hacks.rb&lt;br /&gt;   60 test/lib/elem_stack_test.rb&lt;br /&gt;   35 test/lib/rapidito_data_test.rb&lt;br /&gt;  187 test/lib/rapidito_html_test.rb&lt;br /&gt;   81 test/lib/state_test.rb&lt;br /&gt;   48 test/lib/nodes_test.rb&lt;br /&gt;  110 test/lib/tokenizer_test.rb&lt;br /&gt;   55 test/model/pages_test.rb&lt;br /&gt;   49 test/functional/start_test.rb&lt;br /&gt;  651 total&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Happy hacking,&lt;br /&gt;Aureliano&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-7212802581426254880?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/7212802581426254880/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=7212802581426254880' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/7212802581426254880'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/7212802581426254880'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2009/07/tests-en-rapidito.html' title='Tests en rapidito'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-1242209679758665173</id><published>2009-07-19T21:15:00.004-03:00</published><updated>2009-07-25T13:12:05.995-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='rapidito'/><category scheme='http://www.blogger.com/atom/ns#' term='git'/><category scheme='http://www.blogger.com/atom/ns#' term='markaby'/><category scheme='http://www.blogger.com/atom/ns#' term='github'/><category scheme='http://www.blogger.com/atom/ns#' term='sinatra'/><title type='text'>rapidito en github</title><content type='html'>Hola,&lt;br /&gt;puse un repo de rapidito (mi proyecto de base de datos basado en wikis) en github. Está disponible en &lt;a href="http://github.com/aurelianito/rapidito/tree/master"&gt;http://github.com/aurelianito/rapidito/tree/master&lt;/a&gt;. &lt;br /&gt;Si quieren usarlo, solo hay que hacer en el directorio clonado:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;rake db:migrate&lt;br /&gt;rake db:initial&lt;br /&gt;rackup&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Una vez que está corriendo, te conectás a http://localhost:9292 y tenés todas las instrucciones.&lt;br /&gt;Tiene como requerimientos sinatra, activerecord, markaby y sqlite3 (con su gem).&lt;br /&gt;Voy a ir avanzando este proyecto &lt;a href="http://pequenico.blogspot.com"&gt;cuando tenga algo de tiempo&lt;/a&gt;. Por ahora es solo un wiki más, pero espero que se transforme en algo distinto. A medida que tenga más cosas agregadas voy a ir avisando en el blog.&lt;br /&gt;Escucho sugerencias, y acepto patches ;).&lt;br /&gt;&lt;br /&gt;Happy hacking,&lt;br /&gt;Aureliano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-1242209679758665173?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/1242209679758665173/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=1242209679758665173' title='8 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/1242209679758665173'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/1242209679758665173'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2009/07/rapidito-en-github.html' title='rapidito en github'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-7633002584629589611</id><published>2009-07-16T13:50:00.004-03:00</published><updated>2009-07-17T02:12:53.366-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='rake'/><title type='text'>rake sh en otro directorio</title><content type='html'>&lt;span style="font-weight:bold;"&gt;Problema:&lt;/span&gt; Quiero ejecutar un comando desde otro directorio en rake (por ejemplo, ejecutar un makefile que está en un subdirectorio).&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Solución:&lt;/span&gt; Agrego al rakefile la posibilidad de ejecutar comandos en otro directorio. Para eso, al principio de mi rakefile puse:&lt;br /&gt;&lt;br /&gt;&lt;pre class="ruby"&gt;&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;fileutils&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;sh_in_dir&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt; &lt;span class="ident"&gt;dirname&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;*&lt;/span&gt;&lt;span class="ident"&gt;args&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;&amp;amp;&lt;/span&gt;&lt;span class="ident"&gt;block&lt;/span&gt; &lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span class="ident"&gt;old_path&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;pwd&lt;/span&gt;&lt;br /&gt;  &lt;span class="constant"&gt;FileUtils&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;chdir&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt; &lt;span class="ident"&gt;dirname&lt;/span&gt; &lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span class="ident"&gt;sh&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt; &lt;span class="punct"&gt;*&lt;/span&gt;&lt;span class="ident"&gt;args&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;&amp;amp;&lt;/span&gt;&lt;span class="ident"&gt;block&lt;/span&gt; &lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span class="constant"&gt;FileUtils&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;chdir&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt; &lt;span class="ident"&gt;old_path&lt;/span&gt; &lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Happy hacking,&lt;br /&gt;Aureliano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-7633002584629589611?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/7633002584629589611/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=7633002584629589611' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/7633002584629589611'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/7633002584629589611'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2009/07/rake-sh-en-otro-directorio.html' title='rake sh en otro directorio'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-3144782377629316312</id><published>2009-07-16T13:26:00.004-03:00</published><updated>2009-07-16T13:32:11.346-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='firefox'/><category scheme='http://www.blogger.com/atom/ns#' term='x11'/><category scheme='http://www.blogger.com/atom/ns#' term='xorg'/><title type='text'>Firefox remoto y local</title><content type='html'>&lt;span style="font-weight:bold;"&gt;Problema:&lt;/span&gt; Tengo un firefox corriendo en X11 y quiero correr otro firefox remotamente por X11 en otro host (usando el mismo display). Si lo ejecuto directamente, haciendo &lt;tt&gt;ssh -X -n host firefox&lt;/tt&gt; en vez de ejecutar el Firefox en la otra máquina, abre otra ventana del firefox que ya tengo corriendo.&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Solución: &lt;/span&gt; Usando la opción &lt;tt&gt;-no-remote&lt;/tt&gt; evito que el firefox busque ventanas de firefox abiertas para abrir una ventana nueva y se ejecuta remotamente. La línea de comando entera es: &lt;tt&gt;ssh -X -n host firefox -no-remote&lt;/tt&gt;.&lt;br /&gt;&lt;br /&gt;Gracias Pedro Varangot por contarme del parámetro &lt;tt&gt;-no-remote&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;Happy hacking,&lt;br /&gt;Aureliano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-3144782377629316312?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/3144782377629316312/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=3144782377629316312' title='1 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/3144782377629316312'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/3144782377629316312'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2009/07/firefox-remoto-y-local.html' title='Firefox remoto y local'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-2490707093104171819</id><published>2009-07-14T01:47:00.003-03:00</published><updated>2009-07-14T01:49:52.910-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rapidito'/><category scheme='http://www.blogger.com/atom/ns#' term='logo'/><title type='text'>Logo versión 2</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_vrWP6mUamXY/SlwOPG1CJwI/AAAAAAAAAGs/jknpgC6cDE4/s1600-h/logo.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 178px; height: 67px;" src="http://1.bp.blogspot.com/_vrWP6mUamXY/SlwOPG1CJwI/AAAAAAAAAGs/jknpgC6cDE4/s400/logo.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5358173309357926146" /&gt;&lt;/a&gt;&lt;br /&gt;Esta versión del logo de rapidito se viene con texto y fondo. Y me parece que se "mueve" un poco más. De a poco voy aprendiendo a usar el inkscape.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-2490707093104171819?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/2490707093104171819/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=2490707093104171819' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/2490707093104171819'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/2490707093104171819'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2009/07/logo-version-2.html' title='Logo versión 2'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_vrWP6mUamXY/SlwOPG1CJwI/AAAAAAAAAGs/jknpgC6cDE4/s72-c/logo.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-7005020220220907149</id><published>2009-07-12T21:51:00.004-03:00</published><updated>2009-07-12T21:55:01.213-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rapidito'/><category scheme='http://www.blogger.com/atom/ns#' term='dibujo'/><category scheme='http://www.blogger.com/atom/ns#' term='logo'/><title type='text'>Logo para rapidito</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_vrWP6mUamXY/SlqFZjUEWeI/AAAAAAAAAGk/UOC0cfpiEbA/s1600-h/logo.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 50px; height: 67px;" src="http://3.bp.blogspot.com/_vrWP6mUamXY/SlqFZjUEWeI/AAAAAAAAAGk/UOC0cfpiEbA/s400/logo.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5357741380733262306" /&gt;&lt;/a&gt;&lt;br /&gt;Estoy pensando en un logo para la base de datos/wiki que estoy haciendo. ¿Qué les parece este? La idea es ponerlo arriba a la izquierda en todas las páginas y como ícono en la barra de navegación del browser.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-7005020220220907149?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/7005020220220907149/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=7005020220220907149' title='3 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/7005020220220907149'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/7005020220220907149'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2009/07/logo-para-rapidito.html' title='Logo para rapidito'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_vrWP6mUamXY/SlqFZjUEWeI/AAAAAAAAAGk/UOC0cfpiEbA/s72-c/logo.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-1030567752923382780</id><published>2009-07-05T19:08:00.005-03:00</published><updated>2009-07-07T19:00:41.994-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='regexp'/><category scheme='http://www.blogger.com/atom/ns#' term='monkeypatch'/><title type='text'>Patch en Regexp para poder usarlas como clave en un Hash</title><content type='html'>Siguiendo mi proyecto de hacer mi wiki en Ruby, encontré un comportamiento muy raro.&lt;br /&gt;Generé un hash (que se llama @rules) que no tiene un elemento que tiene. O sea, &lt;code&gt;@rules[@rules.keys[2]]&lt;/code&gt; da nil, pero &lt;code&gt;@rules.values[2]&lt;/code&gt; devuelve el objeto asociado a la clave &lt;code&gt;@rules.keys[2]&lt;/code&gt;. Como este hash tiene como claves un montón de expresiones regulares, me imaginé que había un problema con el hash y el eql? de Regexp, así que los implementé de nuevo y monkeypatchié.&lt;br /&gt;Este es el código:&lt;br /&gt;&lt;br /&gt;&lt;pre class="ruby"&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;Regexp&lt;/span&gt;&lt;br /&gt; &lt;span class="ident"&gt;alias_method&lt;/span&gt; &lt;span class="symbol"&gt;:old_rapidito_inspect&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:inspect&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;inspect&lt;/span&gt;&lt;br /&gt;   &lt;span class="attribute"&gt;@inspect&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;old_rapidito_inspect&lt;/span&gt; &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="attribute"&gt;@inspect&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;nil?&lt;/span&gt;&lt;br /&gt;   &lt;span class="attribute"&gt;@inspect&lt;/span&gt;&lt;br /&gt; &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;eql?&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt; &lt;span class="ident"&gt;other&lt;/span&gt; &lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;   &lt;span class="constant"&gt;false&lt;/span&gt; &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;other&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;!=&lt;/span&gt; &lt;span class="ident"&gt;Regexp&lt;/span&gt;&lt;br /&gt;   &lt;span class="ident"&gt;self&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;inspect&lt;/span&gt; &lt;span class="punct"&gt;==&lt;/span&gt; &lt;span class="ident"&gt;other&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;inspect&lt;/span&gt;&lt;br /&gt; &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; &lt;span class="ident"&gt;alias_method&lt;/span&gt; &lt;span class="symbol"&gt;:&amp;quot;&lt;/span&gt;&lt;span class="symbol"&gt;==&lt;/span&gt;&lt;span class="symbol"&gt;&amp;quot;&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:eql?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;hash&lt;/span&gt;&lt;br /&gt;   &lt;span class="constant"&gt;self&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;inspect&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;hash&lt;/span&gt;&lt;br /&gt; &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Esta corrección me anduvo con la siguiente versión de ruby:&lt;br /&gt;&lt;pre&gt;$ ruby --version&lt;br /&gt;ruby 1.8.7 (2008-08-11 patchlevel 72) [i486-linux]&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Espero que les sirva.&lt;br /&gt;Happy hacking,&lt;br /&gt;Aureliano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-1030567752923382780?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/1030567752923382780/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=1030567752923382780' title='2 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/1030567752923382780'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/1030567752923382780'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2009/07/patch-en-regexp-para-poder-usarlas-como.html' title='Patch en Regexp para poder usarlas como clave en un Hash'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-3389397049356128556</id><published>2009-07-03T13:13:00.004-03:00</published><updated>2009-07-07T18:54:50.906-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='regexp'/><category scheme='http://www.blogger.com/atom/ns#' term='monkeypatch'/><title type='text'>Upcase con acentos</title><content type='html'>En ruby no se calculan los cambios minúscula mayúscula para las letras acentuadas. Por ejemplo:&lt;br /&gt;&lt;pre&gt;irb(main):002:0&gt; puts "áa".upcase&lt;br /&gt;áA&lt;br /&gt;=&gt; nil&lt;/pre&gt;&lt;br /&gt;Para que ande un poco mejor (y tome las letras acentuadas de un montón de lenguajes), encontré un hack que en 10 líneas de código hace que puedan pasarse a mínusculas y mayúsculas los caracteres acentuados. Usando que todas las letras minúsculas y mayúsculas acentuadas están todas juntas, armé un par de gsubs que resuelven el problema.&lt;br /&gt;&lt;pre class="ruby"&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;String&lt;/span&gt;&lt;br /&gt;  &lt;span class="ident"&gt;alias_method&lt;/span&gt; &lt;span class="symbol"&gt;:old_rapidito_upcase&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:upcase&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;upcase&lt;/span&gt;&lt;br /&gt;    &lt;span class="constant"&gt;self&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;gsub&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt; &lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="regex"&gt;&lt;span class="escape"&gt;\303&lt;/span&gt;[&lt;span class="escape"&gt;\240&lt;/span&gt;-&lt;span class="escape"&gt;\277&lt;/span&gt;]&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt; &lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;&lt;br /&gt;      &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;match&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;&lt;br /&gt;      &lt;span class="ident"&gt;match&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;].&lt;/span&gt;&lt;span class="ident"&gt;chr&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt; &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;match&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt; &lt;span class="punct"&gt;-&lt;/span&gt; &lt;span class="number"&gt;040&lt;/span&gt;&lt;span class="punct"&gt;).&lt;/span&gt;&lt;span class="ident"&gt;chr&lt;/span&gt;&lt;br /&gt;    &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;old_rapidito_upcase&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;  &lt;br /&gt;  &lt;span class="ident"&gt;alias_method&lt;/span&gt; &lt;span class="symbol"&gt;:old_rapidito_downcase&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:downcase&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;downcase&lt;/span&gt;&lt;br /&gt;    &lt;span class="constant"&gt;self&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;gsub&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt; &lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="regex"&gt;&lt;span class="escape"&gt;\303&lt;/span&gt;[&lt;span class="escape"&gt;\200&lt;/span&gt;-&lt;span class="escape"&gt;\237&lt;/span&gt;]&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt; &lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;&lt;br /&gt;      &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;match&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;&lt;br /&gt;      &lt;span class="ident"&gt;match&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;].&lt;/span&gt;&lt;span class="ident"&gt;chr&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt; &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;match&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt; &lt;span class="number"&gt;040&lt;/span&gt;&lt;span class="punct"&gt;).&lt;/span&gt;&lt;span class="ident"&gt;chr&lt;/span&gt;&lt;br /&gt;    &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;old_rapidito_downcase&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;Lo que hago acá es reemplazar las funciones &lt;code&gt;upcase&lt;/code&gt; y &lt;code&gt;downcase&lt;/code&gt; para que manejen los acentos, sumando o restando 32 (40 en octal) al segundo byte. Pongo este código en &lt;code&gt;lang_hacks.rb&lt;/code&gt; y sale todo con fritas. Mirando el irb&lt;br /&gt;&lt;pre&gt;irb(main):001:0&gt; require 'lang_hacks'&lt;br /&gt;=&gt; true&lt;br /&gt;irb(main):002:0&gt; "aÁ".upcase&lt;br /&gt;=&gt; "A\303\201"&lt;br /&gt;irb(main):003:0&gt; puts "aÁ".upcase&lt;br /&gt;AÁ&lt;br /&gt;=&gt; nil&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Espero que les sirva.&lt;br /&gt;Happy hacking,&lt;br /&gt;Aureliano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-3389397049356128556?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/3389397049356128556/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=3389397049356128556' title='7 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/3389397049356128556'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/3389397049356128556'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2009/07/upcase-con-acentos.html' title='Upcase con acentos'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-3502504797391130994</id><published>2009-07-01T17:35:00.003-03:00</published><updated>2009-07-07T23:34:33.892-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='soja'/><category scheme='http://www.blogger.com/atom/ns#' term='dengue'/><category scheme='http://www.blogger.com/atom/ns#' term='alfredo'/><category scheme='http://www.blogger.com/atom/ns#' term='humor'/><category scheme='http://www.blogger.com/atom/ns#' term='política'/><category scheme='http://www.blogger.com/atom/ns#' term='rap'/><title type='text'>Rap del dengue sojero</title><content type='html'>Entra enfermo de dengue&lt;br /&gt;Mosquito pica enfermo&lt;br /&gt;Sapo se come mosquito&lt;br /&gt;¡No hay dengue!&lt;br /&gt;&lt;br /&gt;Alfredo planta soja&lt;br /&gt;Alfredo fumiga veneno&lt;br /&gt;Veneno mata sapito&lt;br /&gt;Sapo muerto no come mosquito&lt;br /&gt;¡Hay soja!&lt;br /&gt;¡Hay veneno!&lt;br /&gt;¡No hay sapo!&lt;br /&gt;¡Hay dengue!&lt;br /&gt;¡Hay mosquito!&lt;br /&gt;&lt;br /&gt;Hormiga atómica fumiga mosquito&lt;br /&gt;Sapo vivo se caga de hambre&lt;br /&gt;Año que viene&lt;br /&gt;¡Se muere!&lt;br /&gt;¡No hay sapo!&lt;br /&gt;¡Hay dengue!&lt;br /&gt;¡Hay malaria!&lt;br /&gt;¡Hay peste!&lt;br /&gt;¡Hay mosquito!&lt;br /&gt;&lt;br /&gt;Nonsanto reparte los sobres&lt;br /&gt;Al periodismo in-the-pendiente&lt;br /&gt;¡Hay sobre!&lt;br /&gt;¡No hay noticia!&lt;br /&gt;¡Hay soja!&lt;br /&gt;¡Hay veneno!&lt;br /&gt;¡No hay sapo!&lt;br /&gt;¡Hay dengue!&lt;br /&gt;¡Hay mosquito!&lt;br /&gt;&lt;br /&gt;Nonsanto no garpa bloguero&lt;br /&gt;Bloguero publica noticia&lt;br /&gt;¡Nonsanto se cae de culo!&lt;br /&gt;¡Cristina prohibe la soja!&lt;br /&gt;¡No hay sobre!&lt;br /&gt;¡Hay sapo!&lt;br /&gt;¡No hay dengue!&lt;br /&gt;¡No hay mosquito!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Vía:&lt;/span&gt; &lt;a href="http://artepolitica.com/comunidad/el-rap-del-dengue-sojero/"&gt;artepolitica.com&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-3502504797391130994?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/3502504797391130994/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=3502504797391130994' title='3 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/3502504797391130994'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/3502504797391130994'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2009/07/rap-del-dengue-sojero.html' title='Rap del dengue sojero'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-3187479126662238583</id><published>2009-07-01T14:55:00.004-03:00</published><updated>2009-07-07T18:55:32.534-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vmware'/><title type='text'>Autofit guest solo anda si abrís la consola después de loguearte</title><content type='html'>Comprobado en Vmware Server 2.0.1. &lt;br /&gt;Host: KUbuntu 9.0.4. 64 bits.&lt;br /&gt;Guest: KUbuntu 9.0.4. 32 bits.&lt;br /&gt;&lt;br /&gt;¿Estoy haciendo algo mal?&lt;br /&gt;Aureliano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-3187479126662238583?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/3187479126662238583/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=3187479126662238583' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/3187479126662238583'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/3187479126662238583'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2009/07/autofit-guest-solo-anda-si-abris-la.html' title='Autofit guest solo anda si abrís la consola después de loguearte'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-1410164064116629157</id><published>2009-06-30T23:48:00.005-03:00</published><updated>2009-07-07T18:59:31.560-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='rapidito'/><category scheme='http://www.blogger.com/atom/ns#' term='regexp'/><category scheme='http://www.blogger.com/atom/ns#' term='tokenizer'/><title type='text'>Más rapidito</title><content type='html'>Como &lt;a href="http://aurelianito.blogspot.com/2009/06/tokenizer-de-rapidito.html"&gt;les&lt;/a&gt; &lt;a href="http://aurelianito.blogspot.com/2009/06/tokenizer-de-rapidito-segunda-version.html"&gt;estuve&lt;/a&gt; &lt;a href="http://aurelianito.blogspot.com/2009/06/pequenas-delicias-de-las-expresiones.html"&gt;contando&lt;/a&gt;, sigo escribiendo mi wiki. Ya parsea un subconjunto interesante del lenguaje definido por &lt;a href="http://trac.edgewall.org"&gt;trac&lt;/a&gt;.&lt;br /&gt;Siguiendo la tradición, les cuento como está avanzando el tokenizer. Al tokenizer lo simplifiqué para que devuelva la expresión regular que matcheo junto con el match (en vez del "tipo"). Esto hizo que la interfase para definir las reglas para tokenizar sea más simple. Si no hay ninguna regla que matchee sigue devolviendo &lt;tt&gt;["string", :text]&lt;/tt&gt;.&lt;br /&gt;Sin más, acá el código:&lt;br /&gt;&lt;pre class="ruby"&gt;&lt;span class="keyword"&gt;module &lt;/span&gt;&lt;span class="module"&gt;Rapidito&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;Tokenizer&lt;/span&gt;&lt;br /&gt;  &lt;br /&gt;    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;initialize&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt; &lt;span class="punct"&gt;*&lt;/span&gt;&lt;span class="ident"&gt;delimiters&lt;/span&gt; &lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;      &lt;span class="attribute"&gt;@delimiter_list&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;delimiters&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt;  &lt;span class="punct"&gt;[/&lt;/span&gt;&lt;span class="regex"&gt;&lt;span class="escape"&gt;\z&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;/]&lt;/span&gt;&lt;br /&gt;      &lt;span class="attribute"&gt;@match_cache&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;nil&lt;/span&gt;&lt;br /&gt;    &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;source&lt;/span&gt;&lt;br /&gt;      &lt;span class="ident"&gt;valid_cache?&lt;/span&gt; &lt;span class="punct"&gt;?&lt;/span&gt; &lt;span class="attribute"&gt;@match_cache&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;].&lt;/span&gt;&lt;span class="ident"&gt;to_s&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt; &lt;span class="attribute"&gt;@source&lt;/span&gt; &lt;span class="punct"&gt;:&lt;/span&gt; &lt;span class="attribute"&gt;@source&lt;/span&gt;&lt;br /&gt;    &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;source=&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;s&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;      &lt;span class="attribute"&gt;@match_cache&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;nil&lt;/span&gt;&lt;br /&gt;      &lt;span class="attribute"&gt;@source&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;s&lt;/span&gt;&lt;br /&gt;    &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;has_next?&lt;/span&gt;&lt;br /&gt;      &lt;span class="punct"&gt;!&lt;/span&gt;&lt;span class="attribute"&gt;@source&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;empty?&lt;/span&gt; &lt;span class="punct"&gt;||&lt;/span&gt; &lt;span class="ident"&gt;valid_cache?&lt;/span&gt;&lt;br /&gt;    &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;valid_cache?&lt;/span&gt;&lt;br /&gt;      &lt;span class="punct"&gt;(!&lt;/span&gt;&lt;span class="attribute"&gt;@match_cache&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;nil?&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="attribute"&gt;@match_cache&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;].&lt;/span&gt;&lt;span class="ident"&gt;to_s&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;length&lt;/span&gt; &lt;span class="punct"&gt;&amp;gt;&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;next_match&lt;/span&gt;&lt;br /&gt;      &lt;span class="attribute"&gt;@delimiter_list&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;map&lt;/span&gt; &lt;span class="punct"&gt;{|&lt;/span&gt;&lt;span class="ident"&gt;regex&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="ident"&gt;regex&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;match&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="attribute"&gt;@source&lt;/span&gt;&lt;span class="punct"&gt;),&lt;/span&gt;&lt;span class="ident"&gt;regex&lt;/span&gt;&lt;span class="punct"&gt;]}.&lt;/span&gt;&lt;span class="ident"&gt;reject&lt;/span&gt; &lt;span class="punct"&gt;{|&lt;/span&gt;&lt;span class="ident"&gt;p&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="ident"&gt;p&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;].&lt;/span&gt;&lt;span class="ident"&gt;nil?&lt;/span&gt;&lt;span class="punct"&gt;}.&lt;/span&gt;&lt;span class="ident"&gt;inject&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;&lt;br /&gt;        &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;better&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;&lt;br /&gt;        &lt;span class="ident"&gt;better_pos&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;better&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;].&lt;/span&gt;&lt;span class="ident"&gt;pre_match&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;length&lt;/span&gt;&lt;br /&gt;        &lt;span class="ident"&gt;new_pos&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;].&lt;/span&gt;&lt;span class="ident"&gt;pre_match&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;length&lt;/span&gt;&lt;br /&gt;        &lt;br /&gt;        &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;better_pos&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt; &lt;span class="ident"&gt;new_pos&lt;/span&gt;&lt;br /&gt;          &lt;span class="ident"&gt;better&lt;/span&gt;&lt;br /&gt;        &lt;span class="keyword"&gt;elsif&lt;/span&gt; &lt;span class="ident"&gt;new_pos&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt; &lt;span class="ident"&gt;better_pos&lt;/span&gt;&lt;br /&gt;          &lt;span class="ident"&gt;new&lt;/span&gt;&lt;br /&gt;        &lt;span class="keyword"&gt;elsif&lt;/span&gt; &lt;span class="ident"&gt;better&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;].&lt;/span&gt;&lt;span class="ident"&gt;to_s&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;length&lt;/span&gt; &lt;span class="punct"&gt;&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;].&lt;/span&gt;&lt;span class="ident"&gt;to_s&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;length&lt;/span&gt;&lt;br /&gt;          &lt;span class="ident"&gt;better&lt;/span&gt;&lt;br /&gt;        &lt;span class="keyword"&gt;else&lt;/span&gt;&lt;br /&gt;          &lt;span class="ident"&gt;new&lt;/span&gt;&lt;br /&gt;        &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;      &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;    &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;next_token&lt;/span&gt;&lt;br /&gt;      &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="attribute"&gt;@match_cache&lt;/span&gt; &lt;span class="comment"&gt;#cached delimiter&lt;/span&gt;&lt;br /&gt;        &lt;span class="ident"&gt;rv&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="attribute"&gt;@match_cache&lt;/span&gt;&lt;br /&gt;        &lt;span class="attribute"&gt;@match_cache&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;nil&lt;/span&gt;&lt;br /&gt;        &lt;span class="keyword"&gt;return&lt;/span&gt; &lt;span class="ident"&gt;rv&lt;/span&gt;&lt;br /&gt;      &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;      &lt;br /&gt;      &lt;span class="ident"&gt;match&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;next_match&lt;/span&gt;&lt;br /&gt;      &lt;span class="ident"&gt;p&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;match&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;].&lt;/span&gt;&lt;span class="ident"&gt;pre_match&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;length&lt;/span&gt;&lt;br /&gt;      &lt;span class="attribute"&gt;@source&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="attribute"&gt;@source&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="ident"&gt;p&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt; &lt;span class="ident"&gt;match&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;].&lt;/span&gt;&lt;span class="ident"&gt;to_s&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;length&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="attribute"&gt;@source&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;length&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt;&lt;br /&gt;      &lt;br /&gt;      &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;p&lt;/span&gt; &lt;span class="punct"&gt;==&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt; &lt;span class="comment"&gt;#delimiter&lt;/span&gt;&lt;br /&gt;        &lt;span class="ident"&gt;match&lt;/span&gt;&lt;br /&gt;      &lt;span class="keyword"&gt;else&lt;/span&gt; &lt;span class="comment"&gt;#text&lt;/span&gt;&lt;br /&gt;        &lt;span class="attribute"&gt;@match_cache&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;match&lt;/span&gt;&lt;br /&gt;        &lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="ident"&gt;match&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;].&lt;/span&gt;&lt;span class="ident"&gt;pre_match&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:text&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt;&lt;br /&gt;      &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;    &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;all_tokens&lt;/span&gt;&lt;br /&gt;      &lt;span class="ident"&gt;tokens&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;[]&lt;/span&gt;&lt;br /&gt;      &lt;span class="keyword"&gt;while&lt;/span&gt; &lt;span class="ident"&gt;has_next?&lt;/span&gt;&lt;br /&gt;        &lt;span class="ident"&gt;tokens&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="ident"&gt;next_token&lt;/span&gt;&lt;br /&gt;      &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;      &lt;span class="ident"&gt;tokens&lt;/span&gt;&lt;br /&gt;    &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;Y si miran los tests de unidad, van a ver que también quedaron más lindos:&lt;br /&gt;&lt;pre class="ruby"&gt;&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;test/unit&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;&lt;br /&gt;&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;rapidito/tokenizer&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="ident"&gt;include&lt;/span&gt; &lt;span class="constant"&gt;Rapidito&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;TokenizerTest&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt; &lt;span class="constant"&gt;Test&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Unit&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;TestCase&lt;/span&gt;&lt;br /&gt;  &lt;br /&gt;  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;test_no_token&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;tok&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Tokenizer&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;source&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;aaaa&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;assert_equal&lt;/span&gt; &lt;span class="constant"&gt;true&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;has_next?&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;assert_equal&lt;/span&gt; &lt;span class="punct"&gt;[&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;aaaa&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:text&lt;/span&gt;&lt;span class="punct"&gt;],&lt;/span&gt; &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;next_token&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;assert_equal&lt;/span&gt; &lt;span class="constant"&gt;false&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;has_next?&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;  &lt;br /&gt;  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;assert_all_tokens&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt; &lt;span class="ident"&gt;expected&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;tokenizer&lt;/span&gt; &lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;assert_equal&lt;/span&gt; &lt;span class="ident"&gt;expected&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;br /&gt;      &lt;span class="ident"&gt;tokenizer&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;all_tokens&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;map&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;token&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;kind&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="ident"&gt;token&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;to_s&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;kind&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;  &lt;br /&gt;  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;test_two_delimiters&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;tok&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Tokenizer&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt; &lt;br /&gt;      &lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="regex"&gt;&lt;span class="escape"&gt;\|&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;/,&lt;/span&gt; &lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="regex"&gt;;;&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt; &lt;br /&gt;    &lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;source&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;aa|bbb;;;;cccc&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;assert_all_tokens&lt;/span&gt; \&lt;br /&gt;      &lt;span class="punct"&gt;[&lt;/span&gt; &lt;span class="punct"&gt;[&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;aa&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:text&lt;/span&gt;&lt;span class="punct"&gt;],&lt;/span&gt; &lt;span class="punct"&gt;[&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;|&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="regex"&gt;&lt;span class="escape"&gt;\|&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;/],&lt;/span&gt; &lt;span class="punct"&gt;[&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;bbb&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:text&lt;/span&gt;&lt;span class="punct"&gt;],&lt;/span&gt; &lt;br /&gt;        &lt;span class="punct"&gt;[&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;;;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="regex"&gt;;;&lt;/span&gt;&lt;span class="punct"&gt;/],&lt;/span&gt; &lt;span class="punct"&gt;[&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;;;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="regex"&gt;;;&lt;/span&gt;&lt;span class="punct"&gt;/],&lt;/span&gt; &lt;span class="punct"&gt;[&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;cccc&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:text&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt; &lt;span class="punct"&gt;],&lt;/span&gt; &lt;br /&gt;      &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;source&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;aa;;bbb||cccc&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;assert_all_tokens&lt;/span&gt; \&lt;br /&gt;      &lt;span class="punct"&gt;[&lt;/span&gt; &lt;span class="punct"&gt;[&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;aa&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:text&lt;/span&gt;&lt;span class="punct"&gt;],&lt;/span&gt; &lt;span class="punct"&gt;[&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;;;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="regex"&gt;;;&lt;/span&gt;&lt;span class="punct"&gt;/],&lt;/span&gt; &lt;span class="punct"&gt;[&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;bbb&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:text&lt;/span&gt;&lt;span class="punct"&gt;],&lt;/span&gt; &lt;br /&gt;        &lt;span class="punct"&gt;[&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;|&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="regex"&gt;&lt;span class="escape"&gt;\|&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;/],&lt;/span&gt; &lt;span class="punct"&gt;[&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;|&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="regex"&gt;&lt;span class="escape"&gt;\|&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;/],&lt;/span&gt; &lt;span class="punct"&gt;[&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;cccc&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:text&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt; &lt;span class="punct"&gt;],&lt;/span&gt; &lt;br /&gt;      &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;  &lt;br /&gt;  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;test_choose_longest_match&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;tok&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Tokenizer&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt; &lt;br /&gt;      &lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="regex"&gt;aa&lt;/span&gt;&lt;span class="punct"&gt;/,&lt;/span&gt; &lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="regex"&gt;aaa&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt;&lt;br /&gt;    &lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;source&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;aaaa&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;assert_all_tokens&lt;/span&gt; &lt;span class="punct"&gt;[&lt;/span&gt; &lt;span class="punct"&gt;[&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;aaa&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="regex"&gt;aaa&lt;/span&gt;&lt;span class="punct"&gt;/],&lt;/span&gt; &lt;span class="punct"&gt;[&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;a&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:text&lt;/span&gt; &lt;span class="punct"&gt;]&lt;/span&gt; &lt;span class="punct"&gt;],&lt;/span&gt; &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;  &lt;br /&gt;  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;test_reset_precache&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;tok&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Tokenizer&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt; &lt;br /&gt;      &lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="regex"&gt;&lt;span class="escape"&gt;\|&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;/,&lt;/span&gt; &lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="regex"&gt;,&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt;&lt;br /&gt;    &lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;source&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;original start|original end&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;next_token&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;source&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;new start,new end&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;assert_equal&lt;/span&gt; &lt;span class="punct"&gt;[&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;new start&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:text&lt;/span&gt;&lt;span class="punct"&gt;],&lt;/span&gt; &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;next_token&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;  &lt;br /&gt;  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;test_almost_finished&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;tok&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Tokenizer&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt; &lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="regex"&gt;!&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt; &lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;source&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;bang!&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;next_token&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;assert_equal&lt;/span&gt; &lt;span class="constant"&gt;true&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;has_next?&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;next_token&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;assert_equal&lt;/span&gt; &lt;span class="constant"&gt;false&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;has_next?&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;  &lt;br /&gt;  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;test_carriage_return_ending&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;tok&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Tokenizer&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt; &lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="regex"&gt;!&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt; &lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;source&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;bang!&lt;span class="escape"&gt;\n&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;next_token&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;assert_equal&lt;/span&gt; &lt;span class="constant"&gt;true&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;has_next?&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;next_token&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;assert_equal&lt;/span&gt; &lt;span class="constant"&gt;true&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;has_next?&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;assert_equal&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&lt;span class="escape"&gt;\n&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;next_token&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;].&lt;/span&gt;&lt;span class="ident"&gt;to_s&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;assert_equal&lt;/span&gt; &lt;span class="constant"&gt;false&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;has_next?&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;  &lt;br /&gt;  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;test_transparent_caching&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;tok&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Tokenizer&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt; &lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="regex"&gt;!&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt; &lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;source&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;bang!pum&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;next_token&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span class="ident"&gt;assert_equal&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;!pum&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;source&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;  &lt;br /&gt;  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;test_match_klass&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;tok&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Tokenizer&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt; &lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="regex"&gt;!&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt; &lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;source&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;!bang!pum&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span class="ident"&gt;assert_equal&lt;/span&gt; \&lt;br /&gt;      &lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="constant"&gt;MatchData&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="constant"&gt;String&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="constant"&gt;MatchData&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="constant"&gt;String&lt;/span&gt;&lt;span class="punct"&gt;],&lt;/span&gt; &lt;br /&gt;      &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;all_tokens&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;map&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;kind&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;}&lt;/span&gt;&lt;br /&gt;  &lt;span class="ident"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;Happy hacking,&lt;br /&gt;Aureliano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-1410164064116629157?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/1410164064116629157/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=1410164064116629157' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/1410164064116629157'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/1410164064116629157'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2009/06/mas-rapidito.html' title='Más rapidito'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-9207448683611791767</id><published>2009-06-19T14:18:00.002-03:00</published><updated>2009-07-07T18:56:39.831-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='tcp/ip'/><category scheme='http://www.blogger.com/atom/ns#' term='bouncer'/><title type='text'>Bouncer versión 2</title><content type='html'>Hice una nueva versión del bouncer que permite bouncear a varios targets desde un mismo host:&lt;br /&gt;&lt;pre&gt;#!/usr/bin/env ruby&lt;br /&gt;&lt;br /&gt;# == Synopsis&lt;br /&gt;#&lt;br /&gt;# bouncer.rb: Redirects TCP connections to distant machines. Handles simultaneously many connections.&lt;br /&gt;#&lt;br /&gt;# == Usage&lt;br /&gt;#&lt;br /&gt;# ruby redirect.rb [OPTION]&lt;br /&gt;#&lt;br /&gt;# -h, --help:&lt;br /&gt;#   Show help&lt;br /&gt;#&lt;br /&gt;# --ip ip, -i ip:&lt;br /&gt;#   Accept connections from ip (default 127.0.0.1)&lt;br /&gt;#&lt;br /&gt;# --port port, -p port:&lt;br /&gt;#   Listen on port (default 12345)&lt;br /&gt;#&lt;br /&gt;# --target ip:port, -t ip:port&lt;br /&gt;#   Connect to ip:port (default 127.0.0.1:23456)&lt;br /&gt;#&lt;br /&gt;&lt;br /&gt;require 'getoptlong'&lt;br /&gt;require 'rdoc/usage'&lt;br /&gt;require 'socket'&lt;br /&gt;&lt;br /&gt;class Bouncer&lt;br /&gt; def self.for_host( source_ip, start_port, targets )&lt;br /&gt;  rules = {}&lt;br /&gt;  targets.each_with_index do&lt;br /&gt;   |target, index|&lt;br /&gt;   rules[ start_port + index ] = target&lt;br /&gt;  end&lt;br /&gt;  self.new( source_ip, rules )&lt;br /&gt; end&lt;br /&gt; def initialize( source_ip, port_target_map )&lt;br /&gt;  @port_target_map = port_target_map&lt;br /&gt;  @source_ip = source_ip&lt;br /&gt;&lt;br /&gt;  @servers = @port_target_map.keys.map do&lt;br /&gt;    |port|&lt;br /&gt;    ss = TCPServer.new( "", port )&lt;br /&gt;    ss.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1 )&lt;br /&gt;    ss&lt;br /&gt;  end&lt;br /&gt;    &lt;br /&gt;  @descriptors = @servers.clone&lt;br /&gt;  @next_step = {}&lt;br /&gt; end&lt;br /&gt;&lt;br /&gt; def handle_new_connection( ss )&lt;br /&gt;  incoming = ss.accept&lt;br /&gt;  if incoming.peeraddr[3] == @source_ip&lt;br /&gt;   begin&lt;br /&gt;    outgoing = TCPSocket.new( *@port_target_map[incoming.addr[1]] )&lt;br /&gt;    @next_step[ incoming ] = outgoing&lt;br /&gt;    @next_step[ outgoing ] = incoming&lt;br /&gt;&lt;br /&gt;    @descriptors += [ incoming, outgoing ]&lt;br /&gt;   rescue&lt;br /&gt;    silent_close( incoming )&lt;br /&gt;   end&lt;br /&gt;  else&lt;br /&gt;   silent_close( incoming )&lt;br /&gt;  end&lt;br /&gt; end&lt;br /&gt;&lt;br /&gt; def silent_close( sock )&lt;br /&gt;  begin&lt;br /&gt;   sock.close&lt;br /&gt;  rescue&lt;br /&gt;   #do nothing intentionally&lt;br /&gt;  end&lt;br /&gt; end&lt;br /&gt;&lt;br /&gt;  def propagate(sock)&lt;br /&gt;    next_sock = @next_step[sock]&lt;br /&gt;    next_sock.write(sock.read_nonblock(1000 * 1000))&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt; def finish_connection(sock)&lt;br /&gt;  next_sock = @next_step[sock]&lt;br /&gt;  [ sock, next_sock ].each do&lt;br /&gt;   |s|&lt;br /&gt;   silent_close(s)&lt;br /&gt;   @descriptors.delete(s)&lt;br /&gt;   @next_step.delete(s)&lt;br /&gt;  end&lt;br /&gt; end&lt;br /&gt;&lt;br /&gt; def run&lt;br /&gt;  loop do&lt;br /&gt;   connections = select( @descriptors )&lt;br /&gt;   connections[0].each do&lt;br /&gt;    |sock|&lt;br /&gt;    if @servers.include? sock then&lt;br /&gt;     handle_new_connection( sock )&lt;br /&gt;    else&lt;br /&gt;     begin&lt;br /&gt;      sock.eof? ? finish_connection(sock) : propagate(sock)&lt;br /&gt;     rescue&lt;br /&gt;      finish_connection(sock)&lt;br /&gt;     end&lt;br /&gt;    end&lt;br /&gt;   end&lt;br /&gt;  end&lt;br /&gt; end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;if $0 == __FILE__ then&lt;br /&gt;&lt;br /&gt; opts = GetoptLong.new(&lt;br /&gt;   [ '--help', '-h', GetoptLong::NO_ARGUMENT ],&lt;br /&gt;   [ '--ip', '-i', GetoptLong::REQUIRED_ARGUMENT ],&lt;br /&gt;   [ '--port', '-p', GetoptLong::REQUIRED_ARGUMENT ],&lt;br /&gt;   [ '--target', '-t', GetoptLong::REQUIRED_ARGUMENT ]&lt;br /&gt; )&lt;br /&gt;&lt;br /&gt; ip = '127.0.0.1'&lt;br /&gt; port = '12345'&lt;br /&gt; target = '127.0.0.1:23456'&lt;br /&gt;&lt;br /&gt; opts.each do&lt;br /&gt;  |opt, arg|&lt;br /&gt;  case opt&lt;br /&gt;  when '--help'&lt;br /&gt;   RDoc::usage&lt;br /&gt;   exit&lt;br /&gt;  when '--ip'&lt;br /&gt;   ip = arg&lt;br /&gt;  when '--port'&lt;br /&gt;   port = arg&lt;br /&gt;  when '--target'&lt;br /&gt;   target = arg&lt;br /&gt;  end&lt;br /&gt; end&lt;br /&gt;&lt;br /&gt; port = port.to_i&lt;br /&gt; target = target.split(":")&lt;br /&gt;&lt;br /&gt; trap("SIGINT") do&lt;br /&gt;   exit&lt;br /&gt; end&lt;br /&gt;&lt;br /&gt; Bouncer.new(ip, port =&gt; [target[0], target[1].to_i]).run&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-9207448683611791767?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/9207448683611791767/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=9207448683611791767' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/9207448683611791767'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/9207448683611791767'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2009/06/bouncer-version-2.html' title='Bouncer versión 2'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-2509103272495931049</id><published>2009-06-18T16:40:00.003-03:00</published><updated>2009-07-07T18:56:54.254-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vmware'/><title type='text'>Mousewheel para arriba en vmware</title><content type='html'>Encontré como hacer para que ande bien la ruedita del mouse adentro de un Guest de VMWare con Kubuntu 9.04. Hay que instalar el paquete &lt;code&gt;xserver-xorg-input-vmmouse&lt;/code&gt;.&lt;br /&gt;Happy hacking, &lt;br /&gt;Aureliano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-2509103272495931049?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/2509103272495931049/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=2509103272495931049' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/2509103272495931049'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/2509103272495931049'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2009/06/mousewheel-para-arriba-en-vmware.html' title='Mousewheel para arriba en vmware'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-2803392953123261308</id><published>2009-06-17T11:27:00.003-03:00</published><updated>2009-08-10T17:50:44.856-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='vmware'/><category scheme='http://www.blogger.com/atom/ns#' term='xorg'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><category scheme='http://www.blogger.com/atom/ns#' term='visio'/><title type='text'>Cambiando de resolución en X</title><content type='html'>El comando &lt;code&gt;xrandr&lt;/code&gt; sirve, entre otras cosas para cambiar la resolución de X desde un shell. Primero listo las resoluciones disponibles:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ xrandr&lt;br /&gt;Screen 0: minimum 320 x 200, current 1280 x 1024, maximum 1280 x 1280&lt;br /&gt;VGA connected 1280x1024+0+0 (normal left inverted right x axis y axis) 338mm x 270mm&lt;br /&gt;   1280x1024      60.0*+   75.0     60.0*&lt;br /&gt;   1152x864       75.0&lt;br /&gt;   1024x768       75.0     60.0&lt;br /&gt;   800x600        75.0     60.3&lt;br /&gt;   640x480        75.0     59.9&lt;br /&gt;   720x400        70.1&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;y puedo elegir la que quiera con el parámetro &lt;code&gt;-s&lt;/code&gt;. Por ejemplo:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ xrandr -s 800x600&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Happy hacking, &lt;br /&gt;Aureliano&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-2803392953123261308?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/2803392953123261308/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=2803392953123261308' title='2 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/2803392953123261308'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/2803392953123261308'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2009/06/cambiando-de-resolucion-en-x.html' title='Cambiando de resolución en X'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-4301954417416078176</id><published>2009-06-13T02:13:00.004-03:00</published><updated>2009-07-07T18:58:32.125-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='rapidito'/><category scheme='http://www.blogger.com/atom/ns#' term='regexp'/><title type='text'>Pequeñas delicias de las expresiones regulares</title><content type='html'>Como les conté &lt;a href="http://aurelianito.blogspot.com/2009/06/tokenizer-de-rapidito.html"&gt;acá&lt;/a&gt; y &lt;a href="http://aurelianito.blogspot.com/2009/06/tokenizer-de-rapidito-segunda-version.html"&gt;acá&lt;/a&gt;, estoy escribiendo un tokenizador para un wiki que estoy programando. Y hoy me encontré con una cosa muy extraña de las expresiones regulares.&lt;br /&gt;En ruby la función &lt;code&gt;match&lt;/code&gt; sirve para buscar el primer match de una regex dentro de un string. Por ejemplo (usando el irb):&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;irb(main):001:0&gt; m = /a/.match "babab"&lt;br /&gt;=&gt; #&amp;lt;MatchData "a"&gt;&lt;br /&gt;irb(main):002:0&gt; m.pre_match&lt;br /&gt;=&gt; "b"&lt;br /&gt;irb(main):003:0&gt; m[0]&lt;br /&gt;=&gt; "a"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;En particular, el &lt;code&gt;pre_match&lt;/code&gt; es lo que está antes del match en el string. También según había entendido (mal) &lt;code&gt;/\Z/&lt;/code&gt; matchea con el final del string. Por ejemplo:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;irb(main):004:0&gt; m = /\Z/.match "hola"&lt;br /&gt;=&gt; #&amp;lt;MatchData ""&gt;&lt;br /&gt;irb(main):005:0&gt; m.pre_match&lt;br /&gt;=&gt; "hola"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Pero, &lt;code&gt;/\Z/&lt;/code&gt; tiene un comportamiento muy extraño, aunque &lt;a href="http://www.regular-expressions.info/reference.html"&gt;documentado&lt;/a&gt;, cuando el último caracter antes del final es un &lt;code&gt;\n&lt;/code&gt;. Lo que pasa es que el &lt;code&gt;pre_match&lt;/code&gt; queda ¡sin el &lt;code&gt;\n&lt;/code&gt; del final!. Lo muestro en el irb:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;irb(main):006:0&gt; m = /\Z/.match "\n"&lt;br /&gt;=&gt; #&amp;lt;MatchData ""&gt;&lt;br /&gt;irb(main):007:0&gt; m.pre_match&lt;br /&gt;=&gt; ""&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Para que no se manduque el &lt;code&gt;\n&lt;/code&gt;, hay que usar &lt;code&gt;/\z/&lt;/code&gt; (¡en minúscula!):&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;irb(main):008:0&gt; m = /\z/.match "\n"&lt;br /&gt;=&gt; #&amp;lt;MatchData ""&gt;&lt;br /&gt;irb(main):009:0&gt; m.pre_match&lt;br /&gt;=&gt; "\n"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Por lo tanto tuve que tocar el tokenizer, ahora la función de initialize quedó así (miren el cambio de la "Z" a "z"):&lt;br /&gt;&lt;pre class="ruby"&gt;    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;initialize&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt; &lt;span class="ident"&gt;delimiters&lt;/span&gt; &lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;      &lt;span class="attribute"&gt;@delimiter_list&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;[[/&lt;/span&gt;&lt;span class="regex"&gt;&lt;span class="escape"&gt;\z&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;/,&lt;/span&gt; &lt;span class="symbol"&gt;:finish&lt;/span&gt;&lt;span class="punct"&gt;]]&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt; &lt;br /&gt;        &lt;span class="ident"&gt;delimiters&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;to_a&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;map&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;k&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt;&lt;span class="ident"&gt;arr&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="ident"&gt;arr&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;map&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;re&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="ident"&gt;re&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;k&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt; &lt;span class="punct"&gt;}.&lt;/span&gt;&lt;span class="ident"&gt;inject&lt;/span&gt;&lt;span class="punct"&gt;([])&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;ac&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt;&lt;span class="ident"&gt;ps&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="ident"&gt;ac&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt; &lt;span class="ident"&gt;ps&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;&lt;br /&gt;      &lt;span class="attribute"&gt;@match_cache&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;nil&lt;/span&gt;&lt;br /&gt;    &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;Y el test que captura el problema que genera usar \Z en vez de \z quedó así:&lt;br /&gt;&lt;pre class="ruby"&gt;  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;test_carriage_return_ending&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;tok&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Tokenizer&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt; &lt;span class="symbol"&gt;:a_kind&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;[/&lt;/span&gt;&lt;span class="regex"&gt;!&lt;/span&gt;&lt;span class="punct"&gt;/]&lt;/span&gt; &lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;source&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;bang!&lt;span class="escape"&gt;\n&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;next_token&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;assert_equal&lt;/span&gt; &lt;span class="constant"&gt;true&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;has_next?&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;next_token&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;assert_equal&lt;/span&gt; &lt;span class="constant"&gt;true&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;has_next?&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;assert_equal&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&lt;span class="escape"&gt;\n&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;next_token&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;].&lt;/span&gt;&lt;span class="ident"&gt;to_s&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;assert_equal&lt;/span&gt; &lt;span class="constant"&gt;false&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;has_next?&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;Happy hacking,&lt;br /&gt;Aureliano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-4301954417416078176?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/4301954417416078176/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=4301954417416078176' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/4301954417416078176'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/4301954417416078176'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2009/06/pequenas-delicias-de-las-expresiones.html' title='Pequeñas delicias de las expresiones regulares'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-2952689373327986951</id><published>2009-06-12T00:35:00.004-03:00</published><updated>2009-07-07T18:59:01.938-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='rapidito'/><category scheme='http://www.blogger.com/atom/ns#' term='regexp'/><category scheme='http://www.blogger.com/atom/ns#' term='tokenizer'/><title type='text'>Tokenizer de rapidito, segunda versión</title><content type='html'>Como les &lt;a href="http://aurelianito.blogspot.com/2009/06/tokenizer-de-rapidito.html"&gt;conté hace un par de posts&lt;/a&gt;, estoy haciendo un wiki y blogueando sobre el tokenizer&lt;br /&gt;Hoy les cuento de la segunda versión del tokenizer. A esta versión (que no es compatible con la anterior) le agregué la posibilidad de asociar un tipo (kind) a cada regexp que define un token. Por lo tanto, el método &lt;code&gt;next_match&lt;/code&gt; ahora devuelve un par [match, kind]. Los matches de texto común (no delimitadores) tienen kind &lt;code&gt;:text&lt;/code&gt;. Los matches de los delimitadores vienen con la &lt;code&gt;MatchData&lt;/code&gt; entera, para poder usarla si interesan partes del match a la hora de procesar el token. También dejé de usar &lt;code&gt;=~&lt;/code&gt; para matchear regexps, ya que el&lt;br /&gt;Me quedaron un par de cosas con dudas después de implementar esto.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;¿Se puede hacer en ruby que busque un match de una regexp en un string a partir de una posición? Hacer una regexp del tipo &lt;code&gt;/.{34,}(regex de verdad)/&lt;/code&gt; no vale.&lt;/li&gt;&lt;li&gt;¿Puedo forzar a la unión de expresiones regulares a buscar el match más largo (en vez del primero que matchee)?&lt;/li&gt;&lt;/ol&gt;A pesar de las dudas, igual tengo una versión que creo que es significativamente mejor que la versión anterior. &lt;br /&gt;Así que como la otra vez dejo el código:&lt;br /&gt;&lt;pre class="ruby"&gt;&lt;span class="keyword"&gt;module &lt;/span&gt;&lt;span class="module"&gt;Rapidito&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;Tokenizer&lt;/span&gt;&lt;br /&gt;  &lt;br /&gt;    &lt;span class="ident"&gt;attr_reader&lt;/span&gt; &lt;span class="symbol"&gt;:source&lt;/span&gt;&lt;br /&gt;  &lt;br /&gt;    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;initialize&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt; &lt;span class="ident"&gt;delimiters&lt;/span&gt; &lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;      &lt;span class="attribute"&gt;@delimiter_list&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;[[/&lt;/span&gt;&lt;span class="regex"&gt;&lt;span class="escape"&gt;\Z&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;/,&lt;/span&gt; &lt;span class="symbol"&gt;:finish&lt;/span&gt;&lt;span class="punct"&gt;]]&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt; &lt;br /&gt;        &lt;span class="ident"&gt;delimiters&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;to_a&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;map&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;k&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt;&lt;span class="ident"&gt;arr&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="ident"&gt;arr&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;map&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;re&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="ident"&gt;re&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;k&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt; &lt;span class="punct"&gt;}.&lt;/span&gt;&lt;span class="ident"&gt;inject&lt;/span&gt;&lt;span class="punct"&gt;([])&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;ac&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt;&lt;span class="ident"&gt;ps&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="ident"&gt;ac&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt; &lt;span class="ident"&gt;ps&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;&lt;br /&gt;      &lt;span class="attribute"&gt;@match_cache&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;nil&lt;/span&gt;&lt;br /&gt;    &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;source=&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;s&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;      &lt;span class="attribute"&gt;@match_cache&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;nil&lt;/span&gt;&lt;br /&gt;      &lt;span class="attribute"&gt;@source&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;s&lt;/span&gt;&lt;br /&gt;    &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;has_next?&lt;/span&gt;&lt;br /&gt;      &lt;span class="punct"&gt;!&lt;/span&gt;&lt;span class="attribute"&gt;@source&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;empty?&lt;/span&gt; &lt;span class="punct"&gt;||&lt;/span&gt; &lt;span class="ident"&gt;valid_cache?&lt;/span&gt;&lt;br /&gt;    &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;valid_cache?&lt;/span&gt;&lt;br /&gt;      &lt;span class="punct"&gt;(!&lt;/span&gt;&lt;span class="attribute"&gt;@match_cache&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;nil?&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="attribute"&gt;@match_cache&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;].&lt;/span&gt;&lt;span class="ident"&gt;to_s&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;length&lt;/span&gt; &lt;span class="punct"&gt;&amp;gt;&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;next_match&lt;/span&gt;&lt;br /&gt;      &lt;span class="attribute"&gt;@delimiter_list&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;map&lt;/span&gt; &lt;span class="punct"&gt;{|&lt;/span&gt;&lt;span class="ident"&gt;p&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="ident"&gt;p&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;].&lt;/span&gt;&lt;span class="ident"&gt;match&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="attribute"&gt;@source&lt;/span&gt;&lt;span class="punct"&gt;),&lt;/span&gt; &lt;span class="ident"&gt;p&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;]]}.&lt;/span&gt;&lt;span class="ident"&gt;reject&lt;/span&gt; &lt;span class="punct"&gt;{|&lt;/span&gt;&lt;span class="ident"&gt;p&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="ident"&gt;p&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;].&lt;/span&gt;&lt;span class="ident"&gt;nil?&lt;/span&gt;&lt;span class="punct"&gt;}.&lt;/span&gt;&lt;span class="ident"&gt;inject&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;&lt;br /&gt;        &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;better&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;&lt;br /&gt;        &lt;span class="ident"&gt;better_pos&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;better&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;].&lt;/span&gt;&lt;span class="ident"&gt;pre_match&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;length&lt;/span&gt;&lt;br /&gt;        &lt;span class="ident"&gt;new_pos&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;].&lt;/span&gt;&lt;span class="ident"&gt;pre_match&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;length&lt;/span&gt;&lt;br /&gt;        &lt;br /&gt;        &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;better_pos&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt; &lt;span class="ident"&gt;new_pos&lt;/span&gt;&lt;br /&gt;          &lt;span class="ident"&gt;better&lt;/span&gt;&lt;br /&gt;        &lt;span class="keyword"&gt;elsif&lt;/span&gt; &lt;span class="ident"&gt;new_pos&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt; &lt;span class="ident"&gt;better_pos&lt;/span&gt;&lt;br /&gt;          &lt;span class="ident"&gt;new&lt;/span&gt;&lt;br /&gt;        &lt;span class="keyword"&gt;elsif&lt;/span&gt; &lt;span class="ident"&gt;better&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;].&lt;/span&gt;&lt;span class="ident"&gt;to_s&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;length&lt;/span&gt; &lt;span class="punct"&gt;&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;].&lt;/span&gt;&lt;span class="ident"&gt;to_s&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;length&lt;/span&gt;&lt;br /&gt;          &lt;span class="ident"&gt;better&lt;/span&gt;&lt;br /&gt;        &lt;span class="keyword"&gt;else&lt;/span&gt;&lt;br /&gt;          &lt;span class="ident"&gt;new&lt;/span&gt;&lt;br /&gt;        &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;      &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;    &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;next_token&lt;/span&gt;&lt;br /&gt;      &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="attribute"&gt;@match_cache&lt;/span&gt; &lt;span class="comment"&gt;#cached delimiter&lt;/span&gt;&lt;br /&gt;        &lt;span class="ident"&gt;rv&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="attribute"&gt;@match_cache&lt;/span&gt;&lt;br /&gt;        &lt;span class="attribute"&gt;@match_cache&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;nil&lt;/span&gt;&lt;br /&gt;        &lt;span class="keyword"&gt;return&lt;/span&gt; &lt;span class="ident"&gt;rv&lt;/span&gt;&lt;br /&gt;      &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;      &lt;br /&gt;      &lt;span class="ident"&gt;match&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;next_match&lt;/span&gt;&lt;br /&gt;      &lt;span class="ident"&gt;p&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;match&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;].&lt;/span&gt;&lt;span class="ident"&gt;pre_match&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;length&lt;/span&gt;&lt;br /&gt;      &lt;span class="attribute"&gt;@source&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="attribute"&gt;@source&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="ident"&gt;p&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt; &lt;span class="ident"&gt;match&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;].&lt;/span&gt;&lt;span class="ident"&gt;to_s&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;length&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="attribute"&gt;@source&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;length&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt;&lt;br /&gt;      &lt;br /&gt;      &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;p&lt;/span&gt; &lt;span class="punct"&gt;==&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt; &lt;span class="comment"&gt;#delimiter&lt;/span&gt;&lt;br /&gt;        &lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="ident"&gt;match&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;].&lt;/span&gt;&lt;span class="ident"&gt;to_s&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;match&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;]]&lt;/span&gt;&lt;br /&gt;      &lt;span class="keyword"&gt;else&lt;/span&gt; &lt;span class="comment"&gt;#text&lt;/span&gt;&lt;br /&gt;        &lt;span class="attribute"&gt;@match_cache&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;match&lt;/span&gt;&lt;br /&gt;        &lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="ident"&gt;match&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;].&lt;/span&gt;&lt;span class="ident"&gt;pre_match&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:text&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt;&lt;br /&gt;      &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;    &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;all_tokens&lt;/span&gt;&lt;br /&gt;      &lt;span class="ident"&gt;tokens&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;[]&lt;/span&gt;&lt;br /&gt;      &lt;span class="keyword"&gt;while&lt;/span&gt; &lt;span class="ident"&gt;has_next?&lt;/span&gt;&lt;br /&gt;        &lt;span class="ident"&gt;tokens&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="ident"&gt;next_token&lt;/span&gt;&lt;br /&gt;      &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;      &lt;span class="ident"&gt;tokens&lt;/span&gt;&lt;br /&gt;    &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;Y los tests de unidad:&lt;br /&gt;&lt;pre class="ruby"&gt;&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;test/unit&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;&lt;br /&gt;&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;rapidito/tokenizer&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="ident"&gt;include&lt;/span&gt; &lt;span class="constant"&gt;Rapidito&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;TokenizerTest&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt; &lt;span class="constant"&gt;Test&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Unit&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;TestCase&lt;/span&gt;&lt;br /&gt;  &lt;br /&gt;  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;test_no_token&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;tok&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Tokenizer&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt; &lt;span class="punct"&gt;{}&lt;/span&gt; &lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;source&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;aaaa&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;assert_equal&lt;/span&gt; &lt;span class="constant"&gt;true&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;has_next?&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;assert_equal&lt;/span&gt; &lt;span class="punct"&gt;[&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;aaaa&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:text&lt;/span&gt;&lt;span class="punct"&gt;],&lt;/span&gt; &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;next_token&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;assert_equal&lt;/span&gt; &lt;span class="constant"&gt;false&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;has_next?&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;  &lt;br /&gt;  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;assert_all_tokens&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt; &lt;span class="ident"&gt;expected&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;tokenizer&lt;/span&gt; &lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;assert_equal&lt;/span&gt; &lt;span class="ident"&gt;expected&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;br /&gt;      &lt;span class="ident"&gt;tokenizer&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;all_tokens&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;map&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;token&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;kind&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="ident"&gt;token&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;to_s&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;kind&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;  &lt;br /&gt;  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;test_two_delimiters&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;tok&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Tokenizer&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt; &lt;br /&gt;      &lt;span class="symbol"&gt;:a_kind&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;[/&lt;/span&gt;&lt;span class="regex"&gt;&lt;span class="escape"&gt;\|&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;/,&lt;/span&gt; &lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="regex"&gt;;;&lt;/span&gt;&lt;span class="punct"&gt;/]&lt;/span&gt; &lt;br /&gt;    &lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;source&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;aa|bbb;;;;cccc&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;assert_all_tokens&lt;/span&gt; \&lt;br /&gt;      &lt;span class="punct"&gt;[&lt;/span&gt; &lt;span class="punct"&gt;[&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;aa&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:text&lt;/span&gt;&lt;span class="punct"&gt;],&lt;/span&gt; &lt;span class="punct"&gt;[&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;|&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:a_kind&lt;/span&gt;&lt;span class="punct"&gt;],&lt;/span&gt; &lt;span class="punct"&gt;[&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;bbb&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:text&lt;/span&gt;&lt;span class="punct"&gt;],&lt;/span&gt; &lt;br /&gt;        &lt;span class="punct"&gt;[&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;;;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:a_kind&lt;/span&gt;&lt;span class="punct"&gt;],&lt;/span&gt; &lt;span class="punct"&gt;[&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;;;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:a_kind&lt;/span&gt;&lt;span class="punct"&gt;],&lt;/span&gt; &lt;span class="punct"&gt;[&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;cccc&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:text&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt; &lt;span class="punct"&gt;],&lt;/span&gt; &lt;br /&gt;      &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;source&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;aa;;bbb||cccc&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;assert_all_tokens&lt;/span&gt; \&lt;br /&gt;      &lt;span class="punct"&gt;[&lt;/span&gt; &lt;span class="punct"&gt;[&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;aa&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:text&lt;/span&gt;&lt;span class="punct"&gt;],&lt;/span&gt; &lt;span class="punct"&gt;[&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;;;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:a_kind&lt;/span&gt;&lt;span class="punct"&gt;],&lt;/span&gt; &lt;span class="punct"&gt;[&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;bbb&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:text&lt;/span&gt;&lt;span class="punct"&gt;],&lt;/span&gt; &lt;br /&gt;        &lt;span class="punct"&gt;[&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;|&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:a_kind&lt;/span&gt;&lt;span class="punct"&gt;],&lt;/span&gt; &lt;span class="punct"&gt;[&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;|&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:a_kind&lt;/span&gt;&lt;span class="punct"&gt;],&lt;/span&gt; &lt;span class="punct"&gt;[&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;cccc&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:text&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt; &lt;span class="punct"&gt;],&lt;/span&gt; &lt;br /&gt;      &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;  &lt;br /&gt;  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;test_choose_longest_match&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;tok&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Tokenizer&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt; &lt;br /&gt;      &lt;span class="symbol"&gt;:a_kind&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;[/&lt;/span&gt;&lt;span class="regex"&gt;aa&lt;/span&gt;&lt;span class="punct"&gt;/,&lt;/span&gt; &lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="regex"&gt;aaa&lt;/span&gt;&lt;span class="punct"&gt;/]&lt;/span&gt; &lt;br /&gt;    &lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;source&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;aaaa&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;assert_equal&lt;/span&gt; &lt;span class="punct"&gt;[&lt;/span&gt; &lt;span class="punct"&gt;[&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;aaa&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:a_kind&lt;/span&gt;&lt;span class="punct"&gt;],&lt;/span&gt; &lt;span class="punct"&gt;[&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;a&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:text&lt;/span&gt; &lt;span class="punct"&gt;]&lt;/span&gt; &lt;span class="punct"&gt;],&lt;/span&gt; &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;all_tokens&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;  &lt;br /&gt;  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;test_reset_precache&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;tok&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Tokenizer&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt; &lt;br /&gt;      &lt;span class="symbol"&gt;:a_kind&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;[/&lt;/span&gt;&lt;span class="regex"&gt;&lt;span class="escape"&gt;\|&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;/,&lt;/span&gt; &lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="regex"&gt;,&lt;/span&gt;&lt;span class="punct"&gt;/]&lt;/span&gt;&lt;br /&gt;    &lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;source&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;original start|original end&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;next_token&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;source&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;new start,new end&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;assert_equal&lt;/span&gt; &lt;span class="punct"&gt;[&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;new start&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:text&lt;/span&gt;&lt;span class="punct"&gt;],&lt;/span&gt; &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;next_token&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;  &lt;br /&gt;  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;test_almost_finished&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;tok&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Tokenizer&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt; &lt;span class="symbol"&gt;:a_kind&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;[/&lt;/span&gt;&lt;span class="regex"&gt;!&lt;/span&gt;&lt;span class="punct"&gt;/]&lt;/span&gt; &lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;source&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;bang!&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;next_token&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;assert_equal&lt;/span&gt; &lt;span class="constant"&gt;true&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;has_next?&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;next_token&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;assert_equal&lt;/span&gt; &lt;span class="constant"&gt;false&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;has_next?&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;Happy hacking,&lt;br /&gt;Aureliano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-2952689373327986951?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/2952689373327986951/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=2952689373327986951' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/2952689373327986951'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/2952689373327986951'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2009/06/tokenizer-de-rapidito-segunda-version.html' title='Tokenizer de rapidito, segunda versión'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-8510335889692075579</id><published>2009-06-11T00:58:00.005-03:00</published><updated>2009-07-07T19:00:58.187-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><title type='text'>Syntax highlighting de Ruby en mi blog</title><content type='html'>Tomando como base lo que dice &lt;a href="http://blog.michaelgreenly.com/2007/12/blog-post.html"&gt;en este post&lt;/a&gt;, hice un script en ruby que genera html con clases que se pueden poner coloritos con css:&lt;br /&gt;&lt;pre class="ruby"&gt;&lt;span class="comment"&gt;#!/usr/bin/env ruby&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;rubygems&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;&lt;br /&gt;&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;syntax/convertors/html&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;Syntax::Convertors::HTML&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;convert&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt; &lt;span class="ident"&gt;text&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;klass&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;html&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&amp;lt;pre class=&lt;span class="escape"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="expr"&gt;#{klass}&lt;/span&gt;&lt;span class="escape"&gt;\&amp;quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;regions&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;[]&lt;/span&gt;&lt;br /&gt;    &lt;span class="attribute"&gt;@tokenizer&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;tokenize&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt; &lt;span class="ident"&gt;text&lt;/span&gt; &lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;&lt;br /&gt;      &lt;span class="ident"&gt;value&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;html_escape&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;      &lt;span class="keyword"&gt;case&lt;/span&gt; &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;instruction&lt;/span&gt;&lt;br /&gt;        &lt;span class="keyword"&gt;when&lt;/span&gt; &lt;span class="symbol"&gt;:region_close&lt;/span&gt; &lt;span class="keyword"&gt;then&lt;/span&gt;&lt;br /&gt;          &lt;span class="ident"&gt;regions&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;pop&lt;/span&gt;&lt;br /&gt;          &lt;span class="ident"&gt;html&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;        &lt;span class="keyword"&gt;when&lt;/span&gt; &lt;span class="symbol"&gt;:region_open&lt;/span&gt; &lt;span class="keyword"&gt;then&lt;/span&gt;&lt;br /&gt;          &lt;span class="ident"&gt;regions&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;push&lt;/span&gt; &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;group&lt;/span&gt;&lt;br /&gt;          &lt;span class="ident"&gt;html&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&amp;lt;span class=&lt;span class="escape"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="expr"&gt;#{tok.group}&lt;/span&gt;&lt;span class="escape"&gt;\&amp;quot;&lt;/span&gt;&amp;gt;&lt;span class="expr"&gt;#{value}&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;        &lt;span class="keyword"&gt;else&lt;/span&gt;&lt;br /&gt;          &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;tok&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;group&lt;/span&gt; &lt;span class="punct"&gt;==&lt;/span&gt; &lt;span class="punct"&gt;(&lt;/span&gt; &lt;span class="ident"&gt;regions&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;last&lt;/span&gt; &lt;span class="punct"&gt;||&lt;/span&gt; &lt;span class="symbol"&gt;:normal&lt;/span&gt; &lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;            &lt;span class="ident"&gt;html&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="ident"&gt;value&lt;/span&gt;&lt;br /&gt;          &lt;span class="keyword"&gt;else&lt;/span&gt;&lt;br /&gt;            &lt;span class="ident"&gt;html&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&amp;lt;span class=&lt;span class="escape"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="expr"&gt;#{tok.group}&lt;/span&gt;&lt;span class="escape"&gt;\&amp;quot;&lt;/span&gt;&amp;gt;&lt;span class="expr"&gt;#{value}&lt;/span&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;          &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;      &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;    &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;html&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="keyword"&gt;while&lt;/span&gt; &lt;span class="ident"&gt;regions&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;pop&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;html&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&amp;lt;/pre&amp;gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;br /&gt;    &lt;span class="ident"&gt;html&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="ident"&gt;convertor&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Syntax&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Convertors&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;HTML&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;for_syntax&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;ruby&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="ident"&gt;convertor&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;convert&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt; &lt;span class="global"&gt;$stdin&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;read&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;ruby&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;  &lt;span class="punct"&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;En el script monkeypatchié un toque para que agregue la clase "ruby" al tag pre que engloba todo el código y aparte estoy usando estos estilos:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;style&gt;&lt;br /&gt;pre.ruby {&lt;br /&gt;      background-color: #ffffcc;&lt;br /&gt;      color: #000000;&lt;br /&gt;      padding: 10px;&lt;br /&gt;      font-size: 1.1em;&lt;br /&gt;      overflow: auto;&lt;br /&gt;      margin: 4px 0px;&lt;br /&gt;      width: 95%;&lt;br /&gt;      border: thin dashed;&lt;br /&gt;}&lt;br /&gt;.ruby .normal {}&lt;br /&gt;.ruby .comment { color: #005; font-style: italic; }&lt;br /&gt;.ruby .keyword { color: #A00; font-weight: bold; }&lt;br /&gt;.ruby .method { color: #077; }&lt;br /&gt;.ruby .class { color: #074; }&lt;br /&gt;.ruby .module { color: #050; }&lt;br /&gt;.ruby .punct { color: #447; font-weight: bold; }&lt;br /&gt;.ruby .symbol { color: #099; }&lt;br /&gt;.ruby .string { color: #944; }&lt;br /&gt;.ruby .char { color: #F07; }&lt;br /&gt;.ruby .ident { color: #004; }&lt;br /&gt;.ruby .constant { color: #07F; }&lt;br /&gt;.ruby .regex { color: #B66; }&lt;br /&gt;.ruby .number { color: #D55; }&lt;br /&gt;.ruby .attribute { color: #377; }&lt;br /&gt;.ruby .global { color: #3B7; }&lt;br /&gt;.ruby .expr { color: #227; }&lt;br /&gt;&amp;lt;/style&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Una cosa más, si estás viendo este post en otro lugar que no sea &lt;a href="http://aurelianito.blogspot.com"&gt;aurelianito.blogspot.com&lt;/a&gt; no vas a ver el resaltado de sintaxis (ya que no va a tener los estilos).&lt;br /&gt;&lt;br /&gt;Hasta la próxima,&lt;br /&gt;Aureliano&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-8510335889692075579?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/8510335889692075579/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=8510335889692075579' title='1 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/8510335889692075579'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/8510335889692075579'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2009/06/syntax-highlighting-de-ruby-en-mi-blog.html' title='Syntax highlighting de Ruby en mi blog'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-4057020437381149676</id><published>2009-06-06T22:33:00.006-03:00</published><updated>2009-07-07T19:02:24.495-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='rapidito'/><category scheme='http://www.blogger.com/atom/ns#' term='regexp'/><category scheme='http://www.blogger.com/atom/ns#' term='tokenizer'/><title type='text'>Tokenizer de rapidito</title><content type='html'>Después de mirar un rato el estado de las bibliotecas para hacer wikis en Ruby, y descubrir que ninguna me servía, Decidí que tenía que poner cartas en el asunto y hacer la mía. Mi idea es implementar el markup de Trac, haciéndolo extensible, y agregarle un par de cositas que por ahora son un secreto :-p.&lt;br /&gt;&lt;br /&gt;Lo importante del asunto es que puse manos en el asunto. Al final, después de un intento fallido de hackear mi camino al andar, decidí que lo mejor es armar un tokenizer y un parser que use esos tokens para generar el árbol del que extraeré el HTML.&lt;br /&gt;&lt;br /&gt;Así que me puse a programar. Como no encontré ningún tokenizer en ruby, programé uno. El tokenizer se contruye con un montón de expresiones regulares que definen cada delimitador. Después se le setea una fuente de caracteres (un string) y separa el string en los delimitadores de arriba (que se devuelven como símbolos) y cadenas que no matchean con ninguno de los delimitadores (que devuelve como strings).&lt;br /&gt;&lt;br /&gt;Bueno, basta de cháchara, acá tá el código:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;b&gt;module&lt;/b&gt; &lt;span style='color: #800000'&gt;Rapidito&lt;/span&gt;&lt;br /&gt;  &lt;b&gt;class&lt;/b&gt; &lt;span style='color: #800000'&gt;Tokenizer&lt;/span&gt;&lt;br /&gt;  &lt;br /&gt;    &lt;b&gt;def&lt;/b&gt; initialize( &lt;span style='color: #ff9fec'&gt;*&lt;/span&gt;delimiters )&lt;br /&gt;      &lt;span style='color: #008000'&gt;@regexp&lt;/span&gt; &lt;span style='color: #ff9fec'&gt;=&lt;/span&gt; &lt;span style='color: #800000'&gt;Regexp&lt;/span&gt;&lt;span style='color: #4000a7'&gt;.union&lt;/span&gt;( &lt;span style='color: #ff9fec'&gt;*&lt;/span&gt;delimiters  &lt;span style='color: #ff9fec'&gt;+&lt;/span&gt; &lt;span style='color: #ff9fec'&gt;[&lt;/span&gt;&lt;span style='color: #4a5704'&gt;/$/&lt;/span&gt;&lt;span style='color: #ff9fec'&gt;]&lt;/span&gt; )&lt;br /&gt;    &lt;b&gt;end&lt;/b&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span style='color: #008000'&gt;attr_accessor&lt;/span&gt; &lt;span style='color: #d40000'&gt;:source&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;b&gt;def&lt;/b&gt; has_next?&lt;br /&gt;     &lt;span style='color: #ff9fec'&gt; !&lt;/span&gt; &lt;span style='color: #008000'&gt;@source&lt;/span&gt;&lt;span style='color: #4000a7'&gt;.empty?&lt;/span&gt;&lt;br /&gt;    &lt;b&gt;end&lt;/b&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;b&gt;def&lt;/b&gt; next_token&lt;br /&gt;      &lt;span style='color: #000080'&gt;p&lt;/span&gt; &lt;span style='color: #ff9fec'&gt;=&lt;/span&gt; (&lt;span style='color: #008000'&gt;@source&lt;/span&gt; &lt;span style='color: #ff9fec'&gt;=~&lt;/span&gt; &lt;span style='color: #008000'&gt;@regexp&lt;/span&gt;)&lt;br /&gt;      &lt;b&gt;if&lt;/b&gt; &lt;span style='color: #000080'&gt;p&lt;/span&gt; &lt;span style='color: #ff9fec'&gt;==&lt;/span&gt; &lt;span style='color: #0000ff'&gt;0&lt;/span&gt; &lt;span style='color: #808080'&gt;&lt;i&gt;#delimiter&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;        token &lt;span style='color: #ff9fec'&gt;=&lt;/span&gt; &lt;span style='color: #0000ff'&gt;nil&lt;/span&gt;&lt;br /&gt;        &lt;span style='color: #008000'&gt;@source&lt;/span&gt;&lt;span style='color: #4000a7'&gt;.sub!&lt;/span&gt;( &lt;span style='color: #008000'&gt;@regexp&lt;/span&gt; ) &lt;span style='color: #ff9fec'&gt;{&lt;/span&gt; &lt;span style='color: #ff9fec'&gt;|&lt;/span&gt;match&lt;span style='color: #ff9fec'&gt;|&lt;/span&gt; token&lt;span style='color: #ff9fec'&gt;=&lt;/span&gt;match&lt;span style='color: #4000a7'&gt;.to_sym&lt;/span&gt;; &lt;span style='color: #dd0000'&gt;""&lt;/span&gt; &lt;span style='color: #ff9fec'&gt;}&lt;/span&gt;&lt;br /&gt;        token&lt;br /&gt;      &lt;b&gt;else&lt;/b&gt; &lt;span style='color: #808080'&gt;&lt;i&gt;#text&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;        token &lt;span style='color: #ff9fec'&gt;=&lt;/span&gt; &lt;span style='color: #008000'&gt;@source&lt;/span&gt;&lt;span style='color: #ff9fec'&gt;[&lt;/span&gt;&lt;span style='color: #0000ff'&gt;0&lt;/span&gt;,&lt;span style='color: #000080'&gt;p&lt;/span&gt;&lt;span style='color: #ff9fec'&gt;]&lt;/span&gt;&lt;br /&gt;        &lt;span style='color: #008000'&gt;@source&lt;/span&gt; &lt;span style='color: #ff9fec'&gt;=&lt;/span&gt; &lt;span style='color: #008000'&gt;@source&lt;/span&gt;&lt;span style='color: #ff9fec'&gt;[&lt;/span&gt;&lt;span style='color: #000080'&gt;p&lt;/span&gt;,&lt;span style='color: #008000'&gt;@source&lt;/span&gt;&lt;span style='color: #4000a7'&gt;.length&lt;/span&gt;&lt;span style='color: #ff9fec'&gt;]&lt;/span&gt;&lt;br /&gt;        token&lt;br /&gt;      &lt;b&gt;end&lt;/b&gt;&lt;br /&gt;    &lt;b&gt;end&lt;/b&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;b&gt;def&lt;/b&gt; all_tokens&lt;br /&gt;      tokens &lt;span style='color: #ff9fec'&gt;=&lt;/span&gt; &lt;span style='color: #ff9fec'&gt;[]&lt;/span&gt;&lt;br /&gt;      &lt;b&gt;while&lt;/b&gt; has_next?&lt;br /&gt;        tokens &lt;span style='color: #ff9fec'&gt;&amp;lt;&amp;lt;&lt;/span&gt; next_token&lt;br /&gt;      &lt;b&gt;end&lt;/b&gt;&lt;br /&gt;      tokens&lt;br /&gt;    &lt;b&gt;end&lt;/b&gt;&lt;br /&gt;    &lt;br /&gt;  &lt;b&gt;end&lt;/b&gt;&lt;br /&gt;&lt;b&gt;end&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; &lt;br /&gt;Y, acá abajo la única documentación que hice hasta ahora, o sea los tests de unidad:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span style='color: #000080'&gt;require&lt;/span&gt; &lt;span style='color: #dd4a4a'&gt;'test/unit'&lt;/span&gt;&lt;br /&gt;&lt;span style='color: #000080'&gt;require&lt;/span&gt; &lt;span style='color: #dd4a4a'&gt;'rapidito/tokenizer'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;include&lt;/b&gt; &lt;span style='color: #800000'&gt;Rapidito&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;class&lt;/b&gt; &lt;span style='color: #800000'&gt;TokenizerTest&lt;/span&gt; &lt;span style='color: #ff9fec'&gt;&amp;lt;&lt;/span&gt; &lt;span style='color: #800000'&gt;Test&lt;/span&gt;&lt;span style='color: #ff9fec'&gt;::&lt;/span&gt;&lt;span style='color: #800000'&gt;Unit&lt;/span&gt;&lt;span style='color: #ff9fec'&gt;::&lt;/span&gt;&lt;span style='color: #800000'&gt;TestCase&lt;/span&gt;&lt;br /&gt;  &lt;br /&gt;  &lt;b&gt;def&lt;/b&gt; test_no_token&lt;br /&gt;    tok &lt;span style='color: #ff9fec'&gt;=&lt;/span&gt; &lt;span style='color: #800000'&gt;Tokenizer&lt;/span&gt;&lt;span style='color: #4000a7'&gt;.new&lt;/span&gt;&lt;br /&gt;    tok&lt;span style='color: #4000a7'&gt;.source&lt;/span&gt; &lt;span style='color: #ff9fec'&gt;=&lt;/span&gt; &lt;span style='color: #dd0000'&gt;"aaaa"&lt;/span&gt;&lt;br /&gt;    assert_equal &lt;span style='color: #0000ff'&gt;true&lt;/span&gt;, tok&lt;span style='color: #4000a7'&gt;.has_next?&lt;/span&gt;&lt;br /&gt;    assert_equal &lt;span style='color: #dd0000'&gt;"aaaa"&lt;/span&gt;, tok&lt;span style='color: #4000a7'&gt;.next_token&lt;/span&gt;&lt;br /&gt;    assert_equal &lt;span style='color: #0000ff'&gt;false&lt;/span&gt;, tok&lt;span style='color: #4000a7'&gt;.has_next?&lt;/span&gt;&lt;br /&gt;  &lt;b&gt;end&lt;/b&gt;&lt;br /&gt;  &lt;br /&gt;  &lt;b&gt;def&lt;/b&gt; test_two_delimiters&lt;br /&gt;    tok &lt;span style='color: #ff9fec'&gt;=&lt;/span&gt; &lt;span style='color: #800000'&gt;Tokenizer&lt;/span&gt;&lt;span style='color: #4000a7'&gt;.new&lt;/span&gt;( &lt;span style='color: #4a5704'&gt;/\|/&lt;/span&gt;, &lt;span style='color: #4a5704'&gt;/;;/&lt;/span&gt; )&lt;br /&gt;    tok&lt;span style='color: #4000a7'&gt;.source&lt;/span&gt; &lt;span style='color: #ff9fec'&gt;=&lt;/span&gt; &lt;span style='color: #dd0000'&gt;"aa|bbb;;;;cccc"&lt;/span&gt;&lt;br /&gt;    assert_equal &lt;span style='color: #ff9fec'&gt;[&lt;/span&gt; &lt;span style='color: #dd0000'&gt;"aa"&lt;/span&gt;, :&lt;span style='color: #dd0000'&gt;"|"&lt;/span&gt;, &lt;span style='color: #dd0000'&gt;"bbb"&lt;/span&gt;, :&lt;span style='color: #dd0000'&gt;";;"&lt;/span&gt;, :&lt;span style='color: #dd0000'&gt;";;"&lt;/span&gt;, &lt;span style='color: #dd0000'&gt;"cccc"&lt;/span&gt; &lt;span style='color: #ff9fec'&gt;]&lt;/span&gt;, tok&lt;span style='color: #4000a7'&gt;.all_tokens&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    tok&lt;span style='color: #4000a7'&gt;.source&lt;/span&gt; &lt;span style='color: #ff9fec'&gt;=&lt;/span&gt; &lt;span style='color: #dd0000'&gt;"aa;;bbb||cccc"&lt;/span&gt;&lt;br /&gt;    assert_equal &lt;span style='color: #ff9fec'&gt;[&lt;/span&gt; &lt;span style='color: #dd0000'&gt;"aa"&lt;/span&gt;, :&lt;span style='color: #dd0000'&gt;";;"&lt;/span&gt;, &lt;span style='color: #dd0000'&gt;"bbb"&lt;/span&gt;, :&lt;span style='color: #dd0000'&gt;"|"&lt;/span&gt;, :&lt;span style='color: #dd0000'&gt;"|"&lt;/span&gt;, &lt;span style='color: #dd0000'&gt;"cccc"&lt;/span&gt; &lt;span style='color: #ff9fec'&gt;]&lt;/span&gt;, tok&lt;span style='color: #4000a7'&gt;.all_tokens&lt;/span&gt;&lt;br /&gt;  &lt;b&gt;end&lt;/b&gt;&lt;br /&gt;  &lt;br /&gt;  &lt;b&gt;def&lt;/b&gt; test_choose_first_match&lt;br /&gt;    tok &lt;span style='color: #ff9fec'&gt;=&lt;/span&gt; &lt;span style='color: #800000'&gt;Tokenizer&lt;/span&gt;&lt;span style='color: #4000a7'&gt;.new&lt;/span&gt;( &lt;span style='color: #4a5704'&gt;/aa/&lt;/span&gt;, &lt;span style='color: #4a5704'&gt;/aaa/&lt;/span&gt; )&lt;br /&gt;    tok&lt;span style='color: #4000a7'&gt;.source&lt;/span&gt; &lt;span style='color: #ff9fec'&gt;=&lt;/span&gt; &lt;span style='color: #dd0000'&gt;"aaa"&lt;/span&gt;&lt;br /&gt;    assert_equal &lt;span style='color: #ff9fec'&gt;[&lt;/span&gt; &lt;span style='color: #d40000'&gt;:aa&lt;/span&gt;, &lt;span style='color: #dd0000'&gt;"a"&lt;/span&gt; &lt;span style='color: #ff9fec'&gt;]&lt;/span&gt;, tok&lt;span style='color: #4000a7'&gt;.all_tokens&lt;/span&gt;&lt;br /&gt;  &lt;b&gt;end&lt;/b&gt;&lt;br /&gt;  &lt;br /&gt;&lt;b&gt;end&lt;/b&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Happy hacking,&lt;br /&gt;Aureliano.&lt;br /&gt;&lt;br /&gt;PD: ¿Prefieren que ponga el código con syntax highlighting?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-4057020437381149676?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/4057020437381149676/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=4057020437381149676' title='2 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/4057020437381149676'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/4057020437381149676'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2009/06/tokenizer-de-rapidito.html' title='Tokenizer de rapidito'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-4487431972598473024</id><published>2009-06-01T00:18:00.003-03:00</published><updated>2009-07-07T19:02:39.504-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><title type='text'>Quine en ruby</title><content type='html'>En el &lt;a href="http://rubyquiz.strd6.com/"&gt;ruby quiz&lt;/a&gt; pusieron como problema de la semana &lt;a href="http://rubyquiz.strd6.com/quizzes/207"&gt;hacer un quine en ruby&lt;/a&gt;. Un quine es un programa que genera como salida el código fuente del mismo (ver &lt;a href="http://en.wikipedia.org/wiki/Quine_(computing)"&gt;wikipedia&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;Así que puse manos a la obra. Agarre el último quine en C de la página de wikipedia:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;main() { char *s="main() { char *s=%c%s%c; printf(s,34,s,34); }"; printf(s,34,s,34); }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Y lo traduje a ruby:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;s="s=%c%s%c;printf(s,34,s,34)";printf(s,34,s,34)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;En ruby no hace falta tener main, porque todo lo que agarra el intérprete lo ejecuta y tampoco hay que declarar variables, así que quedó de 48 caracteres.&lt;br /&gt;&lt;br /&gt;Y después hice uno que hace que tenga un ENTER al final, quedando más lindo cuando lo corrés de la consola:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;s="s=%c%s%c;printf(s,34,s,34,13,10)%c%c";printf(s,34,s,34,13,10)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Fueron 10 minutos divertidos.&lt;br /&gt;&lt;br /&gt;Happy hacking,&lt;br /&gt;Aureliano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-4487431972598473024?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/4487431972598473024/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=4487431972598473024' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/4487431972598473024'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/4487431972598473024'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2009/06/quine-en-ruby.html' title='Quine en ruby'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-2023225360660001396</id><published>2009-05-31T12:11:00.003-03:00</published><updated>2009-07-07T19:02:53.591-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><title type='text'>99 botellas de cerveza</title><content type='html'>Yo no soy un fan de Perl, pero a veces aparecen cosas increíbles. Por ejemplo, este es un programa válido en perl:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;    ''=~(        '(?{'        .('`'        |'%')        .('['        ^'-')&lt;br /&gt;    .('`'        |'!')        .('`'        |',')        .'"'.        '\\$'&lt;br /&gt;    .'=='        .('['        ^'+')        .('`'        |'/')        .('['&lt;br /&gt;    ^'+')        .'||'        .(';'        &amp;'=')        .(';'        &amp;'=')&lt;br /&gt;    .';-'        .'-'.        '\\$'        .'=;'        .('['        ^'(')&lt;br /&gt;    .('['        ^'.')        .('`'        |'"')        .('!'        ^'+')&lt;br /&gt;   .'_\\{'      .'(\\$'      .';=('.      '\\$=|'      ."\|".(      '`'^'.'&lt;br /&gt;  ).(('`')|    '/').').'    .'\\"'.+(    '{'^'[').    ('`'|'"')    .('`'|'/'&lt;br /&gt; ).('['^'/')  .('['^'/').  ('`'|',').(  '`'|('%')).  '\\".\\"'.(  '['^('(')).&lt;br /&gt; '\\"'.('['^  '#').'!!--'  .'\\$=.\\"'  .('{'^'[').  ('`'|'/').(  '`'|"\&amp;").(&lt;br /&gt; '{'^"\[").(  '`'|"\"").(  '`'|"\%").(  '`'|"\%").(  '['^(')')).  '\\").\\"'.&lt;br /&gt; ('{'^'[').(  '`'|"\/").(  '`'|"\.").(  '{'^"\[").(  '['^"\/").(  '`'|"\(").(&lt;br /&gt; '`'|"\%").(  '{'^"\[").(  '['^"\,").(  '`'|"\!").(  '`'|"\,").(  '`'|(',')).&lt;br /&gt; '\\"\\}'.+(  '['^"\+").(  '['^"\)").(  '`'|"\)").(  '`'|"\.").(  '['^('/')).&lt;br /&gt; '+_,\\",'.(  '{'^('[')).  ('\\$;!').(  '!'^"\+").(  '{'^"\/").(  '`'|"\!").(&lt;br /&gt; '`'|"\+").(  '`'|"\%").(  '{'^"\[").(  '`'|"\/").(  '`'|"\.").(  '`'|"\%").(&lt;br /&gt; '{'^"\[").(  '`'|"\$").(  '`'|"\/").(  '['^"\,").(  '`'|('.')).  ','.(('{')^&lt;br /&gt; '[').("\["^  '+').("\`"|  '!').("\["^  '(').("\["^  '(').("\{"^  '[').("\`"|&lt;br /&gt; ')').("\["^  '/').("\{"^  '[').("\`"|  '!').("\["^  ')').("\`"|  '/').("\["^&lt;br /&gt; '.').("\`"|  '.').("\`"|  '$')."\,".(  '!'^('+')).  '\\",_,\\"'  .'!'.("\!"^&lt;br /&gt; '+').("\!"^  '+').'\\"'.  ('['^',').(  '`'|"\(").(  '`'|"\)").(  '`'|"\,").(&lt;br /&gt; '`'|('%')).  '++\\$="})'  );$:=('.')^  '~';$~='@'|  '(';$^=')'^  '[';$/='`';&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Y genera la letra de la canción &lt;a href="http://99-bottles-of-beer.net/lyrics.html"&gt;99 bottles of beer&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;Para ver la explicación sobre como hicieron esto, mirá &lt;a href="http://99-bottles-of-beer.net/language-perl-737.html"&gt;acá&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Happy hacking,&lt;br /&gt;Aureliano.&lt;br /&gt;&lt;br /&gt;PD: ¿Se podrá hacer algo así en ruby?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-2023225360660001396?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/2023225360660001396/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=2023225360660001396' title='1 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/2023225360660001396'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/2023225360660001396'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2009/05/99-botellas-de-cerveza.html' title='99 botellas de cerveza'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-7211870362671187616</id><published>2009-05-16T11:24:00.003-03:00</published><updated>2009-07-07T23:11:26.587-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='consorcio'/><title type='text'>Referencia de administradores de consorcio</title><content type='html'>En el consorcio donde vivo estamos cambiando de administración. Para ello se recibieron propuestas escritas de un montón de administradoras. Después de ser analizadas, elegimos 4 para entrevistar. De esas 4, si sale todo bien, deberíamos elegir a la brevedad cuál de ellas será nuestra próxima administración.&lt;br /&gt;Por lo tanto, quería pedirles que me cuenten si tienen referencias (tanto buenas como malas) de estas administraciones. Las mismas son:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Administración Becherini. TE: 4983-8206&lt;/li&gt;&lt;li&gt;Administración Farfán. Página web: &lt;a href="http://www.admfarfandelnido.com.ar"&gt;http://www.admfarfandelnido.com.ar&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Administración Fernandez. Página web: &lt;a href="http://www.admfernandez.com.ar"&gt;http://www.admfernandez.com.ar&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Administración Schmahl. TE: 4952-1323&lt;/li&gt;&lt;/ul&gt;Muchas gracias,&lt;br /&gt;Aureliano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-7211870362671187616?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/7211870362671187616/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=7211870362671187616' title='2 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/7211870362671187616'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/7211870362671187616'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2009/05/referencia-de-administradores-de.html' title='Referencia de administradores de consorcio'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-3695103671815347659</id><published>2009-05-14T09:56:00.005-03:00</published><updated>2009-07-07T23:11:36.573-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='humor'/><category scheme='http://www.blogger.com/atom/ns#' term='política'/><title type='text'>Pinky y Cerebro</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_vrWP6mUamXY/SgwVQHoAo7I/AAAAAAAAAGM/G8O9tI9btIs/s1600-h/pinky_cerebro.jpg"&gt;&lt;img style="cursor: pointer; width: 400px; height: 234px;" src="http://3.bp.blogspot.com/_vrWP6mUamXY/SgwVQHoAo7I/AAAAAAAAAGM/G8O9tI9btIs/s400/pinky_cerebro.jpg" alt="" id="BLOGGER_PHOTO_ID_5335663025196147634" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Gracias &lt;a href="http://www.flickr.com/photos/pedrov/"&gt;Pedro Varangot&lt;/a&gt; por la idea.&lt;br /&gt;&lt;br /&gt;Y para los que no conocen la versión original:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_vrWP6mUamXY/ShoKMyNCTHI/AAAAAAAAAGU/WWyufgJTLwg/s1600-h/pinky_and_the_brain.jpg"&gt;&lt;img style="cursor: pointer; width: 400px; height: 262px;" src="http://2.bp.blogspot.com/_vrWP6mUamXY/ShoKMyNCTHI/AAAAAAAAAGU/WWyufgJTLwg/s400/pinky_and_the_brain.jpg" alt="" id="BLOGGER_PHOTO_ID_5339591522952301682" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-3695103671815347659?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/3695103671815347659/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=3695103671815347659' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/3695103671815347659'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/3695103671815347659'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2009/05/pinky-y-cerebro.html' title='Pinky y Cerebro'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_vrWP6mUamXY/SgwVQHoAo7I/AAAAAAAAAGM/G8O9tI9btIs/s72-c/pinky_cerebro.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-3790006138224531151</id><published>2009-05-06T16:11:00.002-03:00</published><updated>2009-07-07T23:11:49.729-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='humor'/><title type='text'>YMCA</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_vrWP6mUamXY/SgHhHrwIn0I/AAAAAAAAAGE/f30tAlAXhCk/s1600-h/TheyAreGoingToHell.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 266px;" src="http://2.bp.blogspot.com/_vrWP6mUamXY/SgHhHrwIn0I/AAAAAAAAAGE/f30tAlAXhCk/s400/TheyAreGoingToHell.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5332790955903328066" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-3790006138224531151?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/3790006138224531151/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=3790006138224531151' title='1 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/3790006138224531151'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/3790006138224531151'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2009/05/ymca.html' title='YMCA'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_vrWP6mUamXY/SgHhHrwIn0I/AAAAAAAAAGE/f30tAlAXhCk/s72-c/TheyAreGoingToHell.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-8701867554361547727</id><published>2009-05-05T18:20:00.003-03:00</published><updated>2009-07-07T23:12:04.696-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='bouncer'/><title type='text'>Bouncer básico en ruby</title><content type='html'>Estuve programando un bouncer, usando como base el &lt;a href="http://aurelianito.blogspot.com/2008/05/load-balancer-minimalista-en-ruby-parte.html"&gt;load balancer que hice el año pasado&lt;/a&gt;. Un bouncer es un programa que poner un server TCP en un puerto y cada vez que recibe una conexión abre una conexión a otro lado y las "ata", haciendo que el server al que se conecta le conteste al cliente que se conecta a él. &lt;br /&gt;En mi caso lo programé para tener una salida controlada del entorno de máquinas virtuales que estoy armando para tener más ordenadas las cosas en el trabajo.&lt;br /&gt;Por si les interesa, acá abajo pongo el código completo.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#!/usr/bin/env ruby&lt;br /&gt;&lt;br /&gt;# == Synopsis&lt;br /&gt;#&lt;br /&gt;# redirect.rb: Redirects TCP connections to distant machines. Handles simultaneously many connections.&lt;br /&gt;#&lt;br /&gt;# == Usage&lt;br /&gt;#&lt;br /&gt;# ruby redirect.rb [OPTION]&lt;br /&gt;#&lt;br /&gt;# -h, --help:&lt;br /&gt;#   Show help&lt;br /&gt;#&lt;br /&gt;# --ip ip, -i ip:&lt;br /&gt;#   Accept connections from ip (default 127.0.0.1)&lt;br /&gt;#&lt;br /&gt;# --port port, -p port:&lt;br /&gt;#   Listen on port (default 12345)&lt;br /&gt;#&lt;br /&gt;# --target ip:port, -t ip:port&lt;br /&gt;#   Connect to ip:port (default 127.0.0.1:23456)&lt;br /&gt;#&lt;br /&gt;&lt;br /&gt;require 'getoptlong'&lt;br /&gt;require 'rdoc/usage'&lt;br /&gt;require 'socket'&lt;br /&gt;&lt;br /&gt;class Redirect&lt;br /&gt; def initialize( source_ip, listening_port, target_ip, target_port )&lt;br /&gt;  @source_ip = source_ip&lt;br /&gt;  @target_ip = target_ip&lt;br /&gt;  @target_port = target_port&lt;br /&gt;&lt;br /&gt;  @server_socket = TCPServer.new( "", listening_port )&lt;br /&gt;    @server_socket.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1 )&lt;br /&gt;    &lt;br /&gt;  @descriptors = [ @server_socket ]&lt;br /&gt;  @next_step = {}&lt;br /&gt; end&lt;br /&gt;&lt;br /&gt; def handle_new_connection&lt;br /&gt;  incoming = @server_socket.accept&lt;br /&gt;  if incoming.peeraddr[3] == @source_ip&lt;br /&gt;   begin&lt;br /&gt;    outgoing = TCPSocket.new( @target_ip, @target_port )&lt;br /&gt;    &lt;br /&gt;    @next_step[ incoming ] = outgoing&lt;br /&gt;    @next_step[ outgoing ] = incoming&lt;br /&gt;&lt;br /&gt;    @descriptors += [ incoming, outgoing ]&lt;br /&gt;   rescue&lt;br /&gt;    silent_close( incoming )&lt;br /&gt;   end&lt;br /&gt;  else&lt;br /&gt;   silent_close( incoming )&lt;br /&gt;  end&lt;br /&gt; end&lt;br /&gt;&lt;br /&gt; def silent_close( sock )&lt;br /&gt;  begin&lt;br /&gt;   sock.close&lt;br /&gt;  rescue&lt;br /&gt;   #do nothing intentionally&lt;br /&gt;  end&lt;br /&gt; end&lt;br /&gt;&lt;br /&gt;  def propagate(sock)&lt;br /&gt;    next_sock = @next_step[sock]&lt;br /&gt;    next_sock.write(sock.read_nonblock(1000 * 1000))&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt; def finish_connection(sock)&lt;br /&gt;  next_sock = @next_step[sock]&lt;br /&gt;  [ sock, next_sock ].each do&lt;br /&gt;   |s|&lt;br /&gt;   silent_close(s)&lt;br /&gt;   @descriptors.delete(s)&lt;br /&gt;   @next_step.delete(s)&lt;br /&gt;  end&lt;br /&gt; end&lt;br /&gt;&lt;br /&gt; def run&lt;br /&gt;  loop do&lt;br /&gt;   connections = select( @descriptors )&lt;br /&gt;   connections[0].each do&lt;br /&gt;    |sock|&lt;br /&gt;    if sock == @server_socket then&lt;br /&gt;     handle_new_connection&lt;br /&gt;    else&lt;br /&gt;     begin&lt;br /&gt;      sock.eof? ? finish_connection(sock) : propagate(sock)&lt;br /&gt;     rescue&lt;br /&gt;      finish_connection(sock)&lt;br /&gt;     end&lt;br /&gt;    end&lt;br /&gt;   end&lt;br /&gt;  end&lt;br /&gt; end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;if $0 == __FILE__ then&lt;br /&gt;&lt;br /&gt; opts = GetoptLong.new(&lt;br /&gt;   [ '--help', '-h', GetoptLong::NO_ARGUMENT ],&lt;br /&gt;   [ '--ip', '-i', GetoptLong::REQUIRED_ARGUMENT ],&lt;br /&gt;   [ '--port', '-p', GetoptLong::REQUIRED_ARGUMENT ],&lt;br /&gt;   [ '--target', '-t', GetoptLong::REQUIRED_ARGUMENT ]&lt;br /&gt; )&lt;br /&gt;&lt;br /&gt; ip = '127.0.0.1'&lt;br /&gt; port = '12345'&lt;br /&gt; target = '127.0.0.1:23456'&lt;br /&gt;&lt;br /&gt; opts.each do&lt;br /&gt;  |opt, arg|&lt;br /&gt;  case opt&lt;br /&gt;  when '--help'&lt;br /&gt;   RDoc::usage&lt;br /&gt;   exit&lt;br /&gt;  when '--ip'&lt;br /&gt;   ip = arg&lt;br /&gt;  when '--port'&lt;br /&gt;   port = arg&lt;br /&gt;  when '--target'&lt;br /&gt;   target = arg&lt;br /&gt;  end&lt;br /&gt; end&lt;br /&gt;&lt;br /&gt; port = port.to_i&lt;br /&gt; target = target.split(":")&lt;br /&gt;&lt;br /&gt; trap("SIGINT") do&lt;br /&gt;   exit&lt;br /&gt; end&lt;br /&gt;&lt;br /&gt; Redirect.new(ip, port, target[0], target[1].to_i).run&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-8701867554361547727?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/8701867554361547727/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=8701867554361547727' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/8701867554361547727'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/8701867554361547727'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2009/05/bouncer-basico-en-ruby.html' title='Bouncer básico en ruby'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-2138048135964484546</id><published>2009-04-21T12:16:00.004-03:00</published><updated>2009-07-07T23:12:17.320-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='erlang'/><category scheme='http://www.blogger.com/atom/ns#' term='charla'/><title type='text'>Charla de erlang</title><content type='html'>El viernes pasado di una charla sobre erlang en el trabajo. En la misma, muestro como escribir programas secuenciales en erlang y después un poco de programación distribuida. Para presentar usé &lt;a href="http://aurelianocalvo.googlepages.com/erlang.odp"&gt;esta presentación&lt;/a&gt; (ojo, tenés que abrirla con OpenOffice). Abajo pongo lo que planifiqué dar (que es muy parecido a lo que di).&lt;br /&gt;&lt;br /&gt;&lt;h2 id="Programaciónsecuencial"&gt;Programación secuencial&lt;/h2&gt; &lt;h3 id="Variablesinmutables"&gt;"Variables" inmutables&lt;/h3&gt; &lt;pre class="wiki"&gt;1&gt; X = 1.&lt;br /&gt;1&lt;br /&gt;2&gt; X = 2.&lt;br /&gt;** exception error: no match of right hand side value 2&lt;br /&gt;3&gt; X = 1.&lt;br /&gt;1&lt;br /&gt;&lt;/pre&gt;&lt;h3 id="Atomos"&gt;Atomos&lt;/h3&gt; &lt;pre class="wiki"&gt;4&gt; aaaa.&lt;br /&gt;aaaa&lt;br /&gt;5&gt; bbbb.&lt;br /&gt;bbbb&lt;br /&gt;6&gt; Y = bbbb.&lt;br /&gt;bbbb&lt;br /&gt;7&gt; Y.&lt;br /&gt;bbbb&lt;br /&gt;8&gt; Y = aaaa.&lt;br /&gt;** exception error: no match of right hand side value aaaa&lt;br /&gt;&lt;/pre&gt;&lt;h3 id="Tuplasylistasypatternmatching"&gt;Tuplas y listas (y pattern matching)&lt;/h3&gt; &lt;pre class="wiki"&gt;9&gt; L = [1, 2, 3]&lt;br /&gt;.&lt;br /&gt;[1,2,3]&lt;br /&gt;10&gt; L2 = [-1, 0 | L]&lt;br /&gt;.&lt;br /&gt;[-1,0,1,2,3]&lt;br /&gt;11&gt; [H1, H2, H3 | _ ] = L2&lt;br /&gt;.&lt;br /&gt;[-1,0,1,2,3]&lt;br /&gt;12&gt; H1.&lt;br /&gt;-1&lt;br /&gt;13&gt; H2.&lt;br /&gt;0&lt;br /&gt;14&gt; H3.&lt;br /&gt;1&lt;br /&gt;&lt;br /&gt;15&gt; Yo = {person, {fname, "Aureliano"}, {lname, "Calvo"}}.&lt;br /&gt;{person,{fname,"Aureliano"},{lname,"Calvo"}}&lt;br /&gt;16&gt; Yo.&lt;br /&gt;{person,{fname,"Aureliano"},{lname,"Calvo"}}&lt;br /&gt;17&gt; {person, {fname, Name},_} = Yo.&lt;br /&gt;{person,{fname,"Aureliano"},{lname,"Calvo"}}&lt;br /&gt;18&gt; Name.&lt;br /&gt;"Aureliano"&lt;br /&gt;&lt;/pre&gt;&lt;h3 id="Expresionescase"&gt;Expresiones case&lt;/h3&gt; &lt;pre class="wiki"&gt;34&gt; X = 1. EL = []. L = [1,2,3].&lt;br /&gt;1&lt;br /&gt;35&gt; []&lt;br /&gt;36&gt; [1,2,3]&lt;br /&gt;&lt;br /&gt;38&gt; case X of [] -&gt; empty_list; [H|T] -&gt; {head, H}; _ -&gt; not_a_list end.&lt;br /&gt;not_a_list&lt;br /&gt;39&gt; case EL of [] -&gt; empty_list; [H|T] -&gt; {head, H}; _ -&gt; not_a_list end.&lt;br /&gt;empty_list&lt;br /&gt;40&gt; case L of [] -&gt; empty_list; [H|T] -&gt; {head, H}; _ -&gt; not_a_list end.&lt;br /&gt;{head,1}&lt;br /&gt;&lt;/pre&gt;&lt;h3 id="Funciones"&gt;Funciones&lt;/h3&gt; &lt;p&gt; En &lt;a class="attachment" href="http://pastie.org/453466"&gt;fruit.erl&lt;/a&gt;, &lt;/p&gt; &lt;pre class="wiki"&gt;price( pear ) -&gt; 4.0;&lt;br /&gt;price( banana ) -&gt; 3.0;&lt;br /&gt;price( apple ) -&gt; 6.0;&lt;br /&gt;price( orange ) -&gt; 2.0;&lt;br /&gt;&lt;/pre&gt;&lt;p&gt; En consola, &lt;/p&gt; &lt;pre class="wiki"&gt;13&gt; fruit:price( pear ).&lt;br /&gt;4.0&lt;br /&gt;14&gt; fruit:price( banana ).&lt;br /&gt;3.0&lt;br /&gt;&lt;/pre&gt;&lt;p&gt; Usando pattern matching un toque más en serio: En &lt;a href="http://pastie.org/453466"&gt;fruit.erl&lt;/a&gt;, &lt;/p&gt; &lt;pre class="wiki"&gt;price( [] ) -&gt; 0.0;&lt;br /&gt;price( [{Kilos, Fruit}|Rest] ) -&gt; Kilos * price( Fruit ) + price( Rest ).&lt;br /&gt;&lt;/pre&gt;&lt;p&gt; En la consola, &lt;/p&gt; &lt;pre class="wiki"&gt;15&gt; fruit:price( [] ).&lt;br /&gt;0.0&lt;br /&gt;18&gt; fruit:price( [{2.5, banana}, {1.5, apple}] ).&lt;br /&gt;16.5&lt;br /&gt;&lt;/pre&gt;&lt;p&gt; Pero para que use mejor el espacio (y no se acabe el stack), lo escribo tail recursive (acá explico que el stack sino se va a la mierda): &lt;/p&gt; &lt;pre class="wiki"&gt;price2( L ) -&gt; price2( L, 0.0 ).&lt;br /&gt;&lt;br /&gt;price2( [], Acum ) -&gt; Acum;&lt;br /&gt;price2( [{Kilos, Fruit}|Rest], Acum ) -&gt; price2( Rest, Kilos * price( Fruit ) + Acum ).&lt;br /&gt;&lt;/pre&gt;&lt;h3 id="Programacióndistribuida"&gt;Programación distribuida&lt;/h3&gt; &lt;p&gt; spawn, send y receive &lt;/p&gt; &lt;p&gt; spawn lanza un proceso nuevo de erlang, send (!) manda un mensaje a un proceso, y receive lo recibe. &lt;/p&gt; &lt;p&gt; Hago el &lt;a class="attachment" href="http://pastie.org/453467"&gt;fruit_shop.erl&lt;/a&gt;. &lt;/p&gt; &lt;pre class="wiki"&gt;42&gt; c( fruit_shop).&lt;br /&gt;{ok,fruit_shop}&lt;br /&gt;43&gt; FS = fruit_shop:spawn_shop( [ {banana, 15.0}, {pear, 10.0}, {apple, 10.0}], [ {banana, 3.0}, {pear, 4.0}, {apple, 6.0} ] ).&lt;br /&gt;&lt;/pre&gt;&lt;p&gt; Y lo uso: &lt;/p&gt; &lt;pre class="wiki"&gt;(a@tango)3&gt; fruit_shop:stock(FS).&lt;br /&gt;[{banana,15.0},{pear,10.0},{apple,10.0}]&lt;br /&gt;(a@tango)8&gt; fruit_shop:buy(FS, [{2.0, apple}]).&lt;br /&gt;{purchased,12.0}&lt;br /&gt;(a@tango)10&gt; fruit_shop:stock(FS).&lt;br /&gt;[{apple,8.0},[{banana,15.0},{pear,10.0}]]&lt;br /&gt;&lt;/pre&gt;&lt;p&gt; Por último, lanzar procesos en otros nodos es casi lo mismo: (spawn con un parámetro más, todo el resto igual). &lt;/p&gt; &lt;p&gt; Pongo 2 consolas de erlang: &lt;/p&gt; &lt;pre class="wiki"&gt;&gt;erl -sname a -setcookie oreo&lt;br /&gt;&gt;erl -sname b -setcookie oreo&lt;br /&gt;&lt;/pre&gt;&lt;p&gt; En la primera lanzo la frutería sobre el segundo nodo: &lt;/p&gt; &lt;pre class="wiki"&gt;(a@tango)7&gt; FS = fruit_shop:spawn_shop( 'b@tango', [ {banana, 15.0}, {pear, 10.0&lt;br /&gt;}, {apple, 10.0}], [ {banana, 3.0}, {pear, 4.0}, {apple, 6.0} ] ).&lt;br /&gt;&lt;/pre&gt;&lt;p&gt; Hago lo mismo que antes: &lt;/p&gt; &lt;pre class="wiki"&gt;(a@tango)3&gt; fruit_shop:stock(FS).&lt;br /&gt;[{banana,15.0},{pear,10.0},{apple,10.0}]&lt;br /&gt;(a@tango)8&gt; fruit_shop:buy(FS, [{2.0, apple}]).&lt;br /&gt;{purchased,12.0}&lt;br /&gt;(a@tango)10&gt; fruit_shop:stock(FS).&lt;br /&gt;[{apple,8.0},[{banana,15.0},{pear,10.0}]]&lt;br /&gt;&lt;/pre&gt;&lt;p&gt; Mato la segunda consola y ahora las operaciones dan timeout: &lt;/p&gt; &lt;pre class="wiki"&gt;(a@tango)11&gt; fruit_shop:stock(FS).&lt;br /&gt;timeout&lt;br /&gt;(a@tango)12&gt; fruit_shop:buy(FS, [{2.0, apple}]).&lt;br /&gt;timeout&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-2138048135964484546?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/2138048135964484546/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=2138048135964484546' title='4 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/2138048135964484546'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/2138048135964484546'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2009/04/charla-de-erlang.html' title='Charla de erlang'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-5066857850652794016</id><published>2009-04-18T19:09:00.004-03:00</published><updated>2009-07-07T23:12:27.972-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='humor'/><title type='text'>Pintada</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_vrWP6mUamXY/Sis1AboXneI/AAAAAAAAAGc/jLhOLv2uoOQ/s1600-h/20070420083537-pintada2.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 320px;" src="http://2.bp.blogspot.com/_vrWP6mUamXY/Sis1AboXneI/AAAAAAAAAGc/jLhOLv2uoOQ/s400/20070420083537-pintada2.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5344423664338574818" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Vía &lt;a href="http://volandovengo.blogia.com/2007/042001-pintadas-2.php"&gt;volandovengo&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-5066857850652794016?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/5066857850652794016/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=5066857850652794016' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/5066857850652794016'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/5066857850652794016'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2009/04/pintada.html' title='Pintada'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_vrWP6mUamXY/Sis1AboXneI/AAAAAAAAAGc/jLhOLv2uoOQ/s72-c/20070420083537-pintada2.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-5794534792965137757</id><published>2009-04-10T18:24:00.003-03:00</published><updated>2009-07-07T23:13:12.877-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><title type='text'>como sacar numeros del 0 al 9 con los digitos 4 4 4 4 (parte 3)</title><content type='html'>Sigo jugando con los 4s y ahora quería contarles una curiosidad. Si saco la potenciación de las operaciones posibles, se pueden armar los mismos números que antes:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;0 == (4 / (4 * (4 * 4)))&lt;br /&gt;1 == (4 / (4 / (4 / 4)))&lt;br /&gt;2 == (4 / ((4 + 4) / 4))&lt;br /&gt;3 == ((4 + (4 + 4)) / 4)&lt;br /&gt;4 == (4 - (4 / (4 * 4)))&lt;br /&gt;5 == ((4 + (4 * 4)) / 4)&lt;br /&gt;6 == (4 + ((4 + 4) / 4))&lt;br /&gt;7 == (4 + (4 - (4 / 4)))&lt;br /&gt;8 == (4 - (4 - (4 + 4)))&lt;br /&gt;9 == (4 + (4 + (4 / 4)))&lt;br /&gt;10 ==&lt;br /&gt;11 ==&lt;br /&gt;12 == (4 * (4 - (4 / 4)))&lt;br /&gt;13 ==&lt;br /&gt;14 ==&lt;br /&gt;15 == ((4 * 4) - (4 / 4))&lt;br /&gt;16 == (4 * (4 / (4 / 4)))&lt;br /&gt;17 == ((4 / 4) + (4 * 4))&lt;br /&gt;18 ==&lt;br /&gt;19 ==&lt;br /&gt;20 == (4 * (4 + (4 / 4)))&lt;br /&gt;21 ==&lt;br /&gt;22 ==&lt;br /&gt;23 ==&lt;br /&gt;24 == (4 + (4 + (4 * 4)))&lt;br /&gt;25 ==&lt;br /&gt;26 ==&lt;br /&gt;27 ==&lt;br /&gt;28 == ((4 * (4 + 4)) - 4)&lt;br /&gt;29 ==&lt;br /&gt;30 ==&lt;br /&gt;31 ==&lt;br /&gt;32 == ((4 * 4) + (4 * 4))&lt;br /&gt;33 ==&lt;br /&gt;34 ==&lt;br /&gt;35 ==&lt;br /&gt;36 == (4 + (4 * (4 + 4)))&lt;br /&gt;37 ==&lt;br /&gt;38 ==&lt;br /&gt;39 ==&lt;br /&gt;40 ==&lt;br /&gt;41 ==&lt;br /&gt;42 ==&lt;br /&gt;43 ==&lt;br /&gt;44 ==&lt;br /&gt;45 ==&lt;br /&gt;46 ==&lt;br /&gt;47 ==&lt;br /&gt;48 == (4 * (4 + (4 + 4)))&lt;br /&gt;49 ==&lt;br /&gt;50 ==&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;¿Loco no? Para probarlo, saquen ** de la lista de posibles operadores y corran el script de &lt;a href="http://aurelianito.blogspot.com/2009/04/en-la-entrada-anterior-del-blog-puse-el.html"&gt;la entrada anterior del blog&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Happy hacking,&lt;br /&gt;Aureliano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-5794534792965137757?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/5794534792965137757/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=5794534792965137757' title='2 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/5794534792965137757'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/5794534792965137757'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2009/04/como-sacar-numeros-del-0-al-9-con-los_10.html' title='como sacar numeros del 0 al 9 con los digitos 4 4 4 4 (parte 3)'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-2298859832850403096</id><published>2009-04-10T18:11:00.004-03:00</published><updated>2009-07-07T23:13:28.803-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><title type='text'>como sacar numeros del 0 al 9 con los digitos 4 4 4 4 (parte 2)</title><content type='html'>&lt;a href="http://aurelianito.blogspot.com/2009/04/como-sacar-numeros-del-0-al-9-con-los.html"&gt;En la entrada anterior del blog&lt;/a&gt; puse el desafío de calcular los números del 1 al 50 haciendo operaciones aritméticas sobre 4 4s, y como generarlos para los números que van del 0 al 9. Pero me quedé con la duda de si es posible hacerlo para todos los números menores a 50, así que escribí un programita en ruby que calcula todas las posibles evaluaciones usando los operadores +, -, *, / y **. Lo único, hay que tener en cuenta que la división es entera, por lo que hay algunos resultados poco intuitivos.&lt;br /&gt;&lt;br /&gt;Al final, el primer número imposible es el 10 (por eso no encontraba como armarlo :D). Acá les muestro la salida del programa:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;0 == (4 / (4 ** (4 ** 4)))&lt;br /&gt;1 == (4 ** (4 / (4 ** 4)))&lt;br /&gt;2 == (4 / ((4 + 4) / 4))&lt;br /&gt;3 == (4 - (4 ** (4 - 4)))&lt;br /&gt;4 == (4 ** (4 ** (4 - 4)))&lt;br /&gt;5 == (4 + (4 ** (4 - 4)))&lt;br /&gt;6 == (4 + ((4 + 4) / 4))&lt;br /&gt;7 == (4 + (4 - (4 / 4)))&lt;br /&gt;8 == (4 - (4 - (4 + 4)))&lt;br /&gt;9 == (4 + (4 + (4 / 4)))&lt;br /&gt;10 ==&lt;br /&gt;11 ==&lt;br /&gt;12 == (4 * (4 - (4 / 4)))&lt;br /&gt;13 ==&lt;br /&gt;14 ==&lt;br /&gt;15 == ((4 * 4) - (4 / 4))&lt;br /&gt;16 == (4 * (4 ** (4 / 4)))&lt;br /&gt;17 == ((4 / 4) + (4 * 4))&lt;br /&gt;18 ==&lt;br /&gt;19 ==&lt;br /&gt;20 == (4 * (4 + (4 / 4)))&lt;br /&gt;21 ==&lt;br /&gt;22 ==&lt;br /&gt;23 ==&lt;br /&gt;24 == (4 + (4 + (4 * 4)))&lt;br /&gt;25 ==&lt;br /&gt;26 ==&lt;br /&gt;27 ==&lt;br /&gt;28 == ((4 * (4 + 4)) - 4)&lt;br /&gt;29 ==&lt;br /&gt;30 ==&lt;br /&gt;31 ==&lt;br /&gt;32 == ((4 ** 4) / (4 + 4))&lt;br /&gt;33 ==&lt;br /&gt;34 ==&lt;br /&gt;35 ==&lt;br /&gt;36 == (4 + (4 * (4 + 4)))&lt;br /&gt;37 ==&lt;br /&gt;38 ==&lt;br /&gt;39 ==&lt;br /&gt;40 ==&lt;br /&gt;41 ==&lt;br /&gt;42 ==&lt;br /&gt;43 ==&lt;br /&gt;44 ==&lt;br /&gt;45 ==&lt;br /&gt;46 ==&lt;br /&gt;47 ==&lt;br /&gt;48 == (4 * (4 + (4 + 4)))&lt;br /&gt;49 ==&lt;br /&gt;50 ==&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Y para los geeks codeadores como yo, este fue el script rubyistico que usé para calcular las cosas:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;def template_expressions( leafs = 4 )&lt;br /&gt;  return "4" if leafs == 1&lt;br /&gt;  previous_level = template_expressions( leafs - 1 )&lt;br /&gt;  previous_level.map do&lt;br /&gt;    |expr|&lt;br /&gt;    results = []&lt;br /&gt;    (0...expr.length).each do&lt;br /&gt;      |i|&lt;br /&gt;      if expr[i..i] == "4"&lt;br /&gt;        new_result = expr.clone&lt;br /&gt;        new_result[i] = "(4 o 4)"&lt;br /&gt;        results &lt;&lt; new_result&lt;br /&gt;      end&lt;br /&gt;    end&lt;br /&gt;    results&lt;br /&gt;  end.flatten&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;OPERANDS = %W{+ - * / **}&lt;br /&gt;&lt;br /&gt;def sample_evaluations( leafs = 4 )&lt;br /&gt;  evaluations = {}&lt;br /&gt;  exprs = template_expressions(leafs)&lt;br /&gt;  exprs.each do&lt;br /&gt;    |expr|&lt;br /&gt;    sample_evaluations0( leafs, expr, evaluations )&lt;br /&gt;  end&lt;br /&gt;  evaluations&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;def sample_evaluations0( leafs, expr, evaluations )&lt;br /&gt;  if leafs == 0&lt;br /&gt;    begin&lt;br /&gt;      evaluations[eval( expr )] = expr&lt;br /&gt;    rescue ZeroDivisionError&lt;br /&gt;    end&lt;br /&gt;    return&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  OPERANDS.each do&lt;br /&gt;    |op|&lt;br /&gt;    new_expr = expr.sub( /o/, op)&lt;br /&gt;    sample_evaluations0( leafs - 1, new_expr, evaluations )&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;evaluations = sample_evaluations&lt;br /&gt;(0..50).each { |i| puts "#{i} == #{evaluations[i]}" }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Happy hacking,&lt;br /&gt;Aureliano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-2298859832850403096?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/2298859832850403096/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=2298859832850403096' title='1 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/2298859832850403096'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/2298859832850403096'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2009/04/en-la-entrada-anterior-del-blog-puse-el.html' title='como sacar numeros del 0 al 9 con los digitos 4 4 4 4 (parte 2)'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-4732989208771113720</id><published>2009-04-10T00:42:00.003-03:00</published><updated>2009-07-07T23:13:34.647-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><title type='text'>como sacar numeros del 0 al 9 con los digitos 4 4 4 4</title><content type='html'>Hoy estaba mirando la página del Google Analytics del blog y encontré una busqueda muy rara que entró por acá: "como sacar numeros del 1 al 50 con los digitos 4 4 4 4". Estuve pensando un poco que quería decir e inventé que tenía que hacer operaciones aritméticas comunes sobre los 4 4s y obtener los números del 1 al 50. &lt;br /&gt;Me salieron los números del 1 al 9 (y le agregué el cero de yapa). Los anoté en notación "ruby" para que puedan hacer cut&amp;paste en el &lt;a href="http://en.wikipedia.org/wiki/Interactive_Ruby_Shell"&gt;irb&lt;/a&gt;.&lt;br /&gt;0: 4+4-4-4&lt;br /&gt;1: (4+4)/(4+4)&lt;br /&gt;2: (4/4) + (4/4)&lt;br /&gt;3: (4+4+4)/4&lt;br /&gt;4: (4**(4-4))*4&lt;br /&gt;5: (4**(4-4))+4&lt;br /&gt;6: ((4+4) / 4) + 4&lt;br /&gt;7: (4+4) - (4/4)&lt;br /&gt;8: 4+4+4-4&lt;br /&gt;9: (4+4) + (4/4)&lt;br /&gt;&lt;br /&gt;Ahora me queda la duda de si se pueden, o no, armar todos los números del 1 al 50 de esta manera. Quizás debería escribir un programita que prueba todas las opciones.&lt;br /&gt;&lt;br /&gt;Happy hacking,&lt;br /&gt;Aureliano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-4732989208771113720?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/4732989208771113720/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=4732989208771113720' title='2 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/4732989208771113720'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/4732989208771113720'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2009/04/como-sacar-numeros-del-0-al-9-con-los.html' title='como sacar numeros del 0 al 9 con los digitos 4 4 4 4'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-7874249386646198717</id><published>2009-03-14T23:35:00.004-02:00</published><updated>2009-07-07T23:13:53.802-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='git'/><category scheme='http://www.blogger.com/atom/ns#' term='charla'/><title type='text'>Gitcasts</title><content type='html'>Hace un tiempo que estoy jugando con la idea de empezar a usar git como control de versiones. Pero como estoy acostumbrado a años de subversion, aunque entiendo que tiene ventajas, me cuesta mucho hacer el pase. Las cosas que me detienen son que tiene menos soporte en Windows, la integración con eclipse es peor y usamos subversion en el trabajo.&lt;br /&gt;Las cosas que me tientan son que está bueno poder tener versiones sin conectarse a un server, que es una cosa nueva para aprender, que parece estar bien hecho y que hay un montón de gente usándolo y le sirve. La idea de usar un control de versiones distribuido me gusta mucho.&lt;br /&gt;Así que me puse a usarlo en un proyectito que estoy haciendo para mi, y empecé a buscar como usarlo en internet. Y me encontré con unos &lt;a href="http://www.gitcasts.com/"&gt;screencasts que están re-buenos y quiero compartir con ustedes&lt;/a&gt;. Les recomiendo especialmente que vean el &lt;a href="http://www.gitcasts.com/posts/railsconf-git-talk"&gt;screencast de los slides de la rails-conf&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Me voy a dormir,&lt;br /&gt;Aureliano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-7874249386646198717?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/7874249386646198717/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=7874249386646198717' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/7874249386646198717'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/7874249386646198717'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2009/03/gitcasts.html' title='Gitcasts'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-1738077072634432227</id><published>2009-03-03T01:01:00.005-02:00</published><updated>2009-07-07T23:14:09.131-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nicolás'/><title type='text'>¡Soy papá!</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Update&lt;/span&gt;: pueden &lt;a href="http://pequenico.blogspot.com"&gt;ver las fotos de Nico en su blog&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;El sábado 28 de febrero (o sea, anteayer) a las 12:39 hs nació Nicolás, mi primogénito. Estoy muy contento y emocionado y quería compartir con ustedes la aventura del nacimiento.&lt;br /&gt;&lt;h4&gt;Contracciones&lt;/h4&gt;&lt;br /&gt;El viernes, cuando llegué del laburo, mi mujer me dijo que estaba con contracciones. Ya había tenido contracciones antes pero no muy seguido. Alrededor de las 9 y media empezamos a medir cuándo empezaban. Y se hacían cada vez más frecuentes. A partir de las 11 (o 12) se estabilizaron cada 10 minutos (aprox). Las contracciones se hacían cada vez más fuertes y a la una y media yo me adelanté y saqué el auto de la cochera, lo puse en la puerta del edificio y subí el bolso con las cosas que teníamos preparado para el parto. También me tomé un café re-cargado para estar despierto cuando hiciera falta llevarla al hospital (en mi cabeza, en una media hora).&lt;br /&gt;Pero me apuré al re-pedo. Las contracciones se estabilizaron en los 10' de frecuencia. Y con contracciones cada 10 minutos, la partera nos dijo que esperemos y que la llamemos cuando lleguen a ser cada 5'. Las contracciones siguieron cada 10' un par de horas más y yo encontré que las risas podían inducir partos. Así que primero estuve leyendole a Agus un montón de chistes malos que encontré x la web; y como no se reía, vimos ZooLander. Mientras tanto seguimos anotando las contracciones. Como había tomado un montón de café, no me podía dormir (aunque Agus me lo pidió). Alrededor de las 5AM (¿o 6?), se fue el efecto del café. Las contracciones seguían cada 10 minutos, pero un poco más dolorosas.&lt;br /&gt;Palmé y me dormí. Me despertó Agus a las 9. Me dijo que las contracciones al fin eran cada 5 minutos. Así que habló con la partera y quedamos encontrarnos en la Suizo.&lt;br /&gt;&lt;h4&gt;La Suizo&lt;/h4&gt;&lt;br /&gt;Llegamos antes de las 10 a la Suizo. Fuimos al tercer piso. Le dimos el carnet de OSDE de mi mujer a la recepcionista y nos encontramos con la partera. En ese momento, ella nos dijo que no había habitaciones y que nos ¡teníamos que ir!. También la revisó y vio que el cuello del útero estaba casi completamente borrado, y que tenía un poquitito de dilatación.&lt;br /&gt;Bajamos y pedí en el Valet Parking que me devuelvan el auto. Evidentemente Nico no nacería ahí.&lt;br /&gt;Después de esperar un rato largo (las calles de la zona están medio enquilombadas porque hicieron Pueyrredón doble mano) trajeron el autito y partimos a la clínica Otamendi, donde la partera hizo una reserva.&lt;br /&gt;&lt;h4&gt;Llegando a la Otamendi&lt;/h4&gt;&lt;br /&gt;Dejé a Agustina e Irma en la puerta de la clínica, y fui a estacionar. El estacionamiento de esta clínica salía ¡$55 x día! y había cola. Así que me fui a buscar otro. Encontré uno a 2 cuadras a $35 x día, que abre las 24hs y estacioné ahí. Fui a la clínica, a admisiones. Yo tenía el carnet de OSDE de Agus así que terminé el trámite y subí a la habitación que le habían asignado.&lt;br /&gt;&lt;h4&gt;Preparativos para el parto&lt;/h4&gt;&lt;br /&gt;Llegué a la habitación 509, que es la habitación que asignaron para que estuviera Agus hasta que liberen una de las de internación. Al toque la partera me dijo que fuera con ella a cambiarme para presenciar el parto.&lt;br /&gt;Acá empezó el primer inconveniente. Llegué a una especie de vestuario en el sexto piso del Otamendi donde se suponía que me tenían que dar la ropa que hace falta para entrar en un quirófano y darme un locker para guardar la mía. En el vestuario lo que encontré es un montón de ambos de cirujía tirados, lockers cerrados, y médicos rapiñando los 3 que quedaban. La partera vio lo mismo en su vestuario y volvimos.&lt;br /&gt;A Agus ya la habían preparado y estaba lista para ser mamá. Después de un ratito (que me pareció una eternidad), me trajeron la ropa para entrar a la sala de partos, me cambié, dejé las cosas en la habitación 509 (la enfermera me dijo que dejaban todo con llave) y fui con la partera al parto.&lt;br /&gt;&lt;h4&gt;El parto&lt;/h4&gt;&lt;br /&gt;Entré a la parte de cirujía, y ya estaba todo encaminado. La partera fue derecho a la sala de partos y a mi me dijeron que espere un rato. Mientras tanto me puse unas cosas para cubrir las zapatillas y otra para el pelo. Esperé un rato, y pedí si podía entrar. La enfermera que estaba en la puerta de la sala de parto me dijo que sí.&lt;br /&gt;Entré y estaba el obstetra de Agus metiéndole una barreta en la cachucha. Por lo que había leído, hacen eso para romper la bolsa así que no me asusté. Rompió la bolsa, empezaron las contracciones fuertes, Agus imploró x la peridural y, después de chequear que el bebé esté bien, decidieron dársela. Ahí me echaron de la sala.&lt;br /&gt;Esperé un rato más y volví a preguntar si podía entrar. De nuevo dijeron que sí. Cuando volví apoyaron la piernas de Agus levantadas a 90 grados. El parto, inminente. Aún con peridural a Agus le dolían muuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuucho las contracciones, así que aprovechando que ya tenía puesto un cateter en la espalda le dieron una segunda dosis. Después de eso hizo los pujos y salió Nicolás. A los 5 segundo de salir empezó a llorar. Cortaron el cordón umbilical y lo apoyaron un segundo sobre Agus.&lt;br /&gt;&lt;h4&gt;Chequeos varios&lt;/h4&gt;&lt;br /&gt;Tal como me dijeron en el curso de preparto, ahí mismo dejé a mi mujer para que haga el alumbramiento (o sea, que expulse la placenta) y me fui siguiendo a mi flamante hijo. En una sala aledaña lo pesaron, midieron, le pusieron las pulseritas identificatorias y lo limpiaron un poco. Cuando terminaron, me lo dieron para que lo alce. Y se lo llevé a Agus, que había terminado de expulsar la placenta. Pusieron el bebé encima de Agus un toque más, terminamos algo de papeleo (incluyendo que me dieron el certificado de nacimiento) y vinieron de Nursery a llevarse al bebé. Yo me fui con el bebé.&lt;br /&gt;&lt;h4&gt;El dilema&lt;/h4&gt;&lt;br /&gt;Todavía seguía en la 509. La hab. 509 es muy pequeña y era incómod estar ahí. Así que cuando la "nurse" me dijo si me llevaba al bebé directamente o dejaba que lo lleven un ratito a la nursery para acicalarlo, dudé un toque y después decidí que lo mejor era que se lo llevaran. Yo me fui a cambiar a la habitación (todavía tenía la ropa del quirófano).&lt;br /&gt;&lt;h4&gt;La tarde&lt;/h4&gt;&lt;br /&gt;Llegué a la habitación, me cambié y al toque apareció Agustina, que me cagó a pedos porque dejé que se lleven a Nicolás a la nursery. Le expliqué que dejé que fuera porque me pareció lo mejor, porque la habitación es chiquita, etc y, por suerte, al toque lo trajeron así que la discusión se desvaneció. Esperamos un ratito y me puse a preguntar cuando nos pasaban a una habitación decente, sin conseguir demasiadas respuestas.&lt;br /&gt;A las 2 de la tarde (más o menos), bajé a Admisiones para que me informen cuándo iba a tener el pase de habitación. No solo no había nadie, tampoco había nadie en la recepción y había gente haciendo cola hacía 45', para que los atiendan. Subí al quinto piso a acompañarla a Agus (Nico estaba frito) y al ratito volví a bajar.&lt;br /&gt;Cuando bajé de nuevo, atendían en recepción así que me quejé de que antes no había nadie y que tuve problemas con la ropa para entrar a la sala de parto. Dejé una nota por escrito en la hoja 188 del libro de quejas. Si pasan por el sanatorio pueden pedirlo para leerla. También hablé con la supervisora de hotelería un rato y me quejé de que la habitación era muy chica, de que no tiene baño, de que no puedo recibir gente (y es un nacimiento), de que no había gente en Admisiones ni en recepción, que no andaba el interno de la hab. 509, etc. O sea, le quemé la cabeza. La mina me prometió que iba a hacer todo lo que pudiera y que iba a tener la habitación ese mismo día, así que volví al quinto piso. Después de un rato, llamó la mina diciendome que ya tenían habitación para nosotros. La 321. La 321 es una habitación de más categoría de lo que cubre mi plan de OSDE, tiene recepción, es grande y me la bonifican. Parece que quejarme sirvió.&lt;br /&gt;Llegaron mi suegra y mi cuñada a la hab. chiquita, porque Agus quería que vinieran. Entró mi suegra a la hab y me quedé afuera hablando con mi cuñada. Después nos avisó la enfermera que nos asignaron la habitación y al ratito vienen a buscar a Nicolás para llevarlo. Me voy con los bolsos y él a la nueva habitación.&lt;br /&gt;La nueva habitación (tal como me dijeron) estaba re-buena. Grande, luminosa, cómoda. Dejo durmiendo a Nico y me pongo a ver tele. Llegan Agus y su parentela están un rato más y se van. La verdad que estabamos muertos. A las 8 le traen la cena a Agus, yo compro un sanguche (que estaba bárbaro) en el restaurant del hotel y me lo traen a la habitación. Cenamos, nos bañamos, y a las 9 palmé.&lt;br /&gt;&lt;h4&gt;Segundo día&lt;/h4&gt;&lt;br /&gt;Día de visitas. A la mañana vienen mis hermanos, mi tía y mis viejos. Se quedaron un rato (después aprenderíamos que demasiado). Al mediodía viene la puericultora y descubrimos que Nico no está tomando la teta bien. Después de debuggear el problema un rato, llega a la conclusión de que Nico no toma porque los pezones de Agus son muy chiquitos y no sabe succionar todavía. Para workarroundear el problema, compramos unas pezoneras, y Nico se prendió. Y la puericultora nos dijo que tengamos a ralla a las visitas para captar las señales "de teta" de Nico.&lt;br /&gt;A la tarde vinieron mi abuela con mi vieja y su primo Gregory, que me cuidaba de chico, y que es como un tío para mi, y que ahora vive en Israel. También vinieron mi cuñado y su hija y una tía de Agustina. A todos les dije que estén poco tiempo porque nos dijo la puericultora.&lt;br /&gt;A la noche la llamamos a mi suegra para coordinar la salida de la clínica. Ella nos ayudó a irnos de la clínica.&lt;br /&gt;&lt;h4&gt;Chau clínica&lt;/h4&gt;&lt;br /&gt;Nos levantamos a la mañana. Llevaron a Nico a hacer unos exámenes (donde le pincharon el talón, pobrecito), fui a hacer el trámite administrativo del alta (o sea, pagar), inicié el trámite del DNI de Nico y nos quedamos esperando a la neonatóloga. Alrededor del 1/2 día llegó mi suegra. A las 12:30hs (o sea, media hora después de la hora del alta) fui a averiguar xq no venía la neonatóloga. Después de como 1 hora de quilombo, exigí que le dieran el almuerzo a Agus; compré 2 sanguches para mi suegra y yo y llegó la neonatóloga, que adujo que no sabía que tenía que darnos el alta. Revisó a Nicolás, lo llevó a la nursery para hacerle el control oftalmológico, terminamos de comer, e hicimos el alta.&lt;br /&gt;&lt;h4&gt;La vuelta&lt;/h4&gt;&lt;br /&gt;Bajamos y fuimos a la puerta de la clínica. Yo agarré el bolso y me fui a buscar el auto. Arranqué el auto y lo llevé hasta la puerta de la clínica. Mientras venía, atrás a la derecha el auto hacía un ruido raro. Cuando andaba más rápido el ruido era más rápido.&lt;br /&gt;Llegué a la clínica, subí con dificultad el asiento de Nico al auto y lo encastré en la base y me di cuenta que la rueda trasera derecha estaba completamente desinflada. Saqué la sillita y Agus y la mamá se fueron en un taxi. Yo abrí el baúl, saqué el tapizado, saqué la rueda de auxilio, saqué el crique y la llave. Aflojé la rueda desinflada, subí el auto con el crique, cambié la rueda y fui solo para casa.&lt;br /&gt;Cuando llegué a casa a las 4 de la tarde, me la encontré a mi suegra cuidando a mi nene y a mi mujer durmiendo, palmada. Y yo al borde de un ataque de nervios. Mi suegra se fue porque tenía que ir a trabajar y me quedé cuidando a Nico que, por suerte, estaba dormido.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-1738077072634432227?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/1738077072634432227/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=1738077072634432227' title='6 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/1738077072634432227'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/1738077072634432227'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2009/03/soy-papa.html' title='¡Soy papá!'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-1037534654830201653</id><published>2009-02-27T15:00:00.004-02:00</published><updated>2009-07-07T19:03:29.162-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='erlang'/><category scheme='http://www.blogger.com/atom/ns#' term='rake'/><title type='text'>Rakefile multiplataforma para erlang</title><content type='html'>Los últimos días estuve programando un toque en &lt;a href="http://erlang.org/"&gt;Erlang&lt;/a&gt;. Como estoy tratando de armar un proyectito algo más en serio, necesito algo como un makefile. Y como los makefiles son un dolor de huevos, decidí que es mejor hacer un &lt;a href="http://rake.rubyforge.org/"&gt;rakefile&lt;/a&gt;.&lt;br /&gt;Para eso estuve googleando un poco y encontré &lt;a href="http://medevyoujane.com/blog/2008/8/21/erlang-make-rake-and-emake.html"&gt;este post&lt;/a&gt;. Que casi resolvía los quilombos, pero le falta poder andar en Windows. Así que lo toquetié un poco para hacerlo multiplataforma.&lt;br /&gt;Las cosas que tuve que hacer son:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Usar ruby en vez de llamar a pwd para obtener el path actual.&lt;/li&gt;&lt;li&gt;Generar nombres de archivos con back-slashes.&lt;/li&gt;&lt;li&gt;Hacer que maneje bien cosas con espacios.&lt;/li&gt;&lt;/ul&gt;Para obtener el PATH actual hice esto:&lt;br /&gt;&lt;pre&gt;PWD = Pathname(".").realpath&lt;/pre&gt;&lt;br /&gt;Para que el Pathname fuera con backslashes, después de &lt;a href="http://lista.rubyargentina.com.ar/pipermail/ruby-rubyargentina.com.ar/2009-February/004714.html"&gt;consultarlo con Luis Lavena&lt;/a&gt;, monkey-patchié Pathname para que el to_s mande "back-slashes":&lt;br /&gt;&lt;pre&gt;#Hack to generate paths with back-slashes&lt;br /&gt;class Pathname&lt;br /&gt; alias_method :old_to_s, :to_s&lt;br /&gt; def to_s&lt;br /&gt;   File::ALT_SEPARATOR ? old_to_s.gsub(File::SEPARATOR,File::ALT_SEPARATOR) : old_to_s&lt;br /&gt; end&lt;br /&gt;end&lt;/pre&gt;&lt;br /&gt;Por último, cambié un toque las llamadas a "sh" para que maneje paths con espacios. Para eso, en vez de pasarle un String le paso un Array por parámetro. Las llamadas quedaron algo así:&lt;br /&gt;&lt;pre&gt;sh *%W{erl -switch param1 #{param_calculado}}&lt;/pre&gt;&lt;br /&gt;Al final, el Rakefile quedó así:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#Based on the Rakefile shown in http://medevyoujane.com/blog/2008/8/21/erlang-make-rake-and-emake.html&lt;br /&gt;&lt;br /&gt;require 'rake'&lt;br /&gt;require 'rake/clean'&lt;br /&gt;require 'pathname'&lt;br /&gt;&lt;br /&gt;#Hack to generate paths with back-slashes&lt;br /&gt;class Pathname&lt;br /&gt;&lt;br /&gt;alias_method :old_to_s, :to_s&lt;br /&gt;&lt;br /&gt;def to_s&lt;br /&gt; File::ALT_SEPARATOR ? old_to_s.gsub(File::SEPARATOR,File::ALT_SEPARATOR) : old_to_s&lt;br /&gt;end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;# Configuration&lt;br /&gt;START_MODULE = "hellman"&lt;br /&gt;TEST_MODULE = "TEST MODULE NOT DEFINED"&lt;br /&gt;&lt;br /&gt;# No Need to change&lt;br /&gt;PWD = Pathname(".").realpath&lt;br /&gt;INCLUDE = "include"&lt;br /&gt;ERLC_FLAGS = "-I#{INCLUDE} +warn_unused_vars +warn_unused_import"&lt;br /&gt;&lt;br /&gt;SRC = FileList['src/**/*.erl']&lt;br /&gt;OBJ = SRC.pathmap("%{src,ebin}X.beam")&lt;br /&gt;CLEAN.include(['**/*.dump'])&lt;br /&gt;CLOBBER.include(['**/*.beam'])&lt;br /&gt;&lt;br /&gt;directory 'ebin'&lt;br /&gt;&lt;br /&gt;rule ".beam" =&gt;  ["%{ebin,src}X.erl"] do |t|&lt;br /&gt; sh *%W{erlc -pa ebin -W #{ERLC_FLAGS} -o ebin #{t.source}}&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;desc "Compile all"&lt;br /&gt;task :compile =&gt; ['ebin'] + OBJ&lt;br /&gt;&lt;br /&gt;desc "Open up a shell"&lt;br /&gt;task :shell =&gt; [:compile] do&lt;br /&gt;   sh *%W{erl -sname #{START_MODULE} -pa #{PWD + 'ebin'}}&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;desc "Open up a shell and run #{START_MODULE}:start()"&lt;br /&gt;task :run =&gt; [:compile] do&lt;br /&gt;   sh *%W{erl -sname #{START_MODULE} -pa #{PWD + 'ebin'} -run #{START_MODULE} start}&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;desc "Run Unit Tests"&lt;br /&gt;task :test do&lt;br /&gt; sh *%W{erl -noshell -s #{TEST_MODULE} test -s init stop}&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;task :default =&gt; :compile&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Happy jakin,&lt;br /&gt;Aureliano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-1037534654830201653?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/1037534654830201653/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=1037534654830201653' title='3 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/1037534654830201653'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/1037534654830201653'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2009/02/rakefile-multiplataforma-para-erlang.html' title='Rakefile multiplataforma para erlang'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-5481930185178732974</id><published>2008-12-25T16:12:00.004-02:00</published><updated>2009-07-07T23:14:55.341-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='humor'/><title type='text'>Traducciones hollywoodenses</title><content type='html'>Después de ir todos los mediodías a diversos restaurantes de Palermo Hollywood pude recabar información sobre el "argot" que usan para escribir las cartas. Estas son algunas de las cosas que pude entender hasta ahora:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;colchón de verdes: ¡uy!, no compramos tomates.&lt;/li&gt;&lt;li&gt;a las finas hierbas: en una de esas le ponemos perejil.&lt;/li&gt;&lt;li&gt;papas rústicas: íbamos a hacer papas fritas pero nos dio mucha vagancia pelar las papas.&lt;/li&gt;&lt;li&gt;pezca del día: es lo más barato que había en la pezcadería.&lt;/li&gt;&lt;li&gt;menú ejecutivo: al mediodía son todos unos ratas, así que hay que darles algo barato.&lt;/li&gt;&lt;li&gt;brusquetas: nos sobró pan duro de ayer.&lt;/li&gt;&lt;li&gt;cocina gourmet: vamos a darte re-poca comida, te vas a quedar con mucha hambre y te vamos a cobrar un fangote de guita. Eso sí, cuando te llevemos el plato vas a decir "¡qué lindo! parece un cuadro"&lt;/li&gt;&lt;li&gt;spring-roll: arrolladito primavera, pero todavía más chiquito&lt;/li&gt;&lt;li&gt;explosión de vegetales: Lo que me sobró de ayer le agregué un huevo y lo cociné, AKA: "revuelto de gramajo".&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Aureliano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-5481930185178732974?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/5481930185178732974/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=5481930185178732974' title='4 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/5481930185178732974'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/5481930185178732974'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2008/12/traducciones-hollywoodenses.html' title='Traducciones hollywoodenses'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-9161174911253808981</id><published>2008-12-09T23:52:00.004-02:00</published><updated>2009-07-07T23:15:15.619-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='c++'/><category scheme='http://www.blogger.com/atom/ns#' term='humor'/><title type='text'>C++ frequently questioned answers</title><content type='html'>La obra de Yossi Kreinin en su &lt;a href="http://yosefk.com/c++fqa/"&gt;C++ Frequently questioned answers&lt;/a&gt; es soberbia. Cientos y cientos de Kbytes dedicados exclusivamente a explicar porqué no usar C++ para empezar proyectos nuevos de desarrollo de software (cosa que comparto) y explicar las falencias de C++ detalladamente (y, la verdad, las falencias están bien justificadas).&lt;br /&gt;&lt;br /&gt;Con un estilo ácido, ágil y de fácil lectura, demuele carta a carta ese castillo de naipes que es C++. No puedo hacer más que recomendar la lectura de esta excelente página.&lt;br /&gt;&lt;br /&gt;Happy hacking (pero no en C++),&lt;br /&gt;Aureliano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-9161174911253808981?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/9161174911253808981/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=9161174911253808981' title='2 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/9161174911253808981'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/9161174911253808981'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2008/12/c-frequently-questioned-answers.html' title='C++ frequently questioned answers'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-4759121310883764714</id><published>2008-12-03T21:17:00.007-02:00</published><updated>2011-11-17T17:48:44.425-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ingenio'/><title type='text'>Números de Aure</title><content type='html'>&lt;span style="font-weight:bold;"&gt;Update: &lt;/span&gt; Los números de Aure también se llaman &lt;a href="http://www.research.att.com/~njas/sequences/A131689"&gt;A131689&lt;/a&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Update: &lt;/span&gt; Los números de Aure aparecen en el último libro de Paenza, &lt;a href="http://cms.dm.uba.ar/material/paenza/libro6"&gt;Cómo, esto también es matemática?&lt;/a&gt;. Mirá la página 224.&lt;br /&gt;&lt;br /&gt;La oficina de Agustina tiene en la puerta un teclado donde hay que ingresar una clave para poder entrar. Pensando en esto (y otras cosas donde hay que ingresar claves numéricas, como los cajeros automáticos) se me ocurrió el siguiente problema:&lt;br /&gt;&lt;blockquote&gt;Hay que elegir un número de 6 dígitos (en base 10, con posibles 0s&lt;br /&gt;adelante) como clave para ingresar en un pinpad para ingresar a una "habitación segura".&lt;br /&gt;Pero un atacante tiene la posibilidad de leer huellas digitales y por lo tanto sabe que teclas apretaste pero no en que orden ni con que repetición (o sea, no puede distinguir las claves "111112" y "122222").&lt;br /&gt;&lt;br /&gt;¿Cómo se debe elegir la clave de tal manera que el atacante tenga la mayor dificultad posible para adivinarla?&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Este problema lo postié en los news internos del laburo y &lt;a href="http://corelabs.coresecurity.com/index.php?module=FrontEndMod&amp;action=view&amp;type=researcher&amp;name=Carlos_Sarraute"&gt;Charles&lt;/a&gt;, un compañero de laburo, se mandó una explicación buenísima en dos mensajes. Abajo pongo textuales los mails:&lt;br /&gt;&lt;br /&gt;Primer mail:&lt;br /&gt;&lt;blockquote&gt;Con 6 digitos hay 6! = 720 posibilidades.&lt;br /&gt;&lt;br /&gt;Con 5 digitos, una forma de contar es así: supongamos que los digitos son 1,2,3,4,5 y que el 5 está repetido dos veces, lo contamos como 1,2,3,4,5a,5b y despues dividimos por las permutaciones de 5a y 5b. Eso da 6! / 2!, y como hay 5 posibilidades para el digito repetido el&lt;br /&gt;resultado es:&lt;br /&gt;6! / 2! * 5 = 1800 posibilidades.&lt;br /&gt;&lt;br /&gt;Con 4 digitos, puede haber un digito repetido tres veces, por ejemplo 1,2,3,4a,4b,4c&lt;br /&gt;Posibilidades 6! / 3! * 4 = 480&lt;br /&gt;Puede haber dos digitos repetidos dos veces cada uno, por ejemplo 1,2,3a,3b,4a,4b&lt;br /&gt;Posibilidades 6! / (2! * 2!) * Combinatorio(4,2) = 1080 El Combinatorio(4,2) es la cantidad de formas de elegir 2 elementos entre 4, es 4! / (2!*2!) = 6&lt;br /&gt;En total: 1560 posibilidades con 4 digitos&lt;br /&gt;&lt;br /&gt;Con 3 digitos, las estructuras son 1,2,3a,3b,3c,3d da 6! / 4! * 3 = 90&lt;br /&gt;1,2a,2b,3a,3b,3c da 6! / (3! * 2!) * (3*2) = 360 1a,1b,2a,2b,3a,3b da 6! / (2! * 2! * 2!) = 90&lt;br /&gt;Total: 540 posibilidades con 3 digitos&lt;br /&gt;&lt;br /&gt;Con 2 digitos, las estructuras son 1,2a,2b,2c,2d,2e   da 6! / 5! * 2 = 12&lt;br /&gt;1a,1b,2a,2b,2c,2d  da 6! / (4! * 2!) * 2 = 30 1a,1b,1c,2a,2b,2c  da 6! / (3! * 3!) = 20&lt;br /&gt;Total: 62 posibilidades con 2 digitos&lt;br /&gt;&lt;br /&gt;Con 1 digito, hay 6! / 6! = 1 posibilidad (claro ;-)&lt;br /&gt;&lt;br /&gt;Conclusión: hay que usar 5 digitos!&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Segundo mail:&lt;br /&gt;&lt;blockquote&gt;Me quedé pensando en tratar de sacar una relación de recurrencia...&lt;br /&gt;Llamemos "número de Aure" A(k,n) a la cantidad de claves de n digitos que usen exactamente k digitos distintos. Por ejemplo 1,2,2,3,3 es una clave de 5 digitos que usa 3 digitos distintos.&lt;br /&gt;&lt;br /&gt;Yo lo pienso como cantidad de claves con k digitos distintos en n lugares.&lt;br /&gt;&lt;br /&gt;Los casos faciles:&lt;br /&gt;A(1,n) = 1 para todo n&lt;br /&gt;A(k,n) = 0 si k &gt; n&lt;br /&gt;&lt;br /&gt;Ahora la recurrencia: si tengo una clave con n-1 lugares, hay dos opciones: ya se usaban los k digitos en los n-1 lugares, o solo se usaban k-1 digitos distintos y agregué el k-ésimo digito en el ultimo lugar.&lt;br /&gt;&lt;br /&gt;Si ya se usaban k digitos en n-1 lugares, tengo k posibilidades para el n-esimo lugar (repetir uno de los k digitos).&lt;br /&gt;&lt;br /&gt;Si se usaban exactamente k-1 digitos en n-1 lugares, entonces estoy agregando un digito nuevo en el n-ésimo lugar. Tengo k opciones para el digito nuevo.&lt;br /&gt;&lt;br /&gt;Luego A(k,n) = k * A(k,n-1) + k * A(k-1,n-1)&lt;br /&gt;&lt;br /&gt;A(k,n) = k * ( A(k,n-1) + A(k-1,n-1) )&lt;br /&gt;&lt;br /&gt;Es como un triangulo de Pascal con un multiplicador k.&lt;br /&gt;&lt;br /&gt;Las primeras filas dan:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;       k=1     k=2     k=3     k=4     k=5     k=6&lt;br /&gt;n=1     1       0&lt;br /&gt;n=2     1       2       0&lt;br /&gt;n=3     1       6       6       0&lt;br /&gt;n=4     1       14      36      24      0&lt;br /&gt;n=5     1       30      150     240     120     0&lt;br /&gt;n=6     1       62      540     1560    1800    720     0&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Sorprendentemente, volvió a dar los mismos números ;-)&lt;br /&gt;&lt;br /&gt;La problema de Aure se puede reformular como "qué k maximiza A(k,6)?"&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;En fin, el problema parece que dio para mucho :D, y tengo mis propios números con una serie que tiene un sentido y una "aplicación".&lt;br /&gt;&lt;br /&gt;Happy hacking,&lt;br /&gt;Aureliano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-4759121310883764714?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/4759121310883764714/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=4759121310883764714' title='2 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/4759121310883764714'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/4759121310883764714'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2008/12/nmeros-de-aure.html' title='Números de Aure'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-5928681097799546510</id><published>2008-11-09T00:09:00.003-02:00</published><updated>2009-07-07T23:15:40.712-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Mirando android</title><content type='html'>Hoy estuve mirando un toque como hacer una aplicación en Android. Después de hacer el HelloWorld correspondiente, seguir parte del tutorial sobre como hacer una aplicación que sirva para guardar notas y leer bastante de la documentación, hice correr el Lunar Lander. El Lunar Lander es un port del archi-conocido juego al android. &lt;br /&gt;Pensé que iba a salir de toque, pero no :(. Así que puse manos a la obra, toque las 2 tonteras que tenía mal y lo hice andar. Para que no tengan que hacer lo mismo que yo, les dejo mi proyecto de eclipse armado. Es igual al de los ejemplos de Google salvo porque como package uso aure en vez de com.android.examples. &lt;br /&gt;Acá está el &lt;a href="http://aurelianocalvo.googlepages.com/LunarLander.tar.gz"&gt;tar.gz&lt;/a&gt;.&lt;br /&gt;Happy hacking,&lt;br /&gt;Aureliano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-5928681097799546510?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/5928681097799546510/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=5928681097799546510' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/5928681097799546510'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/5928681097799546510'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2008/11/mirando-android.html' title='Mirando android'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-3149189197545118174</id><published>2008-11-04T00:12:00.006-02:00</published><updated>2009-07-07T19:07:27.059-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='euler'/><title type='text'>Proyecto Euler: Problemas 19 a 21</title><content type='html'>Sigo avanzando con los ejercicios del proyecto Euler. Les cuento los siguientes 3 ejercicios.&lt;br /&gt;EL ejercicio 19 consiste en contar la cantidad de domingos del siglo 20. Primero pensé en hacer un montón de aritmética modular para resolver esto, pero después se me ocurrió una idea mejor. Así que usé la biblioteca de fechas de ruby, iteré por todos los días de enero del siglo 20 y sumé todos los domingos. Acá abajo pongo el código:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;require 'date'&lt;br /&gt;&lt;br /&gt;sundays = 0&lt;br /&gt;(1901..2000).each do&lt;br /&gt;  |year|&lt;br /&gt;  Date.civil(year,1,1).upto(Date.civil(year,1,31)) do&lt;br /&gt;    |d|&lt;br /&gt;    sundays += 1 if d.wday == 0 # is sunday&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;puts "# of sundays in the 20th century: #{sundays}"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;El resultado de la corrida (casi instantáneo) es:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ ruby euler19.rb&lt;br /&gt;# of sundays in the 20th century: 443&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;El ejercicio 20 consiste en encontrar la suma de los dígitos de 100!. Usando las funciones para obtener cada dígito de un número del ejercicio 16, se hace bastante fácil. Este es el código:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class Integer&lt;br /&gt;  def digit(pos)&lt;br /&gt;    (self / (10 ** pos)) % 10&lt;br /&gt;  end&lt;br /&gt;  def digit_count&lt;br /&gt;    dc = 0&lt;br /&gt;    while self - (10 ** dc) &gt; 0&lt;br /&gt;      dc += 1&lt;br /&gt;    end&lt;br /&gt;    dc += 1 if self % (10 ** dc) == 0&lt;br /&gt;    dc&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;fact100 = (1..100).inject { |prod,n| prod * n }&lt;br /&gt;puts "Digits: #{fact100}"&lt;br /&gt;puts "Sum: #{(0...(fact100.digit_count)).inject {|s,n| s + fact100.digit(n)}}"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Y el resultado de la ejecución (también instantánea) es:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ ruby euler20.rb&lt;br /&gt;Digits: 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000&lt;br /&gt;Sum: 648&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;El ejercicio 21 es el más complicado de los 3. Consiste en sumar todos los números naturales "amigables" menores a 10000. Un par de números (a,b) es amigable si la suma de los divisores de a (excluyendo a) es b y la suma de los divisores de b (excluyendo b) es a. Un número es amigable si pertenece a un par amigable. Lo que se me ocurrió fue usar el MemoFactorizator (factorizador de números que recuerda factorizaciones previas) del ejercicio 12 para calcular las factorizaciones de todos los números menores a 10000. Usando esto, calculé analíticamente las sumas de los divisores propios (hay una fórmula re-linda que sale de la factorización, pero como no puedo escribir LaTeX facilmente acá, mejor mirenla en el código). Y habiendo calculado todas las sumas de los divisores, buscar en orden n todos los números amigables. Acá está el código:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class OddPrimes&lt;br /&gt;  def initialize&lt;br /&gt;    @current = 1&lt;br /&gt;    @primes = []&lt;br /&gt;  end&lt;br /&gt;  attr_reader :current&lt;br /&gt;  def next&lt;br /&gt;    while not prime?(@current += 2)&lt;br /&gt;    end&lt;br /&gt;    @primes &amp;lt;&amp;lt; @current&lt;br /&gt;    @current&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  def prime?(n)&lt;br /&gt;    i = 0&lt;br /&gt;    p = 1&lt;br /&gt;    while true&lt;br /&gt;      break if i &gt;= @primes.length&lt;br /&gt;      p = @primes[i]&lt;br /&gt;      break if p * p &gt; n&lt;br /&gt;      break if n % p == 0&lt;br /&gt;      i += 1&lt;br /&gt;    end&lt;br /&gt;    return i &gt;= @primes.length || p * p &gt; n&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;class Primes &lt; OddPrimes&lt;br /&gt;  def initialize&lt;br /&gt;    super&lt;br /&gt;    @first = true&lt;br /&gt;  end&lt;br /&gt;  def next&lt;br /&gt;    if @first&lt;br /&gt;      @first = false&lt;br /&gt;      2&lt;br /&gt;    else&lt;br /&gt;      super&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;  def current&lt;br /&gt;    odd_super = super&lt;br /&gt;    odd_super == 1 ? 2 : odd_super&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;class MemoFactorizator&lt;br /&gt;  attr_reader :factored&lt;br /&gt;  def initialize&lt;br /&gt;    @factored = {1 =&gt; {} }&lt;br /&gt;  end&lt;br /&gt;  def factorize(n, pg = Primes.new)&lt;br /&gt;    return @factored[n] if @factored.include?( n )&lt;br /&gt;    p = pg.current&lt;br /&gt;    while n % p != 0&lt;br /&gt;      p = p.next&lt;br /&gt;    end&lt;br /&gt;    factorization = factorize( n / p, pg ).dup&lt;br /&gt;    factorization[p] = factorization.include?(p) ? factorization[p] + 1 : 1&lt;br /&gt;    @factored[n] = factorization&lt;br /&gt;    factorization&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;def divisor_sum(n, factorization)&lt;br /&gt;  acum = 1&lt;br /&gt;  factorization.each_pair do&lt;br /&gt;    |p,pow|&lt;br /&gt;    acum *= (0..pow).inject(0) { |s,i| s + p ** i }&lt;br /&gt;  end&lt;br /&gt;  acum - n&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;MAX = 10000&lt;br /&gt;&lt;br /&gt;mf = MemoFactorizator.new&lt;br /&gt;(2...MAX).each do&lt;br /&gt;  |n|&lt;br /&gt;  mf.factorize(n)&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;sums = {}&lt;br /&gt;(2...MAX).each do&lt;br /&gt;  |n|&lt;br /&gt;  sums[n] = divisor_sum(n, mf.factored[n])&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;amicable = []&lt;br /&gt;&lt;br /&gt;(2...MAX).each do&lt;br /&gt;  |n|&lt;br /&gt;  amicable &amp;lt;&amp;lt; n if n == sums[sums[n]] and n != sums[n]&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;puts "Amicable numbers: #{amicable.inspect}"&lt;br /&gt;puts "Sum: #{amicable.inject {|s,n| s+n}}"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;La ejecución tardó un poquito (unos 4 segundos) y dio este resultado:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ time ruby euler21.rb&lt;br /&gt;Amicable numbers: [220, 284, 1184, 1210, 2620, 2924, 5020, 5564, 6232, 6368]&lt;br /&gt;Sum: 31626&lt;br /&gt;&lt;br /&gt;real    0m4.681s&lt;br /&gt;user    0m4.560s&lt;br /&gt;sys     0m0.108s&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Happy hacking,&lt;br /&gt;Aureliano&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-3149189197545118174?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/3149189197545118174/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=3149189197545118174' title='1 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/3149189197545118174'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/3149189197545118174'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2008/11/proyecto-euler-problemas-19-21.html' title='Proyecto Euler: Problemas 19 a 21'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-4284561683382308336</id><published>2008-11-01T01:27:00.006-02:00</published><updated>2009-07-07T19:05:35.390-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='euler'/><title type='text'>Proyecto Euler: Problemas 16 a 18</title><content type='html'>&lt;span style="font-weight:bold;"&gt;Update:&lt;/span&gt; Reporto la suma en el ejercicio 18.&lt;br /&gt;&lt;br /&gt;Sigo con mi maratón euleriana. Ahora resolví los problemas 16 a 18. &lt;br /&gt;El problema 16 consiste en encontrar la suma de los dígitos de 2^1000. Para eso desenpolvé la lógica para obtener la cantidad de dígitos de un número y qué dígito es que había hecho para el problema 4 (pequeño quiz: ¿qué bug le arreglé?) calculé 2^1000 y sumé los dígitos. Este es el código:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class Integer&lt;br /&gt;  def digit(pos)&lt;br /&gt;    (self / (10 ** pos)) % 10&lt;br /&gt;  end&lt;br /&gt;  def digit_count&lt;br /&gt;    dc = 0&lt;br /&gt;    while self - (10 ** dc) &gt; 0&lt;br /&gt;      dc += 1&lt;br /&gt;    end&lt;br /&gt;    dc += 1 if self % (10 ** dc) == 0&lt;br /&gt;    dc&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;n = 2 ** 1000&lt;br /&gt;digits_sum = (0..(n.digit_count)).inject(0) { |sum, pos| sum += n.digit(pos) }&lt;br /&gt;puts digits_sum&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Y este el resultado (que sale instantáneamente):&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ ruby euler16.rb&lt;br /&gt;1366&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;El problema 17 consiste en calcular cuantas letras (con repeticiones) hay en los números del 1 al mil en inglés. Por ejemplo "one two three" tiene 11 letras. Para eso hice una rutina que genera las palabras asociadas a cada número entre 1 y 1000, eso generó un string. Al string le saqué los espacios y conté la cantidad de caracteres. Mientras lo hacía me acordé de cuando &lt;a href="http://aurelianito.blogspot.com/2007/11/51-x-109-parte-2.html"&gt;estuve probando unos de los ejercicios que usan en ITA para contratar gente&lt;/a&gt;, pero lo escribí todo de 0. Acá va el código:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class Integer&lt;br /&gt;  UNITS = ["","one","two","three","four","five","six","seven","eight","nine"]&lt;br /&gt;  TEENS = ["ten","eleven","twelve","thirteen","fourteen","fifteen","sixteen","seventeen","eighteen","nineteen"]&lt;br /&gt;  TENS = ["","","twenty","thirty","fourty","fifty","sixty","seventy","eighty","ninety"]&lt;br /&gt;  def to_words&lt;br /&gt;    raise Exception.new("Don't know how to say in words the number #{self}") unless (1..1000).include? self&lt;br /&gt;    return "one thowsand" if self == 1000&lt;br /&gt;    words = []&lt;br /&gt;    if self &gt;= 100 then &lt;br /&gt;      words &lt;&lt; UNITS[self / 100]&lt;br /&gt;      words &lt;&lt; "hundred"&lt;br /&gt;    end&lt;br /&gt;    words &lt;&lt; "and" if (self % 100) != 0&lt;br /&gt;    case (self % 100) / 10&lt;br /&gt;      when 1&lt;br /&gt;        words &lt;&lt; TEENS[self%10]&lt;br /&gt;      else&lt;br /&gt;        words &lt;&lt; TENS[(self % 100) / 10]&lt;br /&gt;        words &lt;&lt; UNITS[self % 10]&lt;br /&gt;    end&lt;br /&gt;    return words.delete_if{|w| w == ""}.join(" ")&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;char_count = (1..1000).inject(0) { |sum,n| sum + n.to_words.gsub(" ","").length }&lt;br /&gt;puts char_count&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Y la corrida (también instantánea):&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ ruby euler17.rb&lt;br /&gt;21521&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Por último hice el ejercicio 18, que es el más interesante de los 3. El mismo consiste en navegar por un triángulo (que pongo más abajo), encontrando el camino desde arriba de todo a algún numerito de abajo de tal manera que la suma de los nodos del camino sea lo mayor posible.&lt;br /&gt;&lt;p style="text-align: center; font-family: courier new;"&gt;75&lt;br /&gt;95 64&lt;br /&gt;17 47 82&lt;br /&gt;18 35 87 10&lt;br /&gt;20 04 82 47 65&lt;br /&gt;19 01 23 75 03 34&lt;br /&gt;88 02 77 73 07 63 67&lt;br /&gt;99 65 04 28 06 16 70 92&lt;br /&gt;41 41 26 56 83 40 80 70 33&lt;br /&gt;41 48 72 33 47 32 37 16 94 29&lt;br /&gt;53 71 44 65 25 43 91 52 97 51 14&lt;br /&gt;70 11 33 28 77 73 17 78 39 68 17 57&lt;br /&gt;91 71 52 38 17 14 91 43 58 50 27 29 48&lt;br /&gt;63 66 04 68 89 53 67 30 73 16 69 87 40 31&lt;br /&gt;04 62 98 27 23 09 70 98 73 93 38 53 60 04 23&lt;/p&gt;&lt;br /&gt;Para resolver este problema, calculé las sumas de los mejores caminos posibles para todos los subtriangulos y después, usando eso, elegí en forma greedy el mejor camino. Acá va el código:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;data_text = &amp;lt;&amp;lt;DATA_TEXT&lt;br /&gt;75&lt;br /&gt;95 64&lt;br /&gt;17 47 82&lt;br /&gt;18 35 87 10&lt;br /&gt;20 04 82 47 65&lt;br /&gt;19 01 23 75 03 34&lt;br /&gt;88 02 77 73 07 63 67&lt;br /&gt;99 65 04 28 06 16 70 92&lt;br /&gt;41 41 26 56 83 40 80 70 33&lt;br /&gt;41 48 72 33 47 32 37 16 94 29&lt;br /&gt;53 71 44 65 25 43 91 52 97 51 14&lt;br /&gt;70 11 33 28 77 73 17 78 39 68 17 57&lt;br /&gt;91 71 52 38 17 14 91 43 58 50 27 29 48&lt;br /&gt;63 66 04 68 89 53 67 30 73 16 69 87 40 31&lt;br /&gt;04 62 98 27 23 09 70 98 73 93 38 53 60 04 23&lt;br /&gt;DATA_TEXT&lt;br /&gt;&lt;br /&gt;data = data_text.split("\n").map{ |row_text| row_text.split(" ").map{ |cell_text| cell_text.to_i(10) } }&lt;br /&gt;sums = Array.new(data.length)&lt;br /&gt;sums[-1] = data[-1].dup&lt;br /&gt;(2..(data.length)).each do&lt;br /&gt;  |row|&lt;br /&gt;  sum = []&lt;br /&gt;  prev_sum = sums[-row+1]&lt;br /&gt;  data[-row].each_with_index do&lt;br /&gt;    |v,i|&lt;br /&gt;    sum[i] = v + [prev_sum[i],prev_sum[i+1]].max&lt;br /&gt;  end&lt;br /&gt;  sums[-row] = sum&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;pos = 0&lt;br /&gt;path = []&lt;br /&gt;&lt;br /&gt;(1..(data.length - 1)).each do&lt;br /&gt;  |row|&lt;br /&gt;  if sums[row][pos] &gt; sums[row][pos+1] then&lt;br /&gt;    path &lt;&lt; :left&lt;br /&gt;  else&lt;br /&gt;    path &lt;&lt; :right&lt;br /&gt;    pos += 1&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;puts path.inspect&lt;br /&gt;puts "Sum: #{sums[0][0]}"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Y este es el resultado de la ejecución (también instantáneo, ya que se hacen tantas sumas como subtriángulos no triviales (que son menos que la cantidad de números en el triángulo) y tantas elecciones como la altura del triángulo. Acá les muestro el resultado:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ ruby euler18.rb&lt;br /&gt;[:right, :right, :left, :left, :right, :left, :left, :right, :right, :right, :right, :right, :left, :right]&lt;br /&gt;Sum: 1074&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Happy hacking,&lt;br /&gt;Aureliano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-4284561683382308336?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/4284561683382308336/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=4284561683382308336' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/4284561683382308336'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/4284561683382308336'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2008/11/proyecto-euler-problemas-16-18.html' title='Proyecto Euler: Problemas 16 a 18'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-4427233372817398747</id><published>2008-10-29T00:43:00.003-02:00</published><updated>2009-07-07T19:05:43.293-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='euler'/><title type='text'>Proyecto Euler: Problemas 13 a 15</title><content type='html'>Los problemas 13 a 15 resultaron más faciles que el 12. El 13 consiste en saber los primeros 10 dígitos de una suma de 100 números re-grandes. Como ruby soporta números arbitrariamente grandes, una vez que obtuve los números lo resolví en un one-liner:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;data_text = &amp;lt;&amp;lt;DATA_TEXT&lt;br /&gt;37107287533902102798797998220837590246510135740250&lt;br /&gt;46376937677490009712648124896970078050417018260538&lt;br /&gt;74324986199524741059474233309513058123726617309629&lt;br /&gt;91942213363574161572522430563301811072406154908250&lt;br /&gt;23067588207539346171171980310421047513778063246676&lt;br /&gt;89261670696623633820136378418383684178734361726757&lt;br /&gt;28112879812849979408065481931592621691275889832738&lt;br /&gt;44274228917432520321923589422876796487670272189318&lt;br /&gt;47451445736001306439091167216856844588711603153276&lt;br /&gt;70386486105843025439939619828917593665686757934951&lt;br /&gt;62176457141856560629502157223196586755079324193331&lt;br /&gt;64906352462741904929101432445813822663347944758178&lt;br /&gt;92575867718337217661963751590579239728245598838407&lt;br /&gt;58203565325359399008402633568948830189458628227828&lt;br /&gt;80181199384826282014278194139940567587151170094390&lt;br /&gt;35398664372827112653829987240784473053190104293586&lt;br /&gt;86515506006295864861532075273371959191420517255829&lt;br /&gt;71693888707715466499115593487603532921714970056938&lt;br /&gt;54370070576826684624621495650076471787294438377604&lt;br /&gt;53282654108756828443191190634694037855217779295145&lt;br /&gt;36123272525000296071075082563815656710885258350721&lt;br /&gt;45876576172410976447339110607218265236877223636045&lt;br /&gt;17423706905851860660448207621209813287860733969412&lt;br /&gt;81142660418086830619328460811191061556940512689692&lt;br /&gt;51934325451728388641918047049293215058642563049483&lt;br /&gt;62467221648435076201727918039944693004732956340691&lt;br /&gt;15732444386908125794514089057706229429197107928209&lt;br /&gt;55037687525678773091862540744969844508330393682126&lt;br /&gt;18336384825330154686196124348767681297534375946515&lt;br /&gt;80386287592878490201521685554828717201219257766954&lt;br /&gt;78182833757993103614740356856449095527097864797581&lt;br /&gt;16726320100436897842553539920931837441497806860984&lt;br /&gt;48403098129077791799088218795327364475675590848030&lt;br /&gt;87086987551392711854517078544161852424320693150332&lt;br /&gt;59959406895756536782107074926966537676326235447210&lt;br /&gt;69793950679652694742597709739166693763042633987085&lt;br /&gt;41052684708299085211399427365734116182760315001271&lt;br /&gt;65378607361501080857009149939512557028198746004375&lt;br /&gt;35829035317434717326932123578154982629742552737307&lt;br /&gt;94953759765105305946966067683156574377167401875275&lt;br /&gt;88902802571733229619176668713819931811048770190271&lt;br /&gt;25267680276078003013678680992525463401061632866526&lt;br /&gt;36270218540497705585629946580636237993140746255962&lt;br /&gt;24074486908231174977792365466257246923322810917141&lt;br /&gt;91430288197103288597806669760892938638285025333403&lt;br /&gt;34413065578016127815921815005561868836468420090470&lt;br /&gt;23053081172816430487623791969842487255036638784583&lt;br /&gt;11487696932154902810424020138335124462181441773470&lt;br /&gt;63783299490636259666498587618221225225512486764533&lt;br /&gt;67720186971698544312419572409913959008952310058822&lt;br /&gt;95548255300263520781532296796249481641953868218774&lt;br /&gt;76085327132285723110424803456124867697064507995236&lt;br /&gt;37774242535411291684276865538926205024910326572967&lt;br /&gt;23701913275725675285653248258265463092207058596522&lt;br /&gt;29798860272258331913126375147341994889534765745501&lt;br /&gt;18495701454879288984856827726077713721403798879715&lt;br /&gt;38298203783031473527721580348144513491373226651381&lt;br /&gt;34829543829199918180278916522431027392251122869539&lt;br /&gt;40957953066405232632538044100059654939159879593635&lt;br /&gt;29746152185502371307642255121183693803580388584903&lt;br /&gt;41698116222072977186158236678424689157993532961922&lt;br /&gt;62467957194401269043877107275048102390895523597457&lt;br /&gt;23189706772547915061505504953922979530901129967519&lt;br /&gt;86188088225875314529584099251203829009407770775672&lt;br /&gt;11306739708304724483816533873502340845647058077308&lt;br /&gt;82959174767140363198008187129011875491310547126581&lt;br /&gt;97623331044818386269515456334926366572897563400500&lt;br /&gt;42846280183517070527831839425882145521227251250327&lt;br /&gt;55121603546981200581762165212827652751691296897789&lt;br /&gt;32238195734329339946437501907836945765883352399886&lt;br /&gt;75506164965184775180738168837861091527357929701337&lt;br /&gt;62177842752192623401942399639168044983993173312731&lt;br /&gt;32924185707147349566916674687634660915035914677504&lt;br /&gt;99518671430235219628894890102423325116913619626622&lt;br /&gt;73267460800591547471830798392868535206946944540724&lt;br /&gt;76841822524674417161514036427982273348055556214818&lt;br /&gt;97142617910342598647204516893989422179826088076852&lt;br /&gt;87783646182799346313767754307809363333018982642090&lt;br /&gt;10848802521674670883215120185883543223812876952786&lt;br /&gt;71329612474782464538636993009049310363619763878039&lt;br /&gt;62184073572399794223406235393808339651327408011116&lt;br /&gt;66627891981488087797941876876144230030984490851411&lt;br /&gt;60661826293682836764744779239180335110989069790714&lt;br /&gt;85786944089552990653640447425576083659976645795096&lt;br /&gt;66024396409905389607120198219976047599490197230297&lt;br /&gt;64913982680032973156037120041377903785566085089252&lt;br /&gt;16730939319872750275468906903707539413042652315011&lt;br /&gt;94809377245048795150954100921645863754710598436791&lt;br /&gt;78639167021187492431995700641917969777599028300699&lt;br /&gt;15368713711936614952811305876380278410754449733078&lt;br /&gt;40789923115535562561142322423255033685442488917353&lt;br /&gt;44889911501440648020369068063960672322193204149535&lt;br /&gt;41503128880339536053299340368006977710650566631954&lt;br /&gt;81234880673210146739058568557934581403627822703280&lt;br /&gt;82616570773948327592232845941706525094512325230608&lt;br /&gt;22918802058777319719839450180888072429661980811197&lt;br /&gt;77158542502016545090413245809786882778948721859617&lt;br /&gt;72107838435069186155435662884062257473692284509516&lt;br /&gt;20849603980134001723930671666823555245252804609722&lt;br /&gt;53503534226472524250874054075591789781264330331690&lt;br /&gt;DATA_TEXT&lt;br /&gt;&lt;br /&gt;puts (data_text.split("\n").map { |n| n.to_i(10) }.inject(0) { |sum,n| sum + n }).to_s[0..9]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;El resultado fue (solo por curiosidad):&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ ruby euler13.rb&lt;br /&gt;5537376230&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Y la corrida fue casi instantánea.&lt;br /&gt;El problema 14 consiste en buscar el número menor a 1000000 que genera la secuencia de Collatz más grande. La secuencia de Collatz se calcula así:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Si n es 1, terminó&lt;/li&gt;&lt;li&gt;Si n es par, es n:collatz(n/2)&lt;/li&gt;&lt;li&gt;Si n es impar, es n:collatz(n*3 + 1)&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Este problema se resuelve con un poco de memoization:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class PathLengthMemoizator&lt;br /&gt;  def initialize&lt;br /&gt;    @lengths = {1 =&gt; 0}&lt;br /&gt;    @max_n = 1&lt;br /&gt;  end&lt;br /&gt;  attr_reader :max_n&lt;br /&gt;  &lt;br /&gt;  def max_length&lt;br /&gt;    @lengths[max_n]&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  def calculate_length(n)&lt;br /&gt;    return @lengths[n] if @lengths.include?(n)&lt;br /&gt;    @lengths[n] = calculate_length( n % 2 == 0 ? n/2 : 3*n + 1 ) + 1&lt;br /&gt;    @max_n = n if @lengths[n] &gt; @lengths[@max_n]&lt;br /&gt;    @lengths[n]&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;plm = PathLengthMemoizator.new&lt;br /&gt;(1...1000000).each do&lt;br /&gt;  |n|&lt;br /&gt;  plm.calculate_length(n)&lt;br /&gt;end&lt;br /&gt;puts "Longest path number: #{plm.max_n}"&lt;br /&gt;puts "Length: #{plm.max_length}"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Y cuando lo corrí, dio este resultado:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ time ruby euler14.rb&lt;br /&gt;Longest path number: 837799&lt;br /&gt;Length: 524&lt;br /&gt;&lt;br /&gt;real    0m15.058s&lt;br /&gt;user    0m13.609s&lt;br /&gt;sys     0m1.284s&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;El problema 15 es el más interesante. En un cuadriculado de tamaño 20 * 20, yendo por las rayitas para abajo y a la derecha, ¿cuántas formas hay de ir desde la posición (0,0) hasta la (20,20)? En un principio, parecía un quilombo. Pero, calculando cuantos caminos hay desde (0,0) hasta (X,Y) me di cuenta que en las diagonales se armaba el &lt;a href="http://en.wikipedia.org/wiki/Pascal_triangle"&gt;Triángulo de pascal&lt;/a&gt;. Entonces, mirando fijo, me salió la fórmula general para calcular cuantos caminos hay hasta (X,Y) desde (0,0). Es (X*Y)! / (X! * Y!).&lt;br /&gt;Aplicando la fórmula a la coordenada (20,20) queda 40! / (20! * 20!), que corriendo en el irb queda así:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ irb&lt;br /&gt;irb(main):001:0&gt; class Integer&lt;br /&gt;irb(main):002:1&gt;   def fact&lt;br /&gt;irb(main):003:2&gt;     (1..self).inject(1) { |f,n| f*n }&lt;br /&gt;irb(main):004:2&gt;   end&lt;br /&gt;irb(main):005:1&gt; end&lt;br /&gt;=&gt; nil&lt;br /&gt;irb(main):006:0&gt; 40.fact / (20.fact * 20.fact)&lt;br /&gt;=&gt; 137846528820&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Habiéndo resuelto el problema en forma elegantísima, me voy a dormir antes que encuentre otro.&lt;br /&gt;Happy hacking,&lt;br /&gt;Aureliano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-4427233372817398747?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/4427233372817398747/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=4427233372817398747' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/4427233372817398747'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/4427233372817398747'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2008/10/proyecto-euler-problemas-13-15.html' title='Proyecto Euler: Problemas 13 a 15'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-3655183094027544816</id><published>2008-10-28T23:18:00.003-02:00</published><updated>2009-07-07T19:05:52.987-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='euler'/><title type='text'>Proyecto Euler: Problema 12</title><content type='html'>Sigo enfermo con el proyecto Euler. Y ya hice el problema 12. El mismo consiste en encontrar el primer número triangular con más de 500 divisores. Un número triangular es de la forma 1 + 2 + 3 + ... + n. Y, se puede calcular rápidamente como n*(n+1)/2.&lt;br /&gt;Mi primer intento de resolución (que anduvo pero fue lento) consistió en usar el generador de números primos del ejercicio 3 para calcular la cantidad de divisores del número, calculándolo directamente. Acá va el código:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class Integer&lt;br /&gt;  def triangle&lt;br /&gt;    (self * (self + 1)) / 2&lt;br /&gt;  end&lt;br /&gt;  def divisor_count&lt;br /&gt;    n = self&lt;br /&gt;    pg = Primes.new&lt;br /&gt;    count = 1&lt;br /&gt;    while n != 1&lt;br /&gt;      p = pg.next&lt;br /&gt;      pow = 0&lt;br /&gt;      while n % p == 0&lt;br /&gt;        pow += 1&lt;br /&gt;        n /= p&lt;br /&gt;      end&lt;br /&gt;      count *= (pow + 1)&lt;br /&gt;    end&lt;br /&gt;    count&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;class OddPrimes&lt;br /&gt;  def initialize&lt;br /&gt;    @current = 1&lt;br /&gt;    @primes = []&lt;br /&gt;  end&lt;br /&gt;  attr_reader :current&lt;br /&gt;  def next&lt;br /&gt;    while not prime?(@current += 2)&lt;br /&gt;    end&lt;br /&gt;    @primes &lt;&lt; @current&lt;br /&gt;    @current&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  def prime?(n)&lt;br /&gt;    i = 0&lt;br /&gt;    p = 1&lt;br /&gt;    while true&lt;br /&gt;      break if i &gt;= @primes.length&lt;br /&gt;      p = @primes[i]&lt;br /&gt;      break if p * p &gt; n&lt;br /&gt;      break if n % p == 0&lt;br /&gt;      i += 1&lt;br /&gt;    end&lt;br /&gt;    return i &gt;= @primes.length || p * p &gt; n&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;class Primes &lt; OddPrimes&lt;br /&gt;  def initialize&lt;br /&gt;    super&lt;br /&gt;    @first = true&lt;br /&gt;  end&lt;br /&gt;  def next&lt;br /&gt;    if @first&lt;br /&gt;      @first = false&lt;br /&gt;      2&lt;br /&gt;    else&lt;br /&gt;      super&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;  def current&lt;br /&gt;    odd_super = super&lt;br /&gt;    odd_super == 1 ? 2 : odd_super&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;n = 1&lt;br /&gt;while n.triangle.divisor_count &lt;= 500&lt;br /&gt;  n += 1&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;puts "Triangle #{n} (#{n.triangle}) is the first with over 500 divisors"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Anduvo, pero la corrida tardó como 4 minutos. Este es el resultado:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ time ruby euler12.rb&lt;br /&gt;Triangle 12375 (76576500) is the first with over 500 divisors&lt;br /&gt;&lt;br /&gt;real    4m17.556s&lt;br /&gt;user    3m57.519s&lt;br /&gt;sys     0m16.117s&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Así que me puse a pensar como hacer para que ande más rápido. Se me ocurrieron varias cosas:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Puedo calcular la factorización de n*(n+1)/2 sabiendo la factorización de n y n+1&lt;/li&gt;&lt;li&gt;Puedo calcular la factorización de cada número una sola vez (guardando factorizaciones viejas)&lt;/li&gt;&lt;li&gt;La factorización la puedo escribir recursivamente para usar las factorizaciones que ya calculé&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Usando todo esto, hice una nueva implementación:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class OddPrimes&lt;br /&gt;  def initialize&lt;br /&gt;    @current = 1&lt;br /&gt;    @primes = []&lt;br /&gt;  end&lt;br /&gt;  attr_reader :current&lt;br /&gt;  def next&lt;br /&gt;    while not prime?(@current += 2)&lt;br /&gt;    end&lt;br /&gt;    @primes &lt;&lt; @current&lt;br /&gt;    @current&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  def prime?(n)&lt;br /&gt;    i = 0&lt;br /&gt;    p = 1&lt;br /&gt;    while true&lt;br /&gt;      break if i &gt;= @primes.length&lt;br /&gt;      p = @primes[i]&lt;br /&gt;      break if p * p &gt; n&lt;br /&gt;      break if n % p == 0&lt;br /&gt;      i += 1&lt;br /&gt;    end&lt;br /&gt;    return i &gt;= @primes.length || p * p &gt; n&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;class Primes &lt; OddPrimes&lt;br /&gt;  def initialize&lt;br /&gt;    super&lt;br /&gt;    @first = true&lt;br /&gt;  end&lt;br /&gt;  def next&lt;br /&gt;    if @first&lt;br /&gt;      @first = false&lt;br /&gt;      2&lt;br /&gt;    else&lt;br /&gt;      super&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;  def current&lt;br /&gt;    odd_super = super&lt;br /&gt;    odd_super == 1 ? 2 : odd_super&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;class MemoFactorizator&lt;br /&gt;  def initialize&lt;br /&gt;    @factored = {1 =&gt; {} }&lt;br /&gt;  end&lt;br /&gt;  def factorize(n, pg = Primes.new)&lt;br /&gt;    return @factored[n] if @factored.include?( n )&lt;br /&gt;    p = pg.current&lt;br /&gt;    while n % p != 0&lt;br /&gt;      p = p.next&lt;br /&gt;    end&lt;br /&gt;    factorization = factorize( n / p, pg ).dup&lt;br /&gt;    factorization[p] = factorization.include?(p) ? factorization[p] + 1 : 1&lt;br /&gt;    @factored[n] = factorization&lt;br /&gt;    factorization&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;n = 1&lt;br /&gt;mf = MemoFactorizator.new&lt;br /&gt;while true&lt;br /&gt;  fact_n = mf.factorize(n)&lt;br /&gt;  fact_nn = mf.factorize(n+1)&lt;br /&gt;  triangle_factorization = fact_n.merge(fact_nn) { |k,old,new| old + new }&lt;br /&gt;  triangle_factorization[2] -= 1&lt;br /&gt;  &lt;br /&gt;  divisor_count = triangle_factorization.values.inject(1) { |c,pow| c*(pow+1) }&lt;br /&gt;  break if divisor_count &gt; 500&lt;br /&gt;  n += 1&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;puts "First triangle: #{n} (#{n*(n+1)/2})"&lt;br /&gt;puts "Factorization: #{triangle_factorization.inspect}"&lt;br /&gt;puts "Divisor count: #{divisor_count}"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;La nueva implementación tardó 6 segundos en correr.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ time ruby euler12.rb&lt;br /&gt;First triangle: 12375 (76576500)&lt;br /&gt;Factorization: {5=&gt;3, 11=&gt;1, 17=&gt;1, 7=&gt;1, 13=&gt;1, 2=&gt;2, 3=&gt;2}&lt;br /&gt;Divisor count: 576&lt;br /&gt;&lt;br /&gt;real    0m6.690s&lt;br /&gt;user    0m6.568s&lt;br /&gt;sys     0m0.100s&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Ahora estoy contento porque dio el mismo resultado que la vez anterior pero mucho más rápido y con código más lindo.&lt;br /&gt;&lt;br /&gt;Happy hacking,&lt;br /&gt;Aureliano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-3655183094027544816?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/3655183094027544816/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=3655183094027544816' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/3655183094027544816'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/3655183094027544816'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2008/10/proyecto-euler-problema-12.html' title='Proyecto Euler: Problema 12'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-3381247403140356041</id><published>2008-10-28T10:19:00.002-02:00</published><updated>2009-07-07T23:16:07.785-03:00</updated><title type='text'>Cumplí 0x20</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_vrWP6mUamXY/SQcEacbRE4I/AAAAAAAAADo/dZWdeDq7G2g/s1600-h/aure.26oct08.IMG_0402.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 300px;" src="http://4.bp.blogspot.com/_vrWP6mUamXY/SQcEacbRE4I/AAAAAAAAADo/dZWdeDq7G2g/s400/aure.26oct08.IMG_0402.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5262179541959381890" /&gt;&lt;/a&gt;&lt;br /&gt;El 18 cumplí años de nuevo. Parece que es cada vez más rápido.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-3381247403140356041?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/3381247403140356041/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=3381247403140356041' title='3 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/3381247403140356041'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/3381247403140356041'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2008/10/cumpl-0x20.html' title='Cumplí 0x20'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_vrWP6mUamXY/SQcEacbRE4I/AAAAAAAAADo/dZWdeDq7G2g/s72-c/aure.26oct08.IMG_0402.jpg' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-8213366056699808142</id><published>2008-10-28T01:34:00.005-02:00</published><updated>2009-07-07T23:16:17.723-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='euler'/><title type='text'>Un poquito más del proyecto Euler</title><content type='html'>Sigo enfermo resolviendo ejercicios del proyecto euler. Hoy resolví el ejercicio 11. El mismo consiste en encontrar en una matriz de 20x20 los cuatro números consecutivos en una misma línea (que puede ser horizontal, vertical o diagonal en cualquiera de sus 2 variantes) tal que su multiplicación sea lo más grande posible.&lt;br /&gt;He aquí el código fuente en ruby:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;require 'matrix'&lt;br /&gt;&lt;br /&gt;RAW_DATA = &amp;lt;&amp;lt;RAW_DATA&lt;br /&gt;08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08&lt;br /&gt;49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00&lt;br /&gt;81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65&lt;br /&gt;52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91&lt;br /&gt;22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80&lt;br /&gt;24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50&lt;br /&gt;32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70&lt;br /&gt;67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21&lt;br /&gt;24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72&lt;br /&gt;21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95&lt;br /&gt;78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92&lt;br /&gt;16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57&lt;br /&gt;86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58&lt;br /&gt;19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40&lt;br /&gt;04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66&lt;br /&gt;88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69&lt;br /&gt;04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36&lt;br /&gt;20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16&lt;br /&gt;20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54&lt;br /&gt;01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48&lt;br /&gt;RAW_DATA&lt;br /&gt;data = Matrix[*RAW_DATA.split("\n").map { |row| row.split(" ").map { |n| n.to_i(10) } }]&lt;br /&gt;&lt;br /&gt;DIRECTIONS = [[1,0],[0,1],[1,1],[1,-1]]&lt;br /&gt;best_product = -1&lt;br /&gt;best_row = -1&lt;br /&gt;best_col = -1&lt;br /&gt;best_dir = [0,0]&lt;br /&gt;&lt;br /&gt;DIRECTIONS.each do &lt;br /&gt;  |dir|&lt;br /&gt;  (0...20).each do &lt;br /&gt;    |row|&lt;br /&gt;    (0...20).each do &lt;br /&gt;      |col|&lt;br /&gt;      product = (0...4).inject(1) do &lt;br /&gt;        |prod, pos|&lt;br /&gt;        target_row = row + pos * dir[0]&lt;br /&gt;        target_col = col + pos * dir[1]&lt;br /&gt;        (0...20).include?(target_row) &amp;&amp; (0...20).include?(target_col) ? prod * data[target_row, target_col] : 0&lt;br /&gt;      end&lt;br /&gt;      if product &gt; best_product then&lt;br /&gt;        best_product = product&lt;br /&gt;        best_row = row&lt;br /&gt;        best_col = col&lt;br /&gt;        best_dir = dir&lt;br /&gt;      end&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;puts "Product: #{best_product}"&lt;br /&gt;puts "Row: #{best_row}"&lt;br /&gt;puts "Col: #{best_col}"&lt;br /&gt;puts "Dir: #{best_dir.inspect}"&lt;br /&gt;&lt;br /&gt;(0...4).each do &lt;br /&gt;  |pos|&lt;br /&gt;  target_row = best_row + pos * best_dir[0]&lt;br /&gt;  target_col = best_col + pos * best_dir[1]&lt;br /&gt;  puts "Position: #{target_row}, #{target_col}"&lt;br /&gt;  puts "Value: #{data[target_row, target_col]}"&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Y para que vean cuanto dio, esta es la salida de la corrida&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Product: 70600674&lt;br /&gt;Row: 12&lt;br /&gt;Col: 6&lt;br /&gt;Dir: [1, -1]&lt;br /&gt;Position: 12, 6&lt;br /&gt;Value: 89&lt;br /&gt;Position: 13, 5&lt;br /&gt;Value: 94&lt;br /&gt;Position: 14, 4&lt;br /&gt;Value: 97&lt;br /&gt;Position: 15, 3&lt;br /&gt;Value: 87&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Me voy a dormir. &lt;br /&gt;Happy hacking,&lt;br /&gt;Aureliano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-8213366056699808142?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/8213366056699808142/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=8213366056699808142' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/8213366056699808142'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/8213366056699808142'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2008/10/un-poquito-ms-del-proyecto-euler.html' title='Un poquito más del proyecto Euler'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1437970354124720603.post-2543765029830972181</id><published>2008-10-24T22:35:00.003-02:00</published><updated>2009-07-07T23:16:49.394-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='humor'/><title type='text'>Algunas verdades y mentiras infundadas del desarrollo de software</title><content type='html'>&lt;ul&gt;&lt;li&gt;Java es el nuevo Cobol&lt;/li&gt;&lt;li&gt;Eclipse es el nuevo emacs&lt;/li&gt;&lt;li&gt;Java es lento&lt;/li&gt;&lt;li&gt;Ruby es lento&lt;/li&gt;&lt;li&gt;C es rápido&lt;/li&gt;&lt;li&gt;C++ es rápido&lt;/li&gt;&lt;li&gt;PHP es una bosta&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Las 3 virtudes de un gran programador son la pereza, la impaciencia y la soberbia&lt;/li&gt;&lt;li&gt;Haciendo test-first y refactoring se puede mantener la calidad del código&lt;/li&gt;&lt;li&gt;Los sistemas en producción tienen código fuente feo&lt;/li&gt;&lt;li&gt;Haciendo test-first y refactoring no se hacen sistemas que queden en producción&lt;/li&gt;&lt;li&gt;Los programadores tienen pocas habilidades interpersonales&lt;/li&gt;&lt;li&gt;Los programadores deben hablar con los clientes para hacer los desarrollos&lt;/li&gt;&lt;li&gt;Barato, rápido, bueno: elija 2&lt;/li&gt;&lt;li&gt;Programando en Rails un programador es 10 veces más productivo que programando en J2EE&lt;/li&gt;&lt;li&gt;Lisp es el mejor lenguaje de programación&lt;/li&gt;&lt;li&gt;Smalltalk es el mejor lenguaje de programación&lt;/li&gt;&lt;li&gt;A python hay que agregarle closures y sería un lenguaje espectacular&lt;/li&gt;&lt;li&gt;Los verdaderos programadores programan en Fortran&lt;/li&gt;&lt;li&gt;Los verdaderos programadores programan en C++&lt;/li&gt;&lt;li&gt;Los verdaderos programadores programan en Assembler&lt;/li&gt;&lt;li&gt;Los verdaderos programadores programan en código máquina&lt;/li&gt;&lt;li&gt;Los verdaderos programadores silvan en el teléfono para transmitir datos a un modem, hacer un buffer overflow y reprogramar el server&lt;/li&gt;&lt;/ul&gt;Happy hacking,&lt;br /&gt;Aureliiano.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1437970354124720603-2543765029830972181?l=aurelianito.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aurelianito.blogspot.com/feeds/2543765029830972181/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1437970354124720603&amp;postID=2543765029830972181' title='2 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/2543765029830972181'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1437970354124720603/posts/default/2543765029830972181'/><link rel='alternate' type='text/html' href='http://aurelianito.blogspot.com/2008/10/algunas-verdades-y-mentiras-infundadas.html' title='Algunas verdades y mentiras infundadas del desarrollo de software'/><author><name>aurelianito</name><uri>http://www.blogger.com/profile/16123954643930749058</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry></feed>
