<?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-1354794578842586233</id><updated>2012-02-16T06:34:24.056-03:00</updated><category term='flash'/><category term='yield'/><category term='bardeo'/><category term='web'/><category term='desarrollo'/><category term='usuario'/><category term='memoria'/><category term='antipattern'/><category term='factorial'/><category term='css'/><category term='git'/><category term='memes'/><category term='tario'/><category term='gem'/><category term='mocking'/><category term='destino'/><category term='extension'/><category term='rails'/><category term='openvpn'/><category term='analisis'/><category term='gmodeler'/><category term='original'/><category term='blogs'/><category term='humor'/><category term='patch'/><category term='battlestargalactica'/><category term='changelog'/><category term='cyber'/><category term='lost'/><category term='mug'/><category term='apophysis'/><category term='security'/><category term='vmware'/><category term='commit'/><category term='freemind'/><category term='juego'/><category term='informatica'/><category term='boludeces'/><category term='xna'/><category term='jugo'/><category term='rvm'/><category term='post-mortem'/><category term='bash'/><category term='rubik'/><category term='game'/><category term='coworkers'/><category term='pizza'/><category term='vcube'/><category term='c'/><category term='pentaminx'/><category term='dns'/><category term='mental'/><category term='rsif'/><category term='unit testing'/><category term='dev'/><category term='sugar'/><category term='release'/><category term='comentarios'/><category term='blogging'/><category term='svn'/><category term='yuml'/><category term='trabajo'/><category term='ruby'/><category term='sandbox'/><category term='reflection'/><category term='net'/><category term='debugging'/><category term='picotest'/><category term='eval'/><category term='const_missing'/><category term='github'/><category term='environment'/><category term='hexadecimal'/><category term='perversion'/><category term='bsg'/><category term='numerico'/><category term='trucos'/><category term='botella'/><category term='radioactiva'/><category term='guerra'/><category term='uml'/><category term='filosofia'/><category term='tdd'/><category term='NilClass'/><category term='redes'/><category term='rubyconf'/><category term='linux'/><category term='debug'/><category term='acertijo'/><category term='cvs'/><category term='creatly'/><category term='gdb'/><category term='cookies'/><category term='cacoo'/><category term='codecamp'/><category term='scm'/><category term='blog'/><category term='parse_tree'/><category term='e2fsck'/><category term='argentina'/><category term='raii'/><category term='usuarios'/><category term='hooking'/><category term='codepress'/><category term='discos'/><category term='microsoft'/><category term='vpn'/><category term='mono'/><category term='bundle'/><category term='blackmagic'/><category term='mercurial'/><category term='zip'/><category term='git-svn'/><category term='finales'/><category term='gliffy'/><title type='text'>nil = NilClass.new</title><subtitle type='html'>Programacion en ruby - Resolucion de rubik - C bizarro - Tecnologia - Cosas locas - Programacion en general - C++ - Y mucho ++ !!!...</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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>81</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1354794578842586233.post-1897409002608600434</id><published>2012-01-02T11:29:00.008-03:00</published><updated>2012-01-02T11:40:37.886-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='unit testing'/><category scheme='http://www.blogger.com/atom/ns#' term='picotest'/><category scheme='http://www.blogger.com/atom/ns#' term='release'/><category scheme='http://www.blogger.com/atom/ns#' term='mocking'/><category scheme='http://www.blogger.com/atom/ns#' term='gem'/><title type='text'>No mas excusas para no testear con picotest</title><content type='html'>&lt;a href="https://github.com/tario/picotest"&gt;Picotest&lt;/a&gt; es una gem pensada principalmente para testear pequeños metodos, como helpers, funciones de calculo, etc... &lt;div&gt;Apenas se libero una primera version 0.0.1 de prueba para mostrar la idea, la cual consiste en evitar el "no vale la pena testear esto" cuando estamos frente a metodos o funciones que tienen un monton de casos pero testearlos supondria escribir mucha mas cantidad de lineas de codigo de lo que implicaria la propia funcionalidad que se testea&lt;/div&gt;&lt;div&gt;La solucion a esto en picotest es ofrecer un DSL que permita escribir una gran cantidad de casos de prueba en una o por lo menos muy pocas lineas. Por ejemplo:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;pre name="code" class="ruby"&gt;require "picotest"&lt;br /&gt;&lt;br /&gt;suite(1 =&amp;gt; 1, 4 =&amp;gt; 2, 9 =&amp;gt; 3, 16 =&amp;gt; 4).test(Math.method(:sqrt))&lt;br /&gt;&lt;/pre&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Tambien tiene sintaxis especifica para hacer &lt;i&gt;oracle testing&lt;/i&gt; y &lt;i&gt;mocking&lt;/i&gt; muy sencillo (seguir los enlaces para mas informacion)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;b&gt;Enlaces&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Post un poco mas detallado, con ejemplos: &lt;a href="http://tario-project.blogspot.com/2012/01/no-more-excuses-for-not-testing.html"&gt;http://tario-project.blogspot.com/2012/01/no-more-excuses-for-not-testing.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Sitio en github: &lt;a href="https://github.com/tario/picotest/"&gt;https://github.com/tario/picotest/&lt;/a&gt;&lt;/li&gt;&lt;/ul&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/1354794578842586233-1897409002608600434?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/1897409002608600434/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=1897409002608600434' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/1897409002608600434'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/1897409002608600434'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2012/01/no-mas-excusas-para-no-testear-con.html' title='No mas excusas para no testear con picotest'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-17061977248721304</id><published>2011-12-27T11:26:00.002-03:00</published><updated>2011-12-27T11:31:36.848-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='juego'/><category scheme='http://www.blogger.com/atom/ns#' term='acertijo'/><category scheme='http://www.blogger.com/atom/ns#' term='game'/><title type='text'>The Ruby Game</title><content type='html'>&lt;a href="http://anazulada.files.wordpress.com/2010/10/puzzle_pieces-01.jpg"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 250px; height: 212px;" src="http://anazulada.files.wordpress.com/2010/10/puzzle_pieces-01.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;div&gt;&lt;a href="http://therubygame.com/" style="text-align: -webkit-auto; "&gt;&lt;span&gt;http://therubygame.com/&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: -webkit-auto; "&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: -webkit-auto; "&gt;&lt;span&gt;Es un site que tira acertijos o problemas ruby en los que todos pueden participar enviando el codigo y ves los resultados al instante, lo copado es que podes ver un ranking de las soluciones que todos enviaron y aprender cosas interesantes de la sintaxis de ruby&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: -webkit-auto; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Let's the game begins!&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/1354794578842586233-17061977248721304?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/17061977248721304/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=17061977248721304' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/17061977248721304'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/17061977248721304'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2011/12/ruby-game.html' title='The Ruby Game'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-2885933959003662982</id><published>2011-12-08T13:55:00.042-03:00</published><updated>2011-12-09T12:26:26.039-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='usuario'/><category scheme='http://www.blogger.com/atom/ns#' term='memes'/><category scheme='http://www.blogger.com/atom/ns#' term='git'/><category scheme='http://www.blogger.com/atom/ns#' term='svn'/><title type='text'>Git para usuarios de Subversion</title><content type='html'>&lt;span class="Apple-style-span"&gt;&lt;a href="http://2.bp.blogspot.com/-5B9FpowzcJg/TuDyZaQmJ0I/AAAAAAAAATw/mNRINxvzlqc/s1600/everywhere.jpg" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 320px; height: 178px;" src="http://2.bp.blogspot.com/-5B9FpowzcJg/TuDyZaQmJ0I/AAAAAAAAATw/mNRINxvzlqc/s320/everywhere.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5683809248101148482" /&gt;&lt;/a&gt;O mejor dicho: &lt;div&gt;&lt;b&gt;&lt;span class="Apple-style-span"&gt;Git NO es para usuarios de Subversion&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Ir de svn a git, &lt;b&gt;no&lt;/b&gt; puede ser:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Siendo usuario SVN, leer guia  "Git para usuarios de Subversion"&lt;/li&gt;&lt;li&gt;Siendo usuario SVN, Usar git traduciendo los comandos que ejecutarias si usaras svn (epic fail), &lt;/li&gt;&lt;li&gt;Encontraran esa experiencia fea mientras sacan en conclusión que git posee una complejidad innecesaria y es muy difícil de usarlo&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;i&gt;"Para un usuario de svn siempre sera mas facil usar svn que git"&lt;/i&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Par ir de svn a git, es mejor seguir estos pasos:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Siendo usuario SVN, leer guia "Como volverse un usuario de git"&lt;/li&gt;&lt;li&gt;Siendo usuario &lt;b&gt;git&lt;/b&gt;, Usar git de manera natural&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Asi git se usaria mejor, pero quedan dos problemas:&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;"Para un usuario de &lt;b&gt;git&lt;/b&gt; siempre sera mas facil usar &lt;b&gt;git&lt;/b&gt; que &lt;b&gt;svn&lt;/b&gt;" &lt;/i&gt;, es decir,&lt;i&gt; &lt;/i&gt;que una vez acostumbrado a git usar svn se vuelve complicado.&lt;/li&gt;&lt;li&gt;Y mas importante, cambiar de el svn &lt;i&gt;mindset &lt;/i&gt;al git &lt;i&gt;mindset &lt;/i&gt;no es para nada algo trivial&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 238); font-style: normal; -webkit-text-decorations-in-effect: underline; "&gt;&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;&lt;/div&gt;&lt;div&gt;Si se sigue insistiendo con git, como una mera variante de svn, esto es lo q podria pasar (lo mas comun):&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Siendo usuario SVN, leer guia "Git para usuarios de Subversion"&lt;/li&gt;&lt;li&gt;Pasar meses de agonia mientras se maldice a git, a Linus Torvalds y al manager/PL/co-equiper/profesor que te hizo usarlo ya que es muy complicado al pedo ("¡lo unico que quiero hacer es commitear!", "¡mis cambios desaparecieron!", "¡el merge fallo y perdi todo!", y asi...)&lt;/li&gt;&lt;li&gt;Librarse de git de alguna manera y volver al placido y reconfortante svn (o cvs :( )&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;O si no, esto es mas raro que pase:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Siendo usuario SVN, leer guia "Git para usuarios de Subversion"&lt;/li&gt;&lt;li&gt;Pasar meses de agonia mientras se maldice a git, a Linus Torvalds y al manager/PL/co-equiper/profesor que te hizo usarlo ya que es muy complicado al pedo ("¡lo unico que quiero hacer es commitear!", "¡mis cambios desaparecieron!", "¡el merge fallo y perdi todo!", y asi...)&lt;/li&gt;&lt;li&gt;Aprender como funciona y hacer "cosas que con svn no hacia", explotar sus ventajas&lt;/li&gt;&lt;li&gt;Volverse "usuario git" al "entender como funciona" a costa de todo el sufrimiento previo&lt;/li&gt;&lt;li&gt;Optar por git como control de versiones preferido en todo al punto de creer que usar subversion en realidad un obstáculo&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;De todo esto se concluye que es muy difícil que alguna tabla de equivalencia de comandos o "mini-tutorial" sirva para que un usuario que esta cómodo con svn pueda trabajar igual de cómodo y feliz con git, o por lo menos que valga la pena el cambio, para eso un usuario debe volverse "usuario de git" antes de usarlo y/o en primeras etapas del uso de la herramienta.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span class="Apple-style-span"&gt;Que es ser un usuario de svn y que es ser un usuario de git (mindsets)&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;En esta seccion me voy a referir a un "usuario de svn" a alguien que usa svn desde hace mucho tiempo, y que esta comodo y feliz con la herramienta ya que tiene ese "&lt;i&gt;mindset&lt;/i&gt;". Lo mismo para un "usuario de git".&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;No obstante, la característica mas importante a analizar no es la herramienta, sino la manera de pensar las cosas, los conceptos y en ultima instancia como resuelve las situaciones del dia a dia con su herramienta favorita. Como esto no es "git evangelism", y el foco es estudiar como pasar de svn a git, sere lo mas objetivo posible&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Lo mas sencillo sera mostrar la siguiente tabla:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;table border="3" bordercolor="grey" width="500" cellpadding="4" style="table-layout:fixed"&gt; &lt;colgroup&gt;&lt;col width="75/"&gt;&lt;/colgroup&gt; &lt;colgroup&gt;&lt;col width="75/"&gt;&lt;/colgroup&gt; &lt;colgroup&gt;&lt;col width="75/"&gt;&lt;/colgroup&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Problema o concepto&lt;/td&gt;&lt;td&gt;Usuario de svn&lt;/td&gt;&lt;td&gt;Usuario de git&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Tengo código que quiero guardar,&lt;br /&gt;pero "no esta listo" para integrarlo&lt;br /&gt;al trunk por lo que no quiero&lt;br /&gt;commitearlo ¿Que hago?&lt;/td&gt;&lt;td&gt;"Facil: tengo tres opciones:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;copio el codigo, y lo pego en un notepad, &lt;/li&gt;&lt;li&gt;copio en el mismo archivo pero comentado&lt;/li&gt;&lt;li&gt;No hago nada, porque se que puedo volver atrás con ctrl+Z&lt;/li&gt;&lt;li&gt;crear un branch, pero preferiria que no"&lt;/li&gt;&lt;/ul&gt;&lt;/td&gt;&lt;td&gt;"Facil: puedo commitear ya que ese commit es local, o si no también puedo crear un branch"&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;br /&gt;Estoy trabajando en una feature nueva que todavia no commitie, y alguien me pide que resuelva un bug ¿que hago?&lt;/td&gt;&lt;td&gt;&lt;ul&gt;&lt;li&gt;GTFO, esperar hasta que termine la feature y haga el commit&lt;/li&gt;&lt;li&gt;Hacer checkout del mismo repo en otro directorio, arreglarlo ahi y commitearlo&lt;/li&gt;&lt;li&gt;Copiar el codigo a otro directorio, revertir la WC, arreglarlo ahi y copiarlo&lt;/li&gt;&lt;/ul&gt;&lt;/td&gt;&lt;td&gt;&lt;ul&gt;&lt;li&gt;Guardo un "stash", arreglo el bug, commit, push. restauro el stash&lt;/li&gt;&lt;li&gt;Hago un branch&lt;/li&gt;&lt;/ul&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;br /&gt;Tengo una funcionalidad a medio hacer sin commitear y me tengo que ir a mi casa, mis compañeros se quedan y podrian continuarla&lt;/td&gt;&lt;td&gt;&lt;ul&gt;&lt;li&gt;No commiteo, solo yo sigo mi trabajo mañana&lt;/li&gt;&lt;li&gt;commiteo aunque el trunk quede inestable&lt;/li&gt;&lt;li&gt;Les doy mi computadora&lt;/li&gt;&lt;li&gt;Hago un zip con el codigo y se los mando&lt;/li&gt;&lt;li&gt;Me quedo hasta que pueda commitear algo bueno&lt;/li&gt;&lt;/ul&gt;&lt;/td&gt;&lt;td&gt;&lt;ul&gt;&lt;li&gt;Commiteo (es local) y despues pusheo a un branch asi los demas pueden seguir trabajando en el&lt;/li&gt;&lt;/ul&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Dos o mas integrantes del equipo colaboraran en el desarrollo de un nueva feature, que tardara un mes&lt;/td&gt;&lt;td&gt;&lt;ul&gt;&lt;li&gt;Ahora si se justifica crear un branch&lt;/li&gt;&lt;li&gt;Pair-Programming y commitear cuando termine (no conviene)&lt;/li&gt;&lt;li&gt;Fragmentar en features mas pequeñas y commitear todos los días siempre y cuando "no rompan nada"&lt;/li&gt;&lt;/ul&gt;&lt;/td&gt;&lt;td&gt;&lt;ul&gt;&lt;li&gt;Definitivamente hay que crear un branch&lt;/li&gt;&lt;/ul&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Dos o mas integrantes del equipo colaboraran en el desarrollo de un nueva feature, que se completara en el dia&lt;/td&gt;&lt;td&gt;Pair-Programming y commit cuando se complete&lt;/td&gt;&lt;td&gt;Branch&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Commit&lt;/td&gt;&lt;td&gt;"Es la esencia de esto, hay que hacer update antes del commit para integrar los cambios del servidor"&lt;/td&gt;&lt;td&gt;"Puedo commitear cuando quiera independientemente de que ocurra en el 'servidor'"&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Branch&lt;/td&gt;&lt;td&gt;"Creare branches solo cuando sea estrictamente necesario (por ej: features que tardaran mucho mucho tiempo) o lo indique la gente de SCM"&lt;/td&gt;&lt;td&gt;"Lo mas importante es saber manipular branches, porque aparecen todo el tiempo si se trabaja de manera distribuida"&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Merge&lt;/td&gt;&lt;td&gt;"Pasa automatico cuando hago update pero hacer un merge manual es un quilombo y tarda, por eso no convienen los branches"&lt;/td&gt;&lt;td&gt;"Pasa automaticamente cada vez que hago un pull y hacerlo manual es trivial y rapido"&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Historia&lt;/td&gt;&lt;td&gt;"La historia se almacena en una secuencia de changesets, por eso cada revision tiene un numero, eso lo hace sencillo"&lt;/td&gt;&lt;td&gt;"La historia se almacena como un DAG (Arbol) de commits, entender eso es importante para comprender los branches"&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;El usuario de svn usa los sencillos comandos provistos por svn y varias herramientas mas como editores, IDE, compresores, mail, etc... para resolver los problemas del dia a dia, mientras que el usuario de git para resolver los mismos problemas diarios usa solamente git, que para ser justos, git en realidad es un filesystem mas un set muy extenso de herramientas sencillas, pero git como conjunto de herramientas es complejo, quiere ser lo suficientemente complejo y sofisticado para cubrir todas las necesidades y que no sean necesarios ni notepads, ni código com&lt;/span&gt;&lt;span class="Apple-style-span"&gt;entado, ni mails, ni ctrl-Z para manejar versiones de código.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Un usuario de git estara pensando todo el tiempo que hace control de versiones en branches, para el es fundamental saber como manipular branches (crear, mergear, etc...) ya que sabe que los branches se crean &lt;b&gt;todo el tiempo&lt;/b&gt; por trabajar de manera distribuida. Asumen el concepto de que es literalmente imposible trabajar sin branches en un equipo de desarrollo y por lo tanto no buscaran el imposible de "evitar branch a toda costa" sino solamente se dedicaran a controlar los branches que surgen para que no diverjan demasiado.&lt;/div&gt;&lt;/span&gt;&lt;span class="Apple-style-span"&gt;&lt;/span&gt;&lt;span class="Apple-style-span"&gt;&lt;div&gt;Consideran que todas las versiones son parte de un arbol que muestra la divergencia.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Un usuario de svn se enfoca principalmente en la "linea principal" y pensara en branches solo si surgen ciertas situaciones puntuales como por ej una feature que tardara demasiado tiempo (que en general es mejor evitar) o una version alterna del producto a medida. Asumen que la creación de branches siempre conlleva un overhead que en muchos casos solo sirven para complicar mas las cosas, muchos usuarios svn concuerdan en que si un branch va a durar mucho tiempo (digamos semanas) y se justifica podria aceptarse si el beneficio que se presume traera el branch supera ese overhead. Asi mismo cuando un branch se extiende en el tiempo y diverge mucho la integracion a la linea principal se vuelve mas complicada por lo que la integracion de esos "branches mounstruosos" es algo que no se busca (true story).&lt;/div&gt;&lt;div&gt;No consideran que la diferencia entre su &lt;i&gt;working copy &lt;/i&gt;y lo que hay en el servidor sea un branch por que commitear y updatear es mucho mas facil que manipular branches.&lt;/div&gt;&lt;div&gt;Ven las versiones del repositorio como algo lineal&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span class="Apple-style-span"&gt;¿ Que pasa cuando hay que usar una herramienta "diferente" ?&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Si un usuario svn, pasa a usar git con la consigna "reemplazo svn con git en mi set de herramientas", se encontrara que la complejidad de git, que es mayor que la de svn, sumada a la complejidad de las herramientas que esta acostumbrado a usar (bloc  de notas, mails, etc...) se convertira en una molestia y no podría trabajar bien. Mientras que un usuario habituado a git, usa git para una mayor cantidad de cosas aprovechando al maximo posible las posibilidades de la herramienta (que son la cara buena de esas complejidades) y no permitiendo que surja necesidad de usar algo adicional, asi es como muchos se maravillan con git mientras otros no entienden porque si git es tan complicado.&lt;/div&gt;&lt;div&gt;Por ejemplo, a un usuario svn generalmente no se le ocurriría crear branches de corta duracion, porque tiene la idea de que son complicados y no valen la pena, ahi habria una ventaja que no se aprovecharía (mientras que lidear con muchas de las cosas complicadas esta implícito en el uso dirio). A alguien habituado con svn tambien le causaria mucha confusion el hacer un &lt;i&gt;git pull&lt;/i&gt; y que el merge automatico no funcione, que se haya arrepentido o lo que sea ya que lo que hay en  git no puede ser visualizado con un modelo lineal.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;img src="http://3.bp.blogspot.com/-6LoVk8eygVs/TuDvt7vlnwI/AAAAAAAAATY/MsJ8faymzFA/s200/svngit.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5683806302152007426" style="float: left; margin-top: 0px; margin-right: 10px; margin-bottom: 10px; margin-left: 0px; cursor: pointer; width: 200px; height: 200px; " /&gt;&lt;div&gt;También es complicado para un usuario de git trabajar con svn, ya que tiene la costumbre de manejar el versionado de código solamente con una herramienta, se encontrara con que en svn los branches cortos no valen la pena y que hay muchas herramientas que faltan en comparación con git al que esta habituado y como esta acostumbrado a usar git todo el tiempo casi no conoce de herramientas "extras" y trabajar con svn le seria dificil. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Por eso el &lt;b&gt;&lt;a href="http://knowyourmeme.com/memes/philosoraptor"&gt;philosoraptor&lt;/a&gt;  &lt;/b&gt;de la imagen se pregunta porque no existen manuales de svn para usuarios de git (mas bien seria manuales de las herramientas adicionales que hacen falta para complementar svn) si existen manuales de git para usuarios de svn.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/span&gt;&lt;span class="Apple-style-span"&gt;&lt;b&gt;Conclusión&lt;/b&gt;&lt;/span&gt;&lt;span class="Apple-style-span"&gt;&lt;b&gt;&lt;span class="Apple-style-span"&gt;, como pasar de svn a git&lt;/span&gt;&lt;/b&gt;&lt;div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Comprender que con git las cosas se hacen diferente, que hacerlas "a la vieja usanza" es mas complicado que con la herramienta de siempre&lt;/li&gt;&lt;li&gt;Abordar git de cara a las ventajas (ej: branching, merging, distribuido, forks, staging area, versionado local, etc...)&lt;/li&gt;&lt;li&gt;Cambiar la manera de hacer las cosas, para aprovechar funcionalidades de git (no pensar, tal funcionalidad no la uso porque así no hago las cosas, cambiar la manera de hacer las cosas)&lt;/li&gt;&lt;li&gt;Pensar "out of the box", estar listo para cambiar las estructuras de pensamiento mas elementales&lt;/li&gt;&lt;li&gt;Al enfrentarse a complejidades adicionales que no había en svn, buscar comprender porque es asi, como eso se relaciona con ventajas de la herramienta y como aprovechar esas ventajas&lt;/li&gt;&lt;li&gt;Ver las versiones como un arbol y manipularlas de esa forma. NO tratar de que las cosas funcionen como en svn (por ej: no pretender que git pull funcione como svn update porque &lt;b&gt;son cosas diferentes&lt;/b&gt;)&lt;/li&gt;&lt;li&gt;Invertir tiempo, mucha gente que usa git dice que lo vale. No existe una manera rápida de aprender git pero el aprenderlo vale la pena&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Links&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Libro GitMagic: &lt;a href="http://www-cs-students.stanford.edu/~blynn/gitmagic/intl/es/book.pdf"&gt;http://www-cs-students.stanford.edu/~blynn/gitmagic/intl/es/book.pdf&lt;/a&gt;&lt;/div&gt;&lt;div&gt;Libro ProGit: &lt;a href="http://progit.org/"&gt;http://progit.org/&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;Blog GitEvangelism: &lt;a href="http://gitevangelism.blogspot.com/"&gt;http://gitevangelism.blogspot.com/&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;Generador de memes: &lt;a href="http://memegenerator.net/"&gt;http://memegenerator.net/&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-2885933959003662982?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/2885933959003662982/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=2885933959003662982' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/2885933959003662982'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/2885933959003662982'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2011/12/git-para-usuarios-de-subversion.html' title='Git para usuarios de Subversion'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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/-5B9FpowzcJg/TuDyZaQmJ0I/AAAAAAAAATw/mNRINxvzlqc/s72-c/everywhere.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1354794578842586233.post-8132221785351530454</id><published>2011-11-30T11:17:00.005-03:00</published><updated>2011-12-01T15:36:28.172-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='bash'/><category scheme='http://www.blogger.com/atom/ns#' term='rvm'/><title type='text'>¿Que version de ruby esta seleccionada con RVM?</title><content type='html'>&lt;a href="http://1.bp.blogspot.com/-JiBDd38WEoo/TtY7CMFojWI/AAAAAAAAATA/D-Zyf4glwqw/s1600/Selecci%25C3%25B3n_138.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 400px; height: 206px;" src="http://1.bp.blogspot.com/-JiBDd38WEoo/TtY7CMFojWI/AAAAAAAAATA/D-Zyf4glwqw/s400/Selecci%25C3%25B3n_138.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5680792888765091170" /&gt;&lt;/a&gt;&lt;b&gt;RVM&lt;/b&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://beginrescueend.com/rvm/"&gt;RVM&lt;/a&gt; es una herramienta impresionante que permite entre muchas otras cosas switchear de versiones de ruby o &lt;i&gt;gemsets&lt;/i&gt; con simples comandos ahorrandonos lo que seria un "configuration hell" cada vez que querriamos cambiar la version de ruby (no se puede andar instalando y desinstalando ruby todos los dias)&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;El que hace un uso intensivo de RVM con múltiples versiones de ruby/gemsets sabra que averiguar la version@gemset activada en un momento dado requiere correr el comndo &lt;i&gt;rvm current&lt;/i&gt;, esto podria ser tedioso si se abren multiples tabs y se quiere saber en un vistazo cual es la version de ruby activada y en primera instancia se puede recurrir a cambiar los titulos de los tabs, pero hay otra cosa adicional que se puede hacer&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Poner la version de ruby en el prompt&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Cambiar el &lt;a href="http://tldp.org/HOWTO/Bash-Prompt-HOWTO/x264.html"&gt;COMMAND_PROMPT&lt;/a&gt; en .bashrc o .bash_profile para que muestre en todo momento la version de ruby activada (ver screenshot), &lt;a href="http://mipagina.euskaltel.es/iosus/linux/Bash-Prompt-HOWTO-5.html"&gt;incluso se pueden usar colores y poner lo que sea&lt;/a&gt;, aca va un ejemplo de la linea que yo agregue al final de mi .bashrc para que el prompt salga como en la imagen:&lt;/div&gt;&lt;pre&gt;PROMPT_COMMAND="echo -n -e '\033[1;31m'\$(rvm current) '\033[0;37m'-\ "&lt;br /&gt;&lt;/pre&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Y de aca puede haber un montón de derivaciones, como por ej poner &lt;i&gt;ruby -v&lt;/i&gt; en lugar de &lt;i&gt;rvm current&lt;/i&gt; o incluso algunos lo usan para mostrar a que host están conectados por ssh&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Actualizacion&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;Una versión mejorada del comando podría ser agregar algún texto diciendo que es rvm al principio y al final en lugar de poner un comando ANSI para retornar al color gris claro específicamente, usar el color "default" que es el color del texto que sale en la terminal (que esta sujeto a la configuración de la terminal y no necesariamente sera gris claro)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;pre&gt;PROMPT_COMMAND="echo -n -e '\033[1;31m'&lt;b&gt;rvm: &lt;/b&gt;\$(rvm current) &lt;b&gt;'\033[0m'&lt;/b&gt;-\ "&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;div&gt;&lt;b&gt;Links&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Secuencias de escape ANSI: &lt;a href="http://mipagina.euskaltel.es/iosus/linux/Bash-Prompt-HOWTO-5.html"&gt;http://mipagina.euskaltel.es/iosus/linux/Bash-Prompt-HOWTO-5.html&lt;/a&gt;&lt;/div&gt;&lt;div&gt;PROMPT_COMMAND: &lt;a href="http://tldp.org/HOWTO/Bash-Prompt-HOWTO/x264.html"&gt;http://tldp.org/HOWTO/Bash-Prompt-HOWTO/x264.html&lt;/a&gt;&lt;/div&gt;&lt;div&gt;Sitio oficial de RVM: &lt;a href="http://beginrescueend.com/rvm/"&gt;http://beginrescueend.com/rvm/&lt;/a&gt;&lt;/div&gt;&lt;div&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/1354794578842586233-8132221785351530454?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/8132221785351530454/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=8132221785351530454' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/8132221785351530454'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/8132221785351530454'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2011/11/que-version-de-ruby-esta-seleccionada.html' title='¿Que version de ruby esta seleccionada con RVM?'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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/-JiBDd38WEoo/TtY7CMFojWI/AAAAAAAAATA/D-Zyf4glwqw/s72-c/Selecci%25C3%25B3n_138.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1354794578842586233.post-6835865922692882580</id><published>2011-11-29T12:25:00.009-03:00</published><updated>2011-11-29T13:04:28.240-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><category scheme='http://www.blogger.com/atom/ns#' term='rvm'/><category scheme='http://www.blogger.com/atom/ns#' term='bundle'/><category scheme='http://www.blogger.com/atom/ns#' term='environment'/><title type='text'>¿RVM + bundler es un problema? NO (Solucion)</title><content type='html'>Estoy armando un entorno para desarrollo con rails, y rvm... el como instalar rvm se puede ver en un montón de sitios, empezando por el sitio oficial &lt;a href="http://beginrescueend.com/rvm/install/"&gt;http://beginrescueend.com/rvm/install/&lt;/a&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;En resumen, con RVM instalado, tiro esta secuencia de comando&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: monospace; font-size: 13px; white-space: pre; "&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, serif; font-size: 16px; white-space: normal; "&gt;&lt;div&gt;el primero para instalar ruby 1.9.2:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/span&gt;sudo rvm install 1.9.2&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Despues, si todo salio bien, hay que switchear a esa version de ruby&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: monospace; font-size: 13px; white-space: pre; "&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: monospace; font-size: 13px; white-space: pre; "&gt;rvm use 1.9.2&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Instalar la gem rails&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;pre&gt;gem install rails&lt;br /&gt;&lt;/pre&gt;&lt;div&gt;Hasta ahi todo bien, pero al intentar generar un aplicacion con rails asi:&lt;/div&gt;&lt;pre&gt;rails new testapp&lt;br /&gt;&lt;/pre&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;Algo no funciona...&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;&lt;b&gt;El Problema&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Veran que bundle se cuelga &lt;a href="https://github.com/carlhuda/bundler/issues/703"&gt;"indefinidame&lt;/a&gt;&lt;/div&gt;&lt;img src="http://2.bp.blogspot.com/-BSKm1CzAI1U/TtT9Ob-uOsI/AAAAAAAAASo/FYTt7YjssRk/s400/Selecci%25C3%25B3n_135.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5680443454491867842" style="float: right; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 10px; cursor: pointer; width: 400px; height: 160px; " /&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 238); "&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 0); "&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 238); -webkit-text-decorations-in-effect: underline; "&gt;&lt;img src="http://2.bp.blogspot.com/-uxw5fByPy_0/TtT9ZnKNmTI/AAAAAAAAAS0/sBV3segqPaI/s400/Selecci%25C3%25B3n_136.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5680443646471412018" style="float: right; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 10px; cursor: pointer; width: 400px; height: 165px; " /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;div&gt;&lt;a href="https://github.com/carlhuda/bundler/issues/703"&gt;nte"&lt;/a&gt; y mientras ruby podria llevarse una porción apreciable de CPU (yo por mi parte espere varios minutos y lo único que obtuve fue perder un núcleo durante ese tiempo y el comando no se completo). Si bien en muchos lugares se explica que esperando un rato largo (10 o 15 minutos) el comando se completa, no es muy tolerable para lo que es el "desarrollo rapido" con RoR.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;&lt;b&gt;La Solucion&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Buscando por la web, me encontré con &lt;a href="http://robots.thoughtbot.com/post/2729333530/fetching-source-index-for-http-rubygems-org"&gt;este articulo&lt;/a&gt;, que explica cual es el problema y da una posible solución (que al menos funciono en mi caso). Básicamente explica que el problema tiene que ver con rubygems, no con bundler.&lt;/div&gt;&lt;div&gt;Lo que hay que hacer es asegurarse de que el cache de gems esta generado, esto se hace corriendo el comando &lt;b&gt;bundle pack&lt;/b&gt;, como dice la explicación que extraje de la pagina:&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(51, 51, 51); font-family: 'Times New Roman'; line-height: 16px; background-color: rgb(255, 255, 255); font-size: medium; "&gt;&lt;h2 style="margin-top: 20px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; font-size: 14px; font: normal normal 700 14px/21px proxima-nova-1, proxima-nova-2, 'Helvetica Neue', Helvetica, sans-serif; vertical-align: baseline; color: rgb(17, 17, 17); text-transform: uppercase; "&gt;WHAT YOU CAN DO&lt;/h2&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; font-size: 15px; font: normal normal 400 15px/24px proxima-nova-1, proxima-nova-2, 'Helvetica Neue', Helvetica, sans-serif; vertical-align: baseline; "&gt;So it’s still slow. My general advice is to:&lt;/p&gt;&lt;ul style="margin-top: 0px; margin-right: 0px; margin-bottom: 16px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; font-size: 16px; font: inherit; vertical-align: baseline; list-style-type: none; list-style-position: initial; list-style-image: initial; "&gt;&lt;li style="margin-top: 0px; margin-right: 0px; margin-bottom: 4px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; font-size: 15px; font: normal normal 400 15px/24px proxima-nova-1, proxima-nova-2, 'Helvetica Neue', Helvetica, sans-serif; vertical-align: baseline; position: relative; "&gt;Check in your &lt;code style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; font-size: 12px; font: normal normal normal 12px/18px monaco, monospace; vertical-align: baseline; white-space: pre; "&gt;vendor/cache&lt;/code&gt; directory with your .gem files. If &lt;code style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; font-size: 12px; font: normal normal normal 12px/18px monaco, monospace; vertical-align: baseline; white-space: pre; "&gt;bundle install&lt;/code&gt; doesn’t make one, force it with &lt;code style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; font-size: 12px; font: normal normal normal 12px/18px monaco, monospace; vertical-align: baseline; white-space: pre; "&gt;bundle pack&lt;/code&gt;.&lt;/li&gt;&lt;li style="margin-top: 0px; margin-right: 0px; margin-bottom: 4px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; font-size: 15px; font: normal normal 400 15px/24px proxima-nova-1, proxima-nova-2, 'Helvetica Neue', Helvetica, sans-serif; vertical-align: baseline; position: relative; "&gt;On new installs, CI runs, and deploys, use &lt;code style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; font-size: 12px; font: normal normal normal 12px/18px monaco, monospace; vertical-align: baseline; white-space: pre; "&gt;bundle --local&lt;/code&gt; which will attempt to resolve using only &lt;code style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; font-size: 12px; font: normal normal normal 12px/18px monaco, monospace; vertical-align: baseline; white-space: pre; "&gt;vendor/cache&lt;/code&gt;&lt;/li&gt;&lt;li style="margin-top: 0px; margin-right: 0px; margin-bottom: 4px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; font-size: 15px; font: normal normal 400 15px/24px proxima-nova-1, proxima-nova-2, 'Helvetica Neue', Helvetica, sans-serif; vertical-align: baseline; position: relative; "&gt;Lock down to specific versions (or use the &lt;a href="http://robots.thoughtbot.com/post/2508037841/twiddle-wakka" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; font-size: 15px; font: inherit; vertical-align: baseline; color: rgb(173, 20, 30); font-weight: 700; text-decoration: none; "&gt;twiddle-wakka&lt;/a&gt;) in your Gemfile&lt;/li&gt;&lt;/ul&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;Y despues deberia tardar mucho menos en ejecutarse&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span class="Apple-style-span"&gt;Workaround&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Si por casualidad la solución que les di no funciona pueden aplicar el workaround de crear la aplicación con rails usando la opcion &lt;i&gt;--skip-bundle:&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;&lt;div&gt;Recuerden que esto causa que las gems básicas de la aplicación no se instalen, por lo que tendrán que instalarlas a mano, para eso hay que ver el archivo Gemfile que esta en el directorio raíz de la aplicacion recién creada e instalar las gemas que figuran ahí con el comando gem.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Y después si usan gemas nuevas que no se especifican por default no olviden agregarlas al Gemfile igual ya que es muy útil por si quieren deployar la app a &lt;a href="http://www.heroku.com/"&gt;heroku&lt;/a&gt; después o simplemente para que las dependencias estén explicitas. Recuerden que después se puede correr el comando "bundle install" a mano en cualquier momento.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span class="Apple-style-span"&gt;Links&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;La fuente en donde conseguí la solución:  &lt;a href="http://robots.thoughtbot.com/post/2729333530/fetching-source-index-for-http-rubygems-org"&gt;http://robots.thoughtbot.com/post/2729333530/fetching-source-index-for-http-rubygems-org&lt;/a&gt;&lt;/div&gt;&lt;div&gt;Pagina oficial de RVM: &lt;a href="http://beginrescueend.com/rvm/"&gt;http://beginrescueend.com/rvm/&lt;/a&gt;&lt;/div&gt;&lt;div&gt;Explicación de como instalar RVM: &lt;a href="http://beginrescueend.com/rvm/install/"&gt;http://beginrescueend.com/rvm/install/&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&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/1354794578842586233-6835865922692882580?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/6835865922692882580/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=6835865922692882580' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/6835865922692882580'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/6835865922692882580'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2011/11/rvm-bundler-es-un-problema-no-solucion.html' title='¿RVM + bundler es un problema? NO (Solucion)'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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/-BSKm1CzAI1U/TtT9Ob-uOsI/AAAAAAAAASo/FYTt7YjssRk/s72-c/Selecci%25C3%25B3n_135.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1354794578842586233.post-1306044663847909495</id><published>2011-11-11T10:03:00.027-03:00</published><updated>2011-11-11T16:13:23.630-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='argentina'/><category scheme='http://www.blogger.com/atom/ns#' term='rubyconf'/><title type='text'>Rubyconf Argentina 2011</title><content type='html'>&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="-webkit-text-decorations-in-effect: underline; "&gt;&lt;img src="http://rubyconfargentina.org/images/event_the_event.png" border="0" alt="" style="float: right; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 10px; cursor: pointer; width: 258px; height: 193px; " /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div&gt;No podía dejar de ir a &lt;a href="http://rubyconfargentina.org/"&gt;este evento&lt;/a&gt;,  no voy a contar todo lo que vi porque el post se volveria demasiado extenso, pero voy a incluir las cosas que mas me impactaron.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Ruby Fun Day&lt;/b&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Asi llamaron a la previa que organizaron para dos dias antes de evento. Estuvo muy bien pensado y realmente cumplio lo que decia el titulo &lt;b&gt;Ruby-Fun-Day&lt;/b&gt;, en un principio no estaba seguro de ir pero mas tarde me di cuenta de que si no hubiera ido me hubiera arrepentido.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;El RubyFunDay lo organizaron para los que querian iniciarse en el mundo de ruby y no anden tan desorientados en las charlas (el plato fuerte) pero para los que tienen cancha también estuvo muy bueno porque dio la oportunidad para conocer gente copada, actualizarse y por ahí otras actividades relativas a agile.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Ese dia aproveche la jornada para aprender de rails y &lt;a href="http://dariotest.heroku.com/oradores"&gt;heroku&lt;/a&gt; que los tenia un poco olvidados en un taller dictado por &lt;a href="http://twitter.com/#!/bendycode"&gt;@bendycode&lt;/a&gt; (Stephen Anderson).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Vean el sitio de &lt;a href="http://tryruby.org/"&gt;tryruby&lt;/a&gt; recargado con dibujitos del libro Poignant Guide de Why, es impresionante y una forma muy copada de aprender el lenguaje ruby&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Ruby, Ruby, Ruby, Ruby,  POO OO OO, la cancion de ruby&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Desde el martes, el primer dia de la conferencia, escuche la canción. La deje de ringtone en mi telefono, es muy pegadiza:&lt;/div&gt;&lt;br /&gt;&lt;iframe class="youtube-player" type="text/html" width="480" height="288" src="http://www.youtube.com/embed/qObzgUfCl28" frameborder="0"&gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;br&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;div style="font-weight: normal; "&gt;&lt;b&gt;El presente de ruby es 1.9&lt;/b&gt;&lt;/div&gt;&lt;div style="font-weight: normal; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://twitter.com/#!/yhara_en"&gt;Yutaka Hara&lt;/a&gt; dio la &lt;a href="http://ht.ly/7nOL7"&gt;charla llamada "Pasado, Presente y Futuro de Ruby"&lt;/a&gt;, básicamente la lección que mas me quedo es que hay que migrar todo a ruby 1.9, porque &lt;b style="font-weight: normal; "&gt;ruby 1.8 es el pasado, &lt;/b&gt;basta hacer unos simples benchmarks para ver que ruby 1.9 es mucho mas rápido que su antecesor sin contar otras mejoras como ligeros improvements en la sintaxis del lenguaje, inclusión "out-of-the-box" de rubygems y un sin numero de otras cosas (talvez en la &lt;a href="http://www.ruby-lang.org/es/" style="font-weight: normal; "&gt;pagina oficial de ruby&lt;/a&gt; se encontrara información detallada)&lt;/div&gt;&lt;div&gt;En un momento de la charla &lt;a href="http://twitter.com/#!/yhara_en"&gt;@yhara&lt;/a&gt; pregunto quien usa Ruby 1.8 y a mi me llego a dar un poco de vergüenza levantar la mano&lt;/div&gt;&lt;div style="font-weight: normal; "&gt;Mientras que ruby 1.9 esta muy bueno, siempre tuvo una cosa que no me gusto que es la falta de compatibilidad hacia atrás (igual esto seguramente tiene justificación relacionada con las impresionantes mejores que trae), esta característica hace que la migración a 1.9 sea difícil, no tanto por las aplicaciones hechas por uno mismo, sino por las dependencias ya que no todas las gemas funcionan con ruby 1.9.&lt;/div&gt;&lt;div style="font-weight: normal; "&gt;Esto no me detendrá para migrar y la respuesta al problema de las dependencias no soportadas en ruby 1.9 es forkear las dependencias, en la gran mayoria de los casos la gema que no anda con ruby 1.9 es solo por un par de lineas que usan sintaxis no soportada por ruby 1.9, lo unico que hay que hacer para que funcione es arreglar esas lineas y listo, pero eso es un tema para otro post...&lt;/div&gt;&lt;div style="font-weight: normal; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-weight: normal; "&gt;Links:&lt;/div&gt;&lt;div style="font-weight: normal; "&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal; "&gt;&lt;div&gt;Slides de la charla que dio &lt;a href="http://twitter.com/#!/yhara_en"&gt;@yhara_en:&lt;/a&gt; &lt;a href="http://ht.ly/7nOL7"&gt;http://ht.ly/7nOL7&lt;/a&gt;&lt;/div&gt;&lt;/span&gt;&lt;/b&gt;Notas acerca de que voy a hacer para migrar proyectos: &lt;a href="http://tario-project.blogspot.com/2011/11/migrating-everthing-to-ruby19.html"&gt;http://tario-project.blogspot.com/2011/11/migrating-everthing-to-ruby19.html&lt;/a&gt;&lt;/div&gt;&lt;div style="font-weight: normal; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Cuba Web Micro Framework&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;En una espacio que organizaron para "Ligthing Talks" una de las charlas que dieron me llamo bastante la atención, Cuba es un framework mas minimalista que sinatra, vale la pena probarlo, me preguntaria como seria factible deployar eso a heroku&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;b&gt;Actualizacion: &lt;/b&gt;el usuario &lt;a href="http://www.blogger.com/profile/02403838381437184964"&gt;maxidr&lt;/a&gt; aporto la info necesaria via comentarios en este post para deployar un app hecha con &lt;b&gt;cuba &lt;/b&gt;(o con cualquier framework basado en rack) a heroku sin mayor esfuerzo, pasense por &lt;a href="http://devcenter.heroku.com/articles/rack"&gt;http://devcenter.heroku.com/articles/rack&lt;/a&gt;&lt;span class="Apple-style-span" style="color: rgb(51, 51, 51); font-family: 'Trebuchet MS', Verdana, Arial, sans-serif; line-height: 18px; background-color: rgb(255, 255, 255); font-size: small; "&gt; &lt;/span&gt;para mas info&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Ahora, por ejemplo, asi es una aplicacion &lt;b&gt;con tests incluidos:&lt;/b&gt;&lt;/div&gt;&lt;pre name="code" class="ruby"&gt;# cat hello_world.rb&lt;br /&gt;require "cuba"&lt;br /&gt;&lt;br /&gt;Cuba.use Rack::Session::Cookie&lt;br /&gt;&lt;br /&gt;Cuba.define do&lt;br /&gt; on get do&lt;br /&gt;   on "hello" do&lt;br /&gt;     res.write "Hello world!"&lt;br /&gt;   end&lt;br /&gt;&lt;br /&gt;   on true do&lt;br /&gt;     res.redirect "/hello"&lt;br /&gt;   end&lt;br /&gt; end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;# cat hello_world_test.rb&lt;br /&gt;require "cuba/test"&lt;br /&gt;&lt;br /&gt;scope do&lt;br /&gt; test "Homepage" do&lt;br /&gt;   visit "/"&lt;br /&gt;   assert has_content?("Hello world!")&lt;br /&gt; end&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Links:&lt;br /&gt;&lt;div&gt;&lt;a href="https://github.com/soveran/cuba"&gt;https://github.com/soveran/cuba&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://cuba.is/"&gt;http://cuba.is&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;¿Quien hace el mejor asado?&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Muy graciosa la charla, despues se puso algo mas serio y explico cosas bastante interesantes. &lt;a href="http://twitter.com/#!/tenderlove"&gt;@tenderlove&lt;/a&gt; (Aaron Patterson), ruby commiter y rails commiter, analizo porque el router (el componente de rails que decide a que controlador llamar, que acción y con que parametros de acuerdo a la url) actual es lento en muchos casos y explico como se metio en las tripas del algoritmo de regular expression para cambiar el orden del algoritmo de búsqueda de rutas que implica evaluar un mismo texto contra varias expresiones regulares.&lt;/div&gt;&lt;div&gt;El resultado de esa investigación fue &lt;a href="https://github.com/tenderlove/journey"&gt;Journey&lt;/a&gt;, un nuevo enrutador con un algoritmo mas optimo y por lo tanto mas rapido para mas cantidad de rutas. Este se integrara a rails seguramente para la version 3.2&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Links:&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.slideshare.net/tenderlove/rubyconf-argentina-2011"&gt;http://www.slideshare.net/tenderlove/rubyconf-argentina-2011&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="https://github.com/tenderlove/journey"&gt;https://github.com/tenderlove/journey&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;b&gt;Super Nario GC&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://twitter.com/#!/nari_en"&gt;Narihiro Nakamura&lt;/a&gt;, un commiter de MRI y un mago del Garbage Collection &lt;a href="http://www.slideshare.net/authorNari/parallel-worlds-of-crubys-gc-10108810"&gt;dio una charla acerca de Parallel Marking, una implementacion mas performante del GC de Ruby&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;Basicamente el GC de ruby corre en un solo thread mientras que ademas tiene que detener &lt;b&gt;todos&lt;/b&gt; los threads en ejecución hasta que finaliza el proceso de garbage collection, Parallel Marking en resumidas cuentas hace posible un garbage collection multi-thread con las consecuencias positivas en la performance que eso conlleva.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Para demostrar cuales fueron los resultados de su trabajo, Nari mostro ahi mismo el Super Mario GC que mostraba en pantalla estadisticas del GC e instanciaba objetos a proposito para provocar que se invoque el GC a cada rato.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;img src="http://2.bp.blogspot.com/-5wrjykQRoyA/Tr0nKQRZbLI/AAAAAAAAASA/qjqWuLT9sLA/s200/supenariogc.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5673734162676804786" style="float: left; margin-top: 0px; margin-right: 10px; margin-bottom: 10px; margin-left: 0px; cursor: pointer; width: 200px; height: 150px; " /&gt;&lt;div&gt;Cuando corrio el juego con su implementacion del GC las pausas ocasionadas por este casi no se veian ni se notaban, solo se podia apreciar por un texto en el medio de la pantalla que titilaba una fraccion de segundo cuando el GC se ponia a trabajar, sino no habia manera de saber que el GC estaba trabajando, despues cuando corrio exactamente lo mismo con el GC clasico las pausas pasaban a ser dolorosas para la dinamica del juego.&lt;/div&gt;&lt;div&gt;Nari explico que en la implementacion actual el 30% del CPU era invertido en el GC "Stop-the-world" y que la implementacion de Parallel marking ganaba un 40% de ese tiempo invertido, esto considerando que las pruebas las hizo con un procesador de dos nucleos, pero si se ejecutara en procesadores de 4 u 8 nucleos (que mas o menos es lo que tienden a salir los procesadores asi por estos tiempos) el tiempo invertido en GC seria mucho mucho menor&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Ojala que esa optimizacion se incorpore pronto.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;El Cuento de los Tres Arboles (en ingles TTT)&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://twitter.com/#!/CHACON"&gt;@chacon&lt;/a&gt; explica en detalle lo que pasa con el subcomando reset de git. Los que nunca usaron git quedaron :O porque sin contexto es muy difícil entender de que se estaba hablando, los que usan git a diario seguramente sacaron algo nuevo de la charla. Espero que mucha gente haya perdido el "miedo" al reset y aprendido que &lt;b&gt;reset --hard &lt;/b&gt;usualmente es una pesima idea.&lt;/div&gt;&lt;div&gt;Para aquellos experimentados en git (como yo, muahahahahhahaha) la charla no represento ninguna novedad en lo técnico pero fue una buena lección de como dar lecciones (con diagramas, dibujitos, comparaciones, etc...)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Github wants you&lt;/b&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Aparentemente github no descarta la busqueda de talentos mas alla de las fronteras de EEUU donde residen sus headquarters, incluso en lugares donde *actualmente* (por lo menos hasta donde yo se), github no tiene oficinas, porque un lema al que puso enfasis fue "work &lt;b&gt;where&lt;/b&gt; and when you want".&lt;/div&gt;&lt;div&gt;&lt;a href="http://twitter.com/#!/mojombo"&gt;@mojombo&lt;/a&gt;, Tom Preston-Werner (vendria a ser algo asi como el Batman de git con un logo de pulpo en lugar de murcielago) explico como empezaron github y con muchos estímulos visuales (talvez, creo yo, un poco exagerados) se dedico a convencernos de ir (vacaciones flexibles, seguro medico, ambiente distendido, esas cosas).&lt;/div&gt;&lt;div&gt;Yo, personalmente, no creo que github en ese sentido sea muy diferente a otras compañías, pero trabajar ahi seria muy interesante, por las cosas que hacen que es algo que todos lo ven desde la perspectiva de usuario de la plataforma o "superfan"&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Aca la deck de &lt;a href="http://twitter.com/#!/mojombo"&gt;@mojombo&lt;/a&gt;:&lt;/div&gt;&lt;div&gt;&lt;a href="http://speakerdeck.com/u/mojombo/p/optimizing-for-happiness"&gt;http://speakerdeck.com/u/mojombo/p/optimizing-for-happiness&lt;/a&gt;&lt;/div&gt;&lt;div&gt;Igualmente nada se comparara con haber visto esa presentacion en vivo&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Ruby hasta en el drinkup&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;img src="http://2.bp.blogspot.com/-XlHzIm9CAHE/Tr02n-BDjoI/AAAAAAAAASM/5lWR1oe8TiI/s200/rubyred.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5673751165846916738" style="float: right; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 10px; cursor: pointer; width: 200px; height: 150px; " /&gt;&lt;div&gt;Ni sabia que habia una bebida que se llamaba Ruby (el nombre completo es &lt;a href="http://images.google.com/search?q=Absolut+Ruby+Red"&gt;Absolute Ruby Red&lt;/a&gt;) , también vi un lambda el domingo cuando iba al RubyFunDay y la patente del taxi en el que volvi despues del drinkup decia "GEM"&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;RVM&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;No hubo una charla acerca de eso, pero hablando con otros rubystas durante la conferencia me di cuenta que tendría que probarlo. Al final lo instale y me di cuenta de que es una magnifica herramienta, sobre todo &lt;b&gt;imprescindible &lt;/b&gt;cuando se tiene que trabajar con múltiples versiones de ruby de manera comoda (ejemplo: buscar que una gem sea compatible con ruby 1.8 y ruby 1.9)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;Como nota final, talvez me este olvidando de algo, pero ya llego la hora de cortar el post... cualquier cosa seguramente habrá una segunda parte de este post si queda algo mas que decir.&lt;/div&gt;&lt;div&gt;&lt;br /&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/1354794578842586233-1306044663847909495?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/1306044663847909495/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=1306044663847909495' title='4 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/1306044663847909495'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/1306044663847909495'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2011/11/rubyconf-argentina-2011.html' title='Rubyconf Argentina 2011'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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://img.youtube.com/vi/qObzgUfCl28/default.jpg' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1354794578842586233.post-3897815862854647640</id><published>2011-10-15T18:43:00.029-03:00</published><updated>2011-10-19T12:26:21.403-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mug'/><category scheme='http://www.blogger.com/atom/ns#' term='git'/><category scheme='http://www.blogger.com/atom/ns#' term='codecamp'/><category scheme='http://www.blogger.com/atom/ns#' term='github'/><category scheme='http://www.blogger.com/atom/ns#' term='mono'/><category scheme='http://www.blogger.com/atom/ns#' term='xna'/><category scheme='http://www.blogger.com/atom/ns#' term='net'/><category scheme='http://www.blogger.com/atom/ns#' term='microsoft'/><title type='text'>¡concluyo CodeCamp 2011!</title><content type='html'>&lt;a href="http://4.bp.blogspot.com/-wtQxhrYUjw8/TpoUkTB69ZI/AAAAAAAAARI/q2ffqfvnYyw/s1600/codecamp.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 200px; height: 124px;" src="http://4.bp.blogspot.com/-wtQxhrYUjw8/TpoUkTB69ZI/AAAAAAAAARI/q2ffqfvnYyw/s200/codecamp.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5663862095187998098" /&gt;&lt;/a&gt;&lt;div&gt;Y me puse la camiseta para dar una charla de git, junto con mi colega &lt;a href="http://nicopaez.wordpress.com/"&gt;Nico Paez&lt;/a&gt;, quien obviamente no tardo en escribir &lt;a href="http://nicopaez.wordpress.com/2011/10/15/codecamp-2011/"&gt;este post acerca del tema&lt;/a&gt; (les recomiendo visitar el post ya que da acceso a interesantes recursos)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;&lt;span&gt;&lt;b&gt;&lt;font size=5&gt;La charla que di&lt;/font&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.codecamp.com.ar/sesiones/gestin-de-la-configuracin-con-nuget-y-git"&gt;Gestion de la configuracion con &lt;s&gt;nuget&lt;/s&gt; y Git&lt;/a&gt; (si, nuget tachado), la charla mas que nada empezo siendo iniciativa de Nico Paez quien se ve que la tiene muy clara en la oratoria sobretodo en lo didactico (enseña en la UBA) y se logro una exposicion muy copada, a pesar de que realmente no nos alcanzo el tiempo (esto mas bien significa que teniamos mucho para decir, y que sobre siempre es mejor a que falte ;) )&lt;/div&gt;&lt;img src="http://3.bp.blogspot.com/-KfJhR2C8zXg/TpoauLY-b4I/AAAAAAAAARU/-Bs7rup9PRQ/s200/smiles.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5663868862005669762" style="float: left; margin-top: 0px; margin-right: 10px; margin-bottom: 10px; margin-left: 0px; cursor: pointer; width: 200px; height: 150px; " /&gt;&lt;div&gt;Cabe aclarar que Nico posee profundos conocimientos de muchos otros temas (los que hicieron posible la presentación). Aun asi, sus conocimientos de git todavia no son suficientes para que pueda ver 100% de las ventajas que git ofrece y tuve que dar un empuje (push?) en ese sentido en etapas de preparacion de la presentacion.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A los planteos de "seguir el tema", lo mas probable es que escriba algunos cuantos post, con resumenes tecnicos y continuando lo que quedo pendiente de la charla y no pudo ser en el momento&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;div&gt;Por ultimo quiero felicitar a Nico Paez pues ha sido un gusto compartir esa actividad y tuvo mas aceptacion de lo que me imaginaba (vean los smiles en la foto). Ademas saque una enseñanza importante acerca de las presentaciones con diapositivas:&lt;/div&gt;&lt;div&gt;&lt;b&gt;NO hay que poner diapositivas llenas de texto&lt;/b&gt; porque distraen al publico de lo que el/los oradores dicen, hay que recurrir a graficos, o a titulo sencillos que indiquen de que se esta hablando, en ocasiones yo como publico tambien me distraje leyendo diapositivas con texto&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Links de la charla:&lt;/div&gt;&lt;div&gt;&lt;a href="http://nicopaez.wordpress.com/2011/03/01/github-quickstart/"&gt;Post en el blog de Nico con el quickstart de git&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;a href="http://www.box.net/shared/razq788khsey37qhvlni"&gt;Diapositivas usadas en la sesion&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;&lt;b&gt;&lt;font size=5&gt;Las charlas a las que fui&lt;/font&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Actualizacion:&lt;/b&gt; Ahora si funciona el sitio codecamp, talvez el dia de la jornada quedo saturado, ahi agregue los links&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;a href="http://www.codecamp.com.ar/sesiones/nodejs-html5-windows-azure-juegos-multiplayer-realtime-para-millones"&gt;Desarrolla con Node.js + HTML5 + Windows Azure juegos multiplayer realtime y seras millones&lt;/a&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;¿Que mas hay que decir? ¡Juegos multiplayer! ¡Sentencias/presagios de muerte para flash! ¡Java Lopez! De chico tenia el berretin de hacer jueguitos, despues los hice con QBasic (me siento viejo :S) , despues con VB, despues con Div Games Studio, pero estas historias son para otro post. Lo importante es que volver al mundo del desarrollo videojueguil con esta clase de tecnologias (HTML5 y demas yerbas) seria volver por una de las puertas grandes&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;a href="http://www.codecamp.com.ar/sesiones/mi-primer-juego-xna-para-wp7-y-xbox-360"&gt;Desarrollo de juegos con XNA para WP7 y XBOX&lt;/a&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Impresionante charla, queria saber en que estado estaba eso del XNA. Y por lo visto logran cosas muy copadas (con 3D y todo), pero para mi gusto demasiado exclusivo de plataformas microsoft, por el momento me inclinaria mas al HTML5 con javascript, o Java, algo que corra "en todos lados"&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;a href="http://www.codecamp.com.ar/sesiones/pasado-presente-y-futuro-de-c"&gt;C++, el fantasma de las natividades pasadas, presentes y futuras&lt;/a&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;El pasado lo conociamos casi todos (esta en los libros), el presente lo vi (y no me gusto), a mi y a la mayoria de los presentes en esa charla nos intrigo el futuro,&lt;/div&gt;&lt;div&gt;A mi me gusto la charla, me entere de cosas que no sabia que existian (¡C++ tiene lambdas!) y tambien de cosas del nuevo c++ que hay en windows 8, que no tiene garbage collector ni es managed (a cambio tiene la mega-performance y el bajo nivel) pero tiene reference counting integrado con el lenguaje, interaccion casi "magica" con cualquier otro lenguaje como por&lt;/div&gt;&lt;div&gt;ej javascript y seguro un monton de cosas mas que el tiempo no da para explicarlas todas en una sola charla.&lt;/div&gt;&lt;div&gt;No me gusto cierta parte del mensaje tanatico, si puede llamarselo asi, que anuncia que "todo estara en c++" (igual solo es una forma de decir), fuera de ese detalle la charla me gusto bastante y el c++ con todas las implementaciones a nivel IDE que agregaron ahora sera mas "soportable"&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;&lt;b&gt;&lt;font size=5&gt;Masas de desarrolladores, masas de chocolate&lt;/font&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Masividad de desarrolladores talentosos exponiendo ideas y/o curiosos en la cacería de&lt;/div&gt;&lt;div&gt;conocimiento&lt;/div&gt;&lt;div&gt;Masividad de azucar, masas y cafe masivo... la comida/bebida&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;img src="http://2.bp.blogspot.com/-s21xZ6oAy5w/TpoQkkRPWaI/AAAAAAAAAQ8/psyV91fkldw/s200/masas2.jpg" border="0" alt="" style="float: right; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 10px; cursor: pointer; width: 200px; height: 200px; " /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;ideal para las 24x7 de la mayoria de los informaticos, y que en realidad no llevan a la practica por falta de dinero/infraestructura hepatica capaz de procesar toneladas de glucosa diaria&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;Disclaimer: no llegue a sacarle fotos a las masas, pero eran del estilo de las que se ven en la foto y eran ricas&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;&lt;b&gt;&lt;font size=5&gt;Unicas Criticas&lt;/font&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A la tarde se acabo la azucar (o no se conseguia) para el cafe :(, lo perdono al considerarlo tambien una buena medida para controlar el consumo adictivo de glucosa (combinado con el sedentarismo tipico de la profesion IT puede llegar a ser dañina) y teniendo en cuenta de q las masas ya proveian la sobredosis necesaria de glucosa&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;No podia ir a las 10 charlas que habia en cada horario a la vez, si bien no eran todas taaaaan interesantes, habia horarios en los que era muy dificil decidir entre dos o tres sesiones interesantes que habian al mismo tiempo&lt;/div&gt;&lt;div&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/1354794578842586233-3897815862854647640?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/3897815862854647640/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=3897815862854647640' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/3897815862854647640'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/3897815862854647640'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2011/10/concluyo-codecamp-2011.html' title='¡concluyo CodeCamp 2011!'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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/-wtQxhrYUjw8/TpoUkTB69ZI/AAAAAAAAARI/q2ffqfvnYyw/s72-c/codecamp.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1354794578842586233.post-9188740388712974084</id><published>2011-09-14T11:58:00.012-03:00</published><updated>2011-09-16T09:57:22.788-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='antipattern'/><category scheme='http://www.blogger.com/atom/ns#' term='mercurial'/><category scheme='http://www.blogger.com/atom/ns#' term='git'/><category scheme='http://www.blogger.com/atom/ns#' term='cvs'/><category scheme='http://www.blogger.com/atom/ns#' term='zip'/><category scheme='http://www.blogger.com/atom/ns#' term='svn'/><title type='text'>Anti-Pattern legacy: making a zip in the era of DVCS</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://sourcemaking.com/files/sm/images/antipatterns/img_20.jpg"&gt;&lt;img style="float: right; margin: 0pt 0pt 10px 10px; cursor: pointer; width: 240px; height: 246px;" src="http://sourcemaking.com/files/sm/images/antipatterns/img_20.jpg" alt="" border="0" /&gt;&lt;/a&gt;Un &lt;a href="http://es.wikipedia.org/wiki/Antipatr%C3%B3n_de_dise%C3%B1o"&gt;anti-patrón&lt;/a&gt; es una solución repetitiva incorporada o aprendida para la cual se demostró que lejos de resultar una buena solución para un problema (como aparentaría en un principio) genera mas problemas que los que soluciona. &lt;div&gt;Mientras que el concepto se popularizo como &lt;i&gt;anti-patrón de diseño &lt;/i&gt;con orígenes en el libro &lt;a href="http://es.wikipedia.org/wiki/Design_Patterns"&gt;Design Patterns&lt;/a&gt;, el concepto de anti-patron se utiliza en variedad de escenarios como en la programación (ej: el infame &lt;a href="http://es.wikipedia.org/wiki/C%C3%B3digo_espagueti"&gt;Codigo spaghetti&lt;/a&gt;), project managament (ej: &lt;a href="http://en.wikipedia.org/wiki/Groupthink"&gt;Groupthink&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;&lt;b&gt;Anti-Patrones como Patrones Legacy&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;Algunos (¡y muchos!) anti-patrones como &lt;a href="http://en.wikipedia.org/wiki/Waterfall_model"&gt;Waterfall model&lt;/a&gt; (Desarrollo de software en cascada), son practicas o patrones generalmente aceptados y enseñados en viejas épocas y que ahora al quedar obsoletos fueron reemplazados por otras practicas mas eficaces (Desarrollo iterativo, metodologías agiles, etc...) . A pesar de eso viejas practicas quedan en el knowhow colectivo y lo importante es saber reconocerlos como &lt;b&gt;anti&lt;/b&gt;-patrones y no como una practica que haya que fomentar (y también saber cuales son las practicas que son convenientes por estos tiempos).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;&lt;b&gt;Anti-Patrones en Control de versiones&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Como se había mencionado anteriormente, el concepto de anti-patrón se extendió rápidamente a variedad de entornos, siendo uno de ellos el mundo de las versiones (o como algunos le dicen,  SCM), un área del desarrollo de software que crece mas lentamente que otras (el porque de esto seguramente lo tratare en algún que otro post). &lt;/div&gt;&lt;div&gt;A pesar de no haberse desarrollado mucho, SCM (o abreviado CM) fue un ciencia/brujería/técnica que paso por varias fases a lo largo de su historia pasando por herramientas que solo servían para trabajar individualmente, sistemas de control de versiones concurrentes para equipos (CVS :P), sistemas centralizados mas avanzados para dar mejor soporte a ramas aunque no sea lo suficientemente bueno (ej: &lt;a href="http://subversion.tigris.org/"&gt;SVN&lt;/a&gt;), sistemas distribuidos (ej: &lt;a href="http://mercurial.selenic.com/"&gt;Mercurial&lt;/a&gt;) (para información detallada vean este &lt;a href="http://codicesoftware-es.blogspot.com/2010/11/la-historia-del-control-de-versiones.html"&gt;excelente articulo&lt;/a&gt; acerca de la historia del source control).&lt;br /&gt;Esta historia es la que habilita la posibilidad de que determinadas buenas practicas muy comunes y que resultaban satisfactorias ayer sobrevivan mas allá de su obsoletización para convertirse en anti-patrones hoy.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Los Patches que se usaban antes&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Una de las practicas que fue muy utilizada durante un tiempo fueron los patches, sobretodo en los entornos de desarrollo open source, en épocas donde la internet estaba en pañales y cosas como &lt;a href="http://www.codeplex.com/"&gt;codeplex&lt;/a&gt;, &lt;a href="https://github.com/"&gt;github&lt;/a&gt;, &lt;a href="http://code.google.com/intl/es-ES/"&gt;googlecode&lt;/a&gt; no existían ni en la imaginación (es mas, muchas de esas compañías ni siquiera existían), cuando alguien realizaba una contribución a un proyecto lo que generalmente este hacia era generar un patch (que no es mas que un .tar.gz o &lt;b&gt;.zip&lt;/b&gt; del diff entre determinadas versiones y/o el contenido de esas versiones) y posteriormente se lo hacia llegar, era común mandarlos por email firmados, adjuntarlos en foros, BBS, etc... En definitiva, no existía el concepto de "commitear a un repo en la nube".&lt;br /&gt;&lt;br /&gt;&lt;b&gt;El "Make a zip" que se usa ahora&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Posteriormente exploto la internet, llegaron los servicios, se estabilizaron y herramientas como SVN pudieron cobrar mas protagonismo, yo por ejemplo usaba el servicio de &lt;a href="http://www.assembla.com/"&gt;http://www.assembla.com/&lt;/a&gt;, que por esos momentos ofrecia SVN (estamos hablando del 2006 aprox.). &lt;/div&gt;&lt;div&gt;Sin embargo, existía cierta "cosa" por la cual "commitear al repo" no era tan frecuente, estaba (y esta) vigente &lt;i&gt;Continuous Integration, &lt;/i&gt;una excelente herramienta para llevar a cabo proyectos integros aprovechando al máximo un versionador, pero que inadvertidamente dejaba varios asuntos de lado. &lt;/div&gt;&lt;div&gt;Uno de esos asuntos es el intercambio de código "unmanaged", es decir, código que no debería ser parte de la &lt;i&gt;mainline &lt;/i&gt;en ese momento, pero que lo seria en el futuro o que tiene que por diversas razones tiene que "estar en algún lugar".&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Noten que hasta el momento no use la palabra con &lt;a href="http://en.wikipedia.org/wiki/Branching_%28software%29"&gt;B&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Entonces, generalmente es fácil caer en este razonamiento: "Si ahora se esta usando un repositorio para compartir una mainline, y eso es fabuloso, entonces como envió el código que no tengo que commitear por H o por B razon ? &lt;b&gt;Uso lo que ya conozco, y hago un patch &lt;/b&gt;para poder enviar el contenido" ( o en otras palabras, hacer un zip ) lo cual parece que es algo &lt;i&gt;bueno &lt;/i&gt;porque era una practica normal y promovida en las viejas épocas, y al trabajar con sistemas de control de versiones &lt;b&gt;centralizado &lt;/b&gt;como el mas popular de esa generacion (svn) incluso yo creo que trabajar con codigo "unmanaged" de esa forma es mas practico que hacer branches la mayoria de las veces.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;b&gt;DVCS's y la palabra con &lt;a href="http://en.wikipedia.org/wiki/Branching_%28software%29"&gt;B&lt;/a&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Pero la practica de realizar patches, en DVCS's como Mercurial o Git solo existe como una practica legacy, un anti-pattern (aunque siempre habrá excepciones, pero deben ser las menos y muy poco frecuente). En herramientas distribuidas de versionamiento, las soluciones alternativas al problema del código "unmanaged" están a mano y es mas facilitada por la herramienta que ofrece alternativas mas practicas que el uso de patches, mails con código o archivos zip y por supuesto mas practicas que las soluciones ofrecidas por herramientas de generaciones anteriores. &lt;/div&gt;&lt;div&gt;Intercambiar código con otros desarrolladores solamente a travez del repositorio y usar otros métodos solo para los que por alguna razón no puedan, no deseen, o no sepan como acceder al repositorio.&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/1354794578842586233-9188740388712974084?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/9188740388712974084/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=9188740388712974084' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/9188740388712974084'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/9188740388712974084'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2011/09/anti-pattern-legacy-make-zip-dvcs.html' title='Anti-Pattern legacy: making a zip in the era of DVCS'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-3753626994480796097</id><published>2011-09-12T16:09:00.008-03:00</published><updated>2011-09-12T16:56:16.052-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scm'/><category scheme='http://www.blogger.com/atom/ns#' term='blogs'/><category scheme='http://www.blogger.com/atom/ns#' term='coworkers'/><category scheme='http://www.blogger.com/atom/ns#' term='blogging'/><title type='text'>Yet another blog?</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://6x.velneo.es/files/2008/10/question_mark3.jpg"&gt;&lt;img style="float: right; margin: 0pt 0pt 10px 10px; cursor: pointer; width: 228px; height: 239px;" src="http://6x.velneo.es/files/2008/10/question_mark3.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;div&gt;&lt;div class="msg 1st"&gt;&lt;div class="msg 1st"&gt;le preguntaba a un co-worker , &lt;a href="http://nicopaez.wordpress.com/"&gt;Nicolas Paez&lt;/a&gt; y &lt;a href="http://www.ajlopez.com/"&gt;Angel "Java" Lopez&lt;/a&gt;. si seria conveniente o no crear un blog nuevo para los articulos pendientes que tengo acerca de SCM (no centrado en git) y me di cuenta que la respuesta no es tan obvia como imaginaba en un principio.&lt;/div&gt;&lt;div class="msg 1st"&gt;Segun Nicolas es conveniente que tenga un solo blog unificado, esto suena bastante bien por una cuestion de simiplicidad y para poder dar una referencia de mi (ej. el blog de Dario Seminara) pero al imaginarlo me vi escribiendo varios articulos muy especificos de diferentes temas en el mismo blog. Por ej vean&lt;a href="http://tario-project.blogspot.com/2011/09/callcc-puzle-on-fastruby-ii-return-of-c.html"&gt; la detallada explicación de un problema tecnico de un proyecto particular&lt;/a&gt;, la&lt;a href="http://gitevangelism.blogspot.com/2011/07/branch-remotos-en-git-dos-pasos-y.html"&gt; explicación de como usar branches en git&lt;/a&gt; y un &lt;a href="http://nilclass.blogspot.com/2010/08/megapost-overview-de-herramientas-uml.html"&gt;resumen de herramientas UML online&lt;/a&gt;  ¿todos esos articulos caben en el mismo blog? ¿o mas bien lo mio solo es una impresion erronea?&lt;/div&gt;&lt;div class="msg 1st"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="msg 1st"&gt;Los temas acerca de lo que iba a escribir no caben en &lt;a href="http://gitevangelism.blogspot.com/2011/07/branch-remotos-en-git-dos-pasos-y.html"&gt;gitevangelism&lt;/a&gt; ya que tratan de alejarse de git mientras el titulo de aquel blog indica que contiene ayudas tecnicas de git (pretendo que cualquiera que entre a ese blog encuentre lo que el blog promete por titulo, ni mas ni menos)&lt;/div&gt;&lt;div class="msg 1st"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="msg 1st"&gt;Los nuevos articulos tampoco parecen ir muy bien en este blog (&lt;a href="http://gitevangelism.blogspot.com/2011/07/branch-remotos-en-git-dos-pasos-y.html"&gt;Nilclass&lt;/a&gt;) porque a pesar de que Nilclass haya quedado como el blog de "miscelaneas" estos temas son muy especificos, densos y analiticos. No es un post que uno quiera ver en el camino cuando busca lo "generico"&lt;br /&gt;&lt;/div&gt;&lt;div class="msg 1st"&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="msg 1st"&gt;Segun las propias palabras de Nico: &lt;b&gt;"Yo tengo un unico blog y escribo sobre distintas cosas, pues no tengo tantas  cosas para escribir", &lt;/b&gt;lo cual es algo que yo asocio a la estrategia de mantener un solo blog al ser pocas las cosas para escribir. Mientras, por mi parte, ahora estoy experimentando como explotar al máximo la comunicación mediante blogs. Buscando la manera de escribir todo lo que  sea escribible y publicable (tratando de seguir un ritmo similar al de&lt;a href="http://msmvps.com/blogs/lopez/"&gt; Java Lopez&lt;/a&gt;) y difundir aquellas ideas genéricas, que si bien es muy probable que fueran aplicables en un entorno real de trabajo, no conviene explicarlas en  una meeting/retrospective o en medio de un trabajo enfocado en lo concreto.&lt;/div&gt;&lt;div class="msg 1st"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="msg 1st"&gt;Un ejemplo de eso es este mismo post, que originalmente fue una conversacion en medio del trabajo y se convirtio en un post que podra ser leido por cualquiera en la web incluyendo obviamente tambien a las personas a la cuales me interesa que la informacion les llegue.&lt;/div&gt;&lt;/div&gt;&lt;div class="msg 1st"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="msg 1st"&gt;Todavia no decidi en que blog iba a escribir esos articulos pero aprendi muchas cosas acerca del mundo del blogging que resulto ser mas nuevo para mi de lo que creia en un principio&lt;br /&gt;&lt;/div&gt;&lt;div class="msg 1st"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="msg 1st"&gt;&lt;b&gt;&lt;span class="Apple-style-span"  style="font-size:130%;"&gt;Mis blogs&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="msg 1st"&gt;&lt;ul&gt;&lt;li&gt;NilClass: &lt;a href="http://nilclass.blogspot.com/"&gt;http://nilclass.blogspot.com/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Ruby y Miscelaneas&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Git Evangelism -  &lt;a href="http://gitevangelism.blogspot.com/"&gt;http://gitevangelism.blogspot.com/&lt;br /&gt;&lt;br /&gt;&lt;/a&gt;Blessed are those who use git for source control. Tips, tecnicismos, conceptos y explicaciones acerca de git&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Tario Projects -  &lt;a href="http://tario-project.blogspot.com/"&gt;http://tario-project.blogspot.com/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Blog for projects: Technical details about personal open source projects&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-3753626994480796097?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/3753626994480796097/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=3753626994480796097' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/3753626994480796097'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/3753626994480796097'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2011/09/yet-another-blog.html' title='Yet another blog?'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-4503524125585066976</id><published>2011-07-18T22:09:00.018-03:00</published><updated>2011-07-19T10:11:53.186-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mental'/><category scheme='http://www.blogger.com/atom/ns#' term='unit testing'/><category scheme='http://www.blogger.com/atom/ns#' term='tdd'/><category scheme='http://www.blogger.com/atom/ns#' term='memoria'/><title type='text'>La memoria y TDD: Refactor/test backlog &amp; Sleeping in Red</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.rethinkware.com/download/attachments/557483/tdd.JPG"&gt;&lt;img style="float: right; margin: 0pt 0pt 10px 10px; cursor: pointer; width: 266px; height: 165px;" src="http://www.rethinkware.com/download/attachments/557483/tdd.JPG" alt="" border="0" /&gt;&lt;/a&gt;Hace tanto tiempo que no escribo en este blog, y ahora vuelvo a escribir (sin razon aparente) para contarles unas impresiones acerca de como se me ocurre optimizar TDD en relacion con la memoria (humana), en esto cualquier comentario que puedan aportar no solo sera bienvenido sino que tambien muy apreciado&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Lo basico&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Bueno, para no dar mas vueltas voy directo al tema empezando por la basico (salteen este parrafo si saben basicamente en que consiste &lt;a href="http://es.wikipedia.org/wiki/TDD"&gt;TDD&lt;/a&gt;)&lt;br /&gt;TDD es una practica de programacion que basicamente consiste en escribir los tests primero y refactorear el codigo convenientemente, este proceso se ejecuta de manera iterativa pasando por tres fases en cada iteracion: rojo, verde y refactor. A grandes rasgos:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;La fase "roja" consiste en escribir tests que fallen expresando especificaciones de como las cosas deberian funcionar, antes de que se implementen&lt;br /&gt;&lt;/li&gt;&lt;li&gt;La fase "verde" consiste en buscar que esos tests pasen a toda costa, es  decir que "vale todo" de manera que el codigo se llena de chanchadas en  esta fase (lease codigo duplicado, harcodeos, variables globales y cualquiera de esas cosas feas que se ven en las pesadillas)&lt;/li&gt;&lt;li&gt;La fase de refactoring la cual hace mas lindo el codigo, limpiando todo lo que se ensucio en la fase verde anterior mientras  &lt;span style="font-weight: bold;"&gt;se mantenga el 100% de tests en verde&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Para mas informacion de TDD pueden ver el &lt;a href="http://es.wikipedia.org/wiki/TDD"&gt;articulo de la wikipedia&lt;/a&gt; o simplemente buscar en la web que esta lleno de blogs que explican cosas muy interesantes&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;¿Que tiene que ver la memoria con TDD?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;La memoria tiene que ver con todo, y en el caso especifico de TDD, la memoria del programador actua diferente de fase en fase (suponiendo que no use un soporte externo como voy a explicar mas adelante).&lt;br /&gt;&lt;ul&gt;&lt;li&gt;En la fase roja, que inicia el ciclo de TDD, la informacion que el desarrollador utiliza para  escribir los tests son las especificaciones (para reducirlas a especificaciones de componentes en el codigo, etc...). &lt;span style="font-weight: bold;"&gt;No se necesita ninguna informacion memorizada&lt;/span&gt; ya que las especificaciones vienen escritas (y si no, ya no es un asunto de TDD). Solo se requiere informacion extra para escribir casos "borde", caminos "no felices" o cualquier cosa que no este explicitamente en la especificacion.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;En la fase verde, se tiende a usar informacion que se escribe en los tests para hacerlos pasar, como por ejemplo nombre de clases, metodos u otra informacion &lt;span style="font-weight: bold;"&gt;que se escribio&lt;/span&gt; en los tests. Depende del caso, se suele utilizar mucho conocimiento del proyecto, pero por ahora eso no importa porque esa memoria esta mas alla del scope de un ciclo de TDD&lt;br /&gt;&lt;/li&gt;&lt;li&gt;En la fase de refactor, se utiliza informacion  &lt;span style="font-weight: bold;"&gt;que esta en el codigo &lt;/span&gt;(por ej, al observar metodos duplicados) e informacion producto de ideas, razonamientos, observaciones al codigo efectuadas en &lt;span style="font-weight: bold;"&gt;cualquier momento&lt;/span&gt;, ya que el codigo se esta observando &lt;span style="font-weight: bold;"&gt;siempre &lt;/span&gt;y hay que considerar que refactorear codigo para mejorar su calidad interna no es una tarea trivial (como si lo es hacer que los tests pasen) y requiere mas trabajo mental&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Las fase que mas informacion producida en el mismo ciclo y mas trabajo mental requiere es la de refactor, la fase verde requiere mas trabajo mental que la roja&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Refactor backlog&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;El que haya usado TDD, seguro se encontro en la situacion de duplicar cierto codigo para hacer que un test pase&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;teniendo en mente refactorizarlo &lt;span style="font-weight: bold;"&gt;despues&lt;/span&gt; (&lt;span style="font-weight: bold;"&gt;no en el momento)&lt;/span&gt;, no deberia memorizarse esa informacion ya que eso es proclive a olvidos y disminuye la concentracion en la tarea del momento, en lugar de eso es mejor usar un "backlog" (que seguramente no sera el mismo backlog agile, es algo distinto) o un "ToDo list" el cual se debe alimentar cada vez que se observe algo que deba ser refactoreado y que no corresponde hacerlo en ese momento&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;Test Backlog&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;Para aplicar el mismo&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;concepto&lt;span style="font-weight: bold;"&gt; &lt;/span&gt; que en el parrafo anterior, cada vez que miramos al codigo, se nos ocurre "¿y si llamara a tal metodo con tal argumento, fallaria?", lo mejor en ese caso sera escribir un test que pruebe eso. No suena muy practico interrumpir el trabajo para hacer pasar los tests o el trabajo de refactoring para escribir el nuevo test fallido en el momento, por eso es mejor anotar los test nuevos en algun lugar a medida que se van descubriendo e implementarlos mas tarde. En mi opinion, lo ideal es hacerlo al finalizar la fase verde o de refactor con todos los tests pasando (se considera que se vuelve a la fase roja)&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;Dormir en rojo&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;Todos&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;tenemos&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;que&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;descansar en algun momento, y el verdadero descanso consiste en distraccion total y si es posible completo &lt;span style="font-weight: bold;"&gt;olvido&lt;/span&gt; del trabajo (y si es posible irse a dormir :P). Eso implica que, al volver al trabajo, tratar de recordar informacion acerca de la tarea que se estaba realizando antes de interrumpirla para descansar, es significativamente mas costoso que recordar lo que se estaba haciendo hace pocos minutos o segundos (como en el caso del trabajo continuo).&lt;br /&gt;La fase que menos memoria reciente requiere (despues de la inicial) es la verde (la de hacer pasar los test), por eso si se va a interrumpir la tarea lo mas conveniente es hacerlo con todos los nuevos tests fallando (al terminar la fase roja) ya que si se hace antes del refactor al volver se tendra que recordar los items de refactor pendientes (a pesar de usar el backlog, este solo actua como un ayuda-memoria que hay que leer, no como una memoria auxiliar). La fase roja inicial requiere menos memoria reciente pero es mas trabajosa, usa informacion de las especificaciones y es mucho menos trivial por lo que aunque tambien sea util interrumpir antes de escribir los tests no es tan conveniente como pausar despues de escribirlos.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Conclusiones&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;Voy a asegurarme de escribir todos los test que pueda antes de interrumpir la tarea para descansar, y despues hacerlos pasar cuando vuelva a trabajar&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Voy a implementar un backlog/ToDo con items de refactor que voy a consultar cuando haga pasar todos los test&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Voy a implementar un backlog/ToDo con items de test (pero voy a ver si eso realmente es util o no)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Links&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;TDD en la wikipedia&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;: &lt;/span&gt;&lt;a href="http://es.wikipedia.org/wiki/TDD"&gt;&lt;span&gt;http://es.wikipedia.org/wiki/TDD&lt;/span&gt;&lt;/a&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-4503524125585066976?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/4503524125585066976/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=4503524125585066976' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/4503524125585066976'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/4503524125585066976'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2011/07/la-memoria-y-tdd-refactortest-backlog.html' title='La memoria y TDD: Refactor/test backlog &amp; Sleeping in Red'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-4190937342391678594</id><published>2011-03-13T21:36:00.005-03:00</published><updated>2011-03-13T21:52:23.434-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='blog'/><category scheme='http://www.blogger.com/atom/ns#' term='github'/><category scheme='http://www.blogger.com/atom/ns#' term='tario'/><title type='text'>El blog para los proyectos</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-3qxk84cSPuo/TX1lIc7VDdI/AAAAAAAAAI8/R6p254HK6H0/s1600/blog.png"&gt;&lt;img style="float: right; margin: 0pt 0pt 10px 10px; cursor: pointer; width: 320px; height: 191px;" src="http://2.bp.blogspot.com/-3qxk84cSPuo/TX1lIc7VDdI/AAAAAAAAAI8/R6p254HK6H0/s320/blog.png" alt="" id="BLOGGER_PHOTO_ID_5583730308887678418" border="0" /&gt;&lt;/a&gt;Se llama Tario's Project Blog (&lt;a href="http://tario-project.blogspot.com/"&gt; http://tario-project.blogspot.com/&lt;/a&gt; ) y lo hice especificamente para los proyectos para los que estoy trabajando bajo ese nickname en github (&lt;a href="https://github.com/tario"&gt;https://github.com/tario&lt;/a&gt;) y posiblemente otros. El objetivo de esto es construir un site separado donde se pueda consultar el status de esos proyectos y al mismo tiempo no saturar este blog con esa clase de informacion. Ademas, Tario's Project sera escrito integramente en ingles para tener un mayor alcance (mas tarde evaluo si implemento la version en español del blog o aprovechando alguna que otra feature de internacionalizacion que vi que tiene blogger)&lt;br /&gt;&lt;br /&gt;Lo ideal en realidad, seria dedicar una pagina a cada proyecto, pero en este caso los proyectos son chicos y son muchos ademas de que estan muy relacionados unos con otros (por ej, el release de cierto gem puede tener alto impacto en la usabilidad de otro ya existente), mas adelante, si corresponde, habra un site para proyectos que crezcan en importancia.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Enlaces:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;El nuevo blog: &lt;a href="http://tario-project.blogspot.com/"&gt;http://tario-project.blogspot.com/&lt;/a&gt;&lt;br /&gt;El sitio de repositorios en github: &lt;a href="https://github.com/tario"&gt;https://github.com/tario&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-4190937342391678594?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/4190937342391678594/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=4190937342391678594' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/4190937342391678594'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/4190937342391678594'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2011/03/el-blog-para-los-proyectos.html' title='El blog para los proyectos'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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/-3qxk84cSPuo/TX1lIc7VDdI/AAAAAAAAAI8/R6p254HK6H0/s72-c/blog.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1354794578842586233.post-8952126836388836387</id><published>2011-01-25T19:08:00.011-03:00</published><updated>2011-01-25T19:34:28.806-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='numerico'/><category scheme='http://www.blogger.com/atom/ns#' term='analisis'/><title type='text'>Buscar la raiz cuadrada mas rapida, con Ruby</title><content type='html'>&lt;div style="text-align: justify;"&gt;Se vienen los examenes y uno de ellos es el de Analisis Numerico, y como estoy usando mucho la raiz cuadrada en un proyecto en el que estoy, me decidi a buscar una raiz cuadrada mas rapida que la que trae el propio &lt;span style="font-weight: bold;"&gt;framework&lt;/span&gt; ;)&lt;br /&gt;&lt;br /&gt;La verdad, es que por default, las librerias matematicas calculan la raiz cuadrada con una muy buena precision, pero pueden surgir casos en los que esa precision es innecesaria (por ejemplo, si se trunca el resultado de la raiz cuadrada, es decir, tirar a la basura los decimales que se calculo) y lo que si es importante es poder efectuar los calculos &lt;span style="font-weight: bold;"&gt;rapido&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Sea cual sea el lenguaje en e que se va a programar, ruby esta bueno para probar los algoritmos muy facilmente, en este caso se utiliza el metodo de Newton-Raphson para calcular la raiz cuadrada de un numero&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre name="code" class="ruby"&gt;&lt;br /&gt;# x**2 - a = 0&lt;br /&gt;&lt;br /&gt;# calcula la raiz cuadrada y se le puede especificar la precision, es decir&lt;br /&gt;# la cota superior del error del resultado&lt;br /&gt;def Math.my_sqrt(a, precision)&lt;br /&gt; &lt;br /&gt;  x = 1&lt;br /&gt;  oldx=1&lt;br /&gt;&lt;br /&gt;  iter = 0&lt;br /&gt;  # newton raphson&lt;br /&gt;  while 1&lt;br /&gt;    oldx = x&lt;br /&gt;    x = x - ( x**2 - a ) / ( 2 * x)&lt;br /&gt;    break if (oldx-x).abs &lt; precision&lt;br /&gt;  end&lt;br /&gt; &lt;br /&gt;  x&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;def show( code )&lt;br /&gt;  print "#{code} =&gt; #{eval(code)}\n"&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;show "Math.my_sqrt(2.0, 0.5)"&lt;br /&gt;show "Math.my_sqrt(2.0, 0.05)"&lt;br /&gt;show "Math.my_sqrt(2.0, 0.005)"&lt;br /&gt;show "Math.my_sqrt(2.0, 0.0005)"&lt;br /&gt;&lt;br /&gt;show "Math.sqrt(2.0)"&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Salida del programa&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Math.my_sqrt(2.0, 0.5) =&gt; 1.41666666666667&lt;br /&gt;Math.my_sqrt(2.0, 0.05) =&gt; 1.41421568627451&lt;br /&gt;Math.my_sqrt(2.0, 0.005) =&gt; 1.41421568627451&lt;br /&gt;Math.my_sqrt(2.0, 0.0005) =&gt; 1.41421356237469&lt;br /&gt;Math.sqrt(2.0) =&gt; 1.4142135623731&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Enlaces:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://es.wikipedia.org/wiki/M%C3%A9todo_de_Newton"&gt;Metodo de Newton explicado en la Wikipedia&lt;/a&gt;&lt;br /&gt;&lt;a href="http://neoparaiso.com/logo/metodo-newton.html"&gt;Explicacion del metodo de newton usado para calcular la raiz cuadrada de un numero&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-8952126836388836387?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/8952126836388836387/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=8952126836388836387' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/8952126836388836387'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/8952126836388836387'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2011/01/buscar-la-raiz-cuadrada-mas-rapida-con.html' title='Buscar la raiz cuadrada mas rapida, con Ruby'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-7526713800626356496</id><published>2010-12-12T12:50:00.007-03:00</published><updated>2010-12-12T13:12:03.437-03:00</updated><title type='text'>¡Habemus Blog!</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_T12nVzD4aEs/TQTwOfVkrtI/AAAAAAAAAFc/lTShwsvjs70/s1600/cuad.jpg"&gt;&lt;img style="float: right; margin: 0pt 0pt 10px 10px; cursor: pointer; width: 209px; height: 209px;" src="http://4.bp.blogspot.com/_T12nVzD4aEs/TQTwOfVkrtI/AAAAAAAAAFc/lTShwsvjs70/s400/cuad.jpg" alt="" id="BLOGGER_PHOTO_ID_5549824772548112082" border="0" /&gt;&lt;/a&gt;El nuevo blog &lt;a href="http://gitevangelism.blogspot.com/"&gt;gitevangelism&lt;/a&gt; se dedica a la promocion de GIT. Un sistema de versionamiento que tiene asombrosos features pero que lamentablemente no esta lo bastante&lt;br /&gt;difundido, por lo menos en los ambientes que frecuento: en los trabajos y en la facultad.&lt;br /&gt;&lt;br /&gt;Sin duda, el sistema de control de versiones mas usado y difundido es el SVN, son muy pocas personas las que conocen a fondo las prestaciones de ambos como para poder elegir y por eso podria parecer que lo unico que agrega GIT son "commits locales" y "complejidad innecesaria". &lt;a href="http://gitevangelism.blogspot.com/"&gt;gitevangelism&lt;/a&gt; se encargara (entre otras cosas) de desmistificar esto y promover el conocimiento acerca de esta herramienta y como el control de versiones esta mas asociado a la forma del proceso de desarrollo de lo que en principio se cree.&lt;br /&gt;&lt;br /&gt;El nuevo blog:&lt;br /&gt;&lt;a href="http://gitevangelism.blogspot.com"&gt;http://gitevangelism.blogspot.com&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;--amend&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-7526713800626356496?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/7526713800626356496/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=7526713800626356496' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/7526713800626356496'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/7526713800626356496'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2010/12/habemus-blog.html' title='¡Habemus Blog!'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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/_T12nVzD4aEs/TQTwOfVkrtI/AAAAAAAAAFc/lTShwsvjs70/s72-c/cuad.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1354794578842586233.post-3542550580102442322</id><published>2010-08-24T20:33:00.037-03:00</published><updated>2010-08-24T23:42:58.749-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='uml'/><category scheme='http://www.blogger.com/atom/ns#' term='cacoo'/><category scheme='http://www.blogger.com/atom/ns#' term='yuml'/><category scheme='http://www.blogger.com/atom/ns#' term='gmodeler'/><category scheme='http://www.blogger.com/atom/ns#' term='gliffy'/><category scheme='http://www.blogger.com/atom/ns#' term='creatly'/><title type='text'>Overview de herramientas UML online</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.ecst.csuchico.edu/%7Erenner/csci112/Online/LabClass/Week12/UML_Class-diagram.gif"&gt;&lt;img style="float: right; margin: 0pt 0pt 10px 10px; cursor: pointer; width: 275px; height: 282px;" src="http://www.ecst.csuchico.edu/%7Erenner/csci112/Online/LabClass/Week12/UML_Class-diagram.gif" alt="" border="0" /&gt;&lt;/a&gt;Resulta que me anote en una materia interesante y estoy necesitando encontrar una herramienta de UML a mano, facil y si es posible colaborativa... esto es &lt;span style="font-weight: bold;"&gt;online&lt;/span&gt;, o "en la nube"&lt;br /&gt;&lt;br /&gt;Ya que estoy probando varias opciones, aprovecho para escribir un overview de todas las herramientas que probe. Para cada herramienta se incluye un diagrama generado con esta y la evaluacion de las siguientes caracteristicas:&lt;br /&gt;&lt;br /&gt;* Almacenamiento: Si tiene storage para almacenar los diagramas online&lt;br /&gt;* Vistas: Si tiene vistas publicas dinamicas para que se pueda mostrar en una pagina o en un blog la ultima version del diagrama&lt;br /&gt;* Diagramas: Que tipos de diagramas se pueden hacer (diagramas de actividad, casos de uso, clases, objetos, secuencia, despliegue, colaboracion, transicion, componentes)&lt;br /&gt;* Exports: Si se puede exportar como imagen o como algun otro formato editable&lt;br /&gt;* Imports: Si se puede importar imagenes o incluso otros objetos&lt;br /&gt;* Coop: Si es colaborativo, o sea, si varios usuarios pueden editar el diagrama simultaneamente diseñando de manera cooperativa.&lt;br /&gt;* Estabilidad: Si es posible editar sin que se cuelgue o tenga algun otro fallo que afecte el trabajo&lt;br /&gt;* Portabilidad: Si funciona en varios navegadores (por ahora testeados en Mozilla Firefox 3.6.8 con Ubuntu Linux)&lt;br /&gt;* Registracion: Si es necesaria, y que implica&lt;br /&gt;* Costo: Si tiene paquetes de uso gratis, si tiene paquetes de servicio pago, que limitaciones y precios hay de cada uno de ellos&lt;br /&gt;* Engine: Como funciona, si usa java, flash, etc...&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;Cacoo&lt;/span&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_T12nVzD4aEs/THRhRV0CxII/AAAAAAAAAEw/DtLgt_L8cv4/s1600/cacoo.jpg"&gt;&lt;img style="float: right; margin: 0pt 0pt 10px 10px; cursor: pointer; width: 358px; height: 210px;" src="http://2.bp.blogspot.com/_T12nVzD4aEs/THRhRV0CxII/AAAAAAAAAEw/DtLgt_L8cv4/s400/cacoo.jpg" alt="" id="BLOGGER_PHOTO_ID_5509135194722059394" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://cacoo.com/"&gt;http://cacoo.com/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Segun mi opinion, uno de los mejores, si se pudiera guardar el diagrama en la computadora local seria perfecto&lt;br /&gt;&lt;br /&gt;* Almacenamiento: SI&lt;br /&gt;* Vistas: SI (ej: &lt;a href="https://cacoo.com/diagrams/hB18F3rQnjWqxQ74/view"&gt;https://cacoo.com&lt;/a&gt;&lt;a href="https://cacoo.com/diagrams/hB18F3rQnjWqxQ74/view"&gt;/diagrams/hB18F3rQnjWqxQ74/view&lt;/a&gt; )&lt;br /&gt;* Diagramas: casos de uso, clases, secuencia, estados, componentes, deployment, ER y tiene mas bibliotecas de objetos&lt;br /&gt;* Exports: Solo imagenes en formato PNG (la version gratuita)&lt;br /&gt;* Imports: Cualquier tipo de imagen&lt;br /&gt;* Coop: SI&lt;br /&gt;* Estabilidad: Si tenes una conexion mala no lo uses&lt;br /&gt;* Portabilidad: Funciona bien en firefox 3.6.8 y en Ubuntu Linux&lt;br /&gt;* Registracion: SI o SI es necesaria (tambien con la version gratuita)&lt;br /&gt;* Costo: Gratis (limitacion de 3 colaboradores por diagrama)&lt;br /&gt;Engine: flash&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;Creatly&lt;/span&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_T12nVzD4aEs/THR-yibmnRI/AAAAAAAAAFA/JUnJ0CNchok/s1600/creatly.jpg"&gt;&lt;img style="float: right; margin: 0pt 0pt 10px 10px; cursor: pointer; width: 321px; height: 221px;" src="http://3.bp.blogspot.com/_T12nVzD4aEs/THR-yibmnRI/AAAAAAAAAFA/JUnJ0CNchok/s400/creatly.jpg" alt="" id="BLOGGER_PHOTO_ID_5509167650882100498" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://creatly.com/"&gt;http://creatly.com&lt;/a&gt;&lt;span style="font-size:180%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Este diagramador puede guardar archivos en la computadora local (ademas de poder guardarlos online)&lt;br /&gt;&lt;br /&gt;* Almacenamiento: SI&lt;br /&gt;* Vistas: SI&lt;br /&gt;* Diagramas: Actividad, Clase, Colaboracion, Componentes, Deployment, ER, Objetos, Secuencia, Estados, Casos de uso, networking, electronica, de flujo&lt;br /&gt;* Exports: PNG, JPG, PDF, Creatly File&lt;br /&gt;* Imports: Image, Creatly File&lt;br /&gt;* Coop: SI&lt;br /&gt;* Estabilidad: Me colgo el firefox una vez, pero la mayoria de las veces lo pude usar&lt;br /&gt;* Registracion: Se puede usar sin registracion (aunque se recomienda registrarse y es gratuito)&lt;br /&gt;* Costo:  Actualmente Gratis para 2 collaborators, U$S4.95 para 5  collaborators y un 1 Gb, U$S9.95 para ilimitado espacio y collaborators. No  se puede tener varios proyectos ni exportar archivos en formato  "editable" en la version gratuita. Ver &lt;a href="http://creately.com/plans7"&gt;http://creately.com/plans7&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;yUML&lt;/span&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_T12nVzD4aEs/TG3j5kFozaI/AAAAAAAAAEg/5vcxIJg3bfc/s400/624216db.png"&gt;&lt;img style="float: right; margin: 0pt 0pt 10px 10px; cursor: pointer; width: 129px; height: 281px;" src="http://2.bp.blogspot.com/_T12nVzD4aEs/TG3j5kFozaI/AAAAAAAAAEg/5vcxIJg3bfc/s400/624216db.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://yuml.me/"&gt;http://yuml.me/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Este es rarisimo, hay que poner un codigo (como una especie de lenguaje) y genera el diagrama. No tiene editor y es el que menos funcionalidades tiene, lo unico bueno que tiene es que funciona bien sin impotar cual sea el browser&lt;br /&gt;&lt;br /&gt;* Almacenamiento: NO&lt;br /&gt;* Vistas: NO (Algo &lt;a href="http://yuml.me/diagram/scruffy/class/edit/%23%20Cool%20UML%20Diagram,%20%5BCustomer%5D+1-%3E*%5BOrder%5D,%20%5BOrder%5D++1-items%20%3E*%5BLineItem%5D,%20%5BOrder%5D-0..1%3E%5BPaymentMethod%5D%20%20"&gt;parecido&lt;/a&gt;)&lt;br /&gt;* Diagramas:  clases, actividad, casos de uso&lt;br /&gt;* Exports: Imagen PNG&lt;br /&gt;* Imports: NO&lt;br /&gt;* Coop: NO&lt;br /&gt;* Estabilidad: 100% Siempre funciona, porque es muy sencillo&lt;br /&gt;* Portabilidad: 100%, ya que no importa que browser uses, el diagrama se genera del lado del servidor a partir del "codigo" que se le ingrese&lt;br /&gt;* Registracion: no hay&lt;br /&gt;* Costo: Gratis&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;gliffy&lt;/span&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_T12nVzD4aEs/THRrD03CG3I/AAAAAAAAAE4/b6pTBYbvt38/s1600/gliffy.png"&gt;&lt;img style="float: right; margin: 0pt 0pt 10px 10px; cursor: pointer; width: 337px; height: 276px;" src="http://4.bp.blogspot.com/_T12nVzD4aEs/THRrD03CG3I/AAAAAAAAAE4/b6pTBYbvt38/s400/gliffy.png" alt="" id="BLOGGER_PHOTO_ID_5509145957654207346" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.gliffy.com/"&gt;http://www.gliffy.com/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Este es interesante, tiene el estilo del cacoo y al creatly, pero viene con templates base para crear diagramas (con lo que ayuda bastante al usuario primerizo), lastima que no me anda el drag&amp;amp;drop (¿sera mi version de flash?), cualquier cosa pruebenlo (no se necesita registracion para probar). En lo personal para lo que necesito no tiene elementos de suficientes diagramas.&lt;br /&gt;&lt;br /&gt;* Almacenamiento: SI&lt;br /&gt;* Vistas: SI (Ej: &lt;a href="http://www.gliffy.com/pubdoc/2214754/S.png"&gt;http://www.gliffy.com/pubdoc/2214754/S.png&lt;/a&gt;)&lt;br /&gt;* Diagramas: Diagramas de flujo, networks, ER, UI, Diagramas de clases, secuencia, casos de uso&lt;br /&gt;* Imports: SI, Formatos GIF, JPEG y PNG&lt;br /&gt;* Exports: SVG(Visio), Gliffy Xml, Formatos graficos JPEG y PNG&lt;br /&gt;Coop: SI&lt;br /&gt;* Estabilidad: Por lo visto es estable, pero no lo pude probar bien&lt;br /&gt;* Portabilidad: Me fallo en firefox 3.6.8 con Ubuntu Linux, talvez funcione en otras plataformas&lt;br /&gt;* Registracion: Se puede usar sin registracion (aunque se recomienda registrarse y es gratuito)&lt;br /&gt;* Costo: es Gratis, pero es un trial de 30 dias&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;gModeler&lt;/span&gt;&lt;br /&gt;&lt;a href="http://www.gskinner.com/gmodeler/"&gt;http://www.gskinner.com/gmodeler/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Mismo problema de drag&amp;amp;drop como con gliffy, mas tarde probare este y otros con otro entorno.&lt;br /&gt;&lt;br /&gt;* Almacenamiento: NO (Aunque permite guardar como XML localmente)&lt;br /&gt;* Coop: NO&lt;br /&gt;* Portabilidad: MALA, no funciono en firefox 3.6.8 con Ubuntu Linux&lt;br /&gt;* Registracion: no hay&lt;br /&gt;* Costo: es totalmente Gratis&lt;br /&gt;&lt;br /&gt;Mas tarde voy a probar gModeler desde otro entorno&lt;br /&gt;&lt;br /&gt;Enlaces:&lt;br /&gt;&lt;br /&gt;Cacoo: &lt;a href="http://cacoo.com/"&gt;http://cacoo.com&lt;/a&gt;&lt;br /&gt;Creatly: &lt;a href="http://creatly.com/"&gt;http://creatly.com&lt;/a&gt;&lt;br /&gt;yUML: &lt;a href="http://yuml.me/"&gt;http://yuml.me/&lt;/a&gt;&lt;br /&gt;gliffy: &lt;a href="http://www.gliffy.com/"&gt;http://www.gliffy.com/&lt;/a&gt;&lt;br /&gt;gmodeler: &lt;a href="http://www.gskinner.com/gmodeler/"&gt;http://www.gskinner.com/gmodeler/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-3542550580102442322?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/3542550580102442322/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=3542550580102442322' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/3542550580102442322'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/3542550580102442322'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2010/08/megapost-overview-de-herramientas-uml.html' title='Overview de herramientas UML online'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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/_T12nVzD4aEs/THRhRV0CxII/AAAAAAAAAEw/DtLgt_L8cv4/s72-c/cacoo.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1354794578842586233.post-658893786403592071</id><published>2010-08-19T22:37:00.003-03:00</published><updated>2010-08-19T23:09:57.383-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='uml'/><title type='text'>Diagramas UML online</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_T12nVzD4aEs/TG3j5kFozaI/AAAAAAAAAEg/5vcxIJg3bfc/s1600/624216db.png"&gt;&lt;img style="float: right; margin: 0pt 0pt 10px 10px; cursor: pointer; width: 184px; height: 400px;" src="http://2.bp.blogspot.com/_T12nVzD4aEs/TG3j5kFozaI/AAAAAAAAAEg/5vcxIJg3bfc/s400/624216db.png" alt="" id="BLOGGER_PHOTO_ID_5507308497423355298" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Visiten esta web:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://yuml.me/"&gt;http://yuml.me/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Permite crear diagramas UMLs online usando un lenguaje bastante interesante, no tuve mucho tiempo para probarlo mas que para hacer este &lt;a href="http://yuml.me/diagram/scruffy/class/edit/%5BBlogger%5D-%5Bnote:%20Un%20blogger%20para%20ser%20tal%20debe%20tener%20por%20lo%20menos%20un%20blog%5D,%20%5BBlogger%5D++-1..*%5BBlog%5D,%20%5BBlogEntries%5D-%5Bnote:%20Un%20blog%20puede%20estar%20vacio%20%28tener%200%20entradas%29%5D,%20%5BBlog%5D++-0..*%5BBlogEntries%5D,%20%5BUser%5D%5E-%5BBlogger%5D"&gt;diagrama que les estoy mostrando&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-658893786403592071?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/658893786403592071/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=658893786403592071' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/658893786403592071'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/658893786403592071'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2010/08/diagramas-uml-online.html' title='Diagramas UML online'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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/_T12nVzD4aEs/TG3j5kFozaI/AAAAAAAAAEg/5vcxIJg3bfc/s72-c/624216db.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1354794578842586233.post-3961615959062181785</id><published>2010-08-16T12:48:00.018-03:00</published><updated>2010-08-16T14:09:31.204-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='parse_tree'/><category scheme='http://www.blogger.com/atom/ns#' term='tdd'/><title type='text'>La magia del TDD: un ejemplo real en ruby</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_T12nVzD4aEs/TGlr-ZMw8rI/AAAAAAAAAEA/6prlAXZW2r4/s1600/TestDrivenGameDevelopment.jpg"&gt;&lt;img style="float: right; margin: 0pt 0pt 10px 10px; cursor: pointer; width: 275px; height: 171px;" src="http://1.bp.blogspot.com/_T12nVzD4aEs/TGlr-ZMw8rI/AAAAAAAAAEA/6prlAXZW2r4/s320/TestDrivenGameDevelopment.jpg" alt="" id="BLOGGER_PHOTO_ID_5506050739097629362" border="0" /&gt;&lt;/a&gt;Este fin de semana comence un proyecto, una nueva gema que "desparsea" los arboles generados por la gema ParseTree. Explicar los detalles de ese proyecto no es el tema de este articulo, sino mas bien contar la experiencia con TDD.&lt;br /&gt;&lt;br /&gt;Para los que no saben que es TDD la &lt;a href="http://en.wikipedia.org/wiki/Test-driven_development"&gt;wikipedia&lt;/a&gt; explica. Sin son vagos como para clickear el link, TDD es una metodologia que basicamente tiene dos pilares: "write tests first" (escribir los test primero) y "refactoring".&lt;br /&gt;&lt;br /&gt;Resulta que lo que estoy desarrollando consiste en una funcion que revierte o encuentra la preimagen de otra funcion (es decir, genera un string con codigo ruby que resulte en un determinado arbol cuando se parsee con ParseTree).&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;Este requerimiento tiene un grado muy alto de testeabilidad ya que se puede calcular el input correspondiente a partir del output esperado (seria como el testeo oracle, pero al revez porq estamos buscando hallar la inversa de una funcion que ya tenemos, que es ParseTree)&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Manos a la obra:&lt;br /&gt;&lt;br /&gt;Paso 1) Escribir los tests primero:&lt;br /&gt;&lt;a href="http://github.com/tario/unparse_tree/tree/0ca29f14"&gt;http://github.com/tario/unparse_tree/tree/0ca29f14&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;En este caso se fue desarrollando de manera de ahorrar lineas y probar *todos* los casos (mas adelante se sabe que se omitieron algunas cosas, pero creo q eso es comun en TDD sobre todo cuando el analisis de cobertura no es viable)&lt;br /&gt;&lt;br /&gt;Paso 2) Implementar hasta que todos los tests pasen:&lt;br /&gt;&lt;a href="http://github.com/tario/unparse_tree/tree/48c9a997"&gt;http://github.com/tario/unparse_tree/tree/48c9a997&lt;/a&gt;&lt;br /&gt;&lt;span style="text-decoration: underline;"&gt;&lt;/span&gt;&lt;br /&gt;Cambios hasta que funcione, algunos "harcodean" o ponen "magic values", otros agregan funcionalidad a conciencia, lo importante es que cada commit disminuye el numero de errors + failures reportados y &lt;span style="font-weight: bold;"&gt;no se modifican los tests&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Paso 3) Refactoring:&lt;br /&gt;&lt;br /&gt;En esta etapa se modificara el codigo hasta que se vea minimamente "bien", es decir, se eliminara codigo duplicado, se implementaran las cosas "de verdad" en lugar de usar "magic values", "harcodeos" o "if extraños" y cualquier cambio que mejore el diseño/la distribucion del codigo, de mas esta decir que por cada cambio todos los tests  &lt;span style="font-weight: bold;"&gt;siempre tienen que pasar&lt;/span&gt;. Todavia no alcance esta etapa en el proyecto... ya llegara.&lt;br /&gt;&lt;br /&gt;Paso 4) Vuelta al paso 1:&lt;br /&gt;&lt;br /&gt;Con nuevos requerimientos y/o bugs encontrados, se genera una nueva bateria de tests y el ciclo vuelve a comenzar.&lt;br /&gt;&lt;br /&gt;De todo esto, en l&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_T12nVzD4aEs/TGlsav6ydaI/AAAAAAAAAEQ/qD2iWkp6xBI/s1600/tdd_cycle.jpg"&gt;&lt;img style="float: left; margin: 0pt 10px 10px 0pt; cursor: pointer; width: 223px; height: 272px;" src="http://4.bp.blogspot.com/_T12nVzD4aEs/TGlsav6ydaI/AAAAAAAAAEQ/qD2iWkp6xBI/s320/tdd_cycle.jpg" alt="" id="BLOGGER_PHOTO_ID_5506051226232583586" border="0" /&gt;&lt;/a&gt;a practica me encuentro con las siguientes ventajas de usar TDD:&lt;br /&gt;&lt;br /&gt;* La validacion de si el codigo funciona es automatica, con solo ejecutar un comando puedo saber si "rompi" el codigo o si estoy progresando&lt;br /&gt;* TDD guia a escribir el codigo de manera "correcta" o por lo menos mas prolija&lt;br /&gt;* Se puede testear un numero mas grande de casos, con lo que se cubren mayor cantidad de posibilidades&lt;br /&gt;&lt;br /&gt;Y, como  todo, tiene sus desventajas (aunque se mitigan y son evidentamente superadas por las ventajas)&lt;br /&gt;&lt;br /&gt;* Hay que programar las pruebas que si no se usara TDD, no se tendrian que programar (de todas maneras, con o sin TDD &lt;span style="font-weight: bold;"&gt;siempre hay que testear el software&lt;/span&gt;, y sin TDD se hace de forma manual)&lt;br /&gt;* Las pruebas no garantizan cobertura total, es decir, pueden ser %100 exitosas las pruebas y el software fallar en la practica al haber omitido algo (esta claro que la idea en principio no es confiar ciegamente en las pruebas, mas bien TDD tiene que basarse en la construccion de pruebas)&lt;br /&gt;* Durante la fase de desarrollo,  me doy cuenta de errores que se ven en el codigo o al escribir el codigo, pero no puedo corregirlos si no existen tests que pasen como resultado de esa correccion (para resolver esto se puede optar principalmente por dos alternativas, una seria registrar como un "ticket" la necesidad de agregar el test para el proximo ciclo, la otra seria agregar el test en ese mismo momento, aunque eso se alejaria del espiritu del TDD y superpondria los pasos 1 y 2)&lt;br /&gt;&lt;br /&gt;Cabe destacar que las ventajas del TDD asi como otras metodologias son apreciables a mediano y largo plazo (TDD mas que otras), ya que a medida que avancen los ciclos de TDD, los tests desarrollados en ciclos anteriores cumpliran el rol de automatizar las regresiones, es decir, que si se modifica el codigo en un proyecto que tiene 8 meses de vida, las pruebas automaticas rebelaran si se rompio funcionalidad implementada al principio del proyecto, tres meses atras, dos meses atras, que implemento otra persona, etc...&lt;br /&gt;Despues de varias iteraciones, volvere a postear para hacer un analisis de las ventajas de TDD a largo plazo&lt;br /&gt;&lt;br /&gt;Enlaces&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.blogger.com/Este%20fin%20de%20semana%20comence%20un%20proyecto,%20una%20nueva%20gema%20que%20%22desparsea%22%20los%20arboles%20generados%20por%20la%20gema%20ParseTree.%20Explicar%20los%20detalles%20de%20ese%20proyecto%20no%20es%20el%20tema%20de%20este%20articulo,%20sino%20mas%20bien%20contar%20la%20experiencia%20con%20TDD.%20%20Para%20los%20que%20no%20saben%20que%20es%20TDD%20la%20wikipedia%20explica.%20Sin%20son%20vagos%20como%20para%20clickear%20el%20link,%20TDD%20es%20una%20metodologia%20que%20basicamente%20tiene%20dos%20pilares:%20%22write%20tests%20first%22%20%28escribir%20los%20test%20primero%29%20y%20%22refactoring%22.%20%20Resulta%20que%20lo%20que%20estoy%20desarrollando%20consiste%20en%20una%20funcion%20que%20revierte%20o%20encuentra%20la%20preimagen%20de%20otra%20funcion%20%28es%20decir,%20genera%20un%20string%20con%20codigo%20ruby%20que%20resulte%20en%20un%20determinado%20arbol%20cuando%20se%20parsee%20con%20ParseTree%29.%20%20Este%20requerimiento%20tiene%20un%20grado%20muy%20alto%20de%20testeabilidad%20ya%20que%20se%20puede%20calcular%20el%20input%20correspondiente%20a%20partir%20del%20output%20esperado%20%28seria%20como%20el%20testeo%20oracle,%20pero%20al%20revez%20porq%20estamos%20buscando%20hallar%20la%20inversa%20de%20una%20funcion%20que%20ya%20tenemos,%20que%20es%20ParseTree%29%20%20Manos%20a%20la%20obra:%20%20Paso%201%29%20Escribir%20los%20tests%20primero:%20http://github.com/tario/unparse_tree/tree/0ca29f14%20%20En%20este%20caso%20se%20fue%20desarrollando%20de%20manera%20de%20ahorrar%20lineas%20y%20probar%20*todos*%20los%20casos%20%28mas%20adelante%20se%20sabe%20que%20se%20omitieron%20algunas%20cosas,%20pero%20creo%20q%20eso%20es%20comun%20en%20TDD%20sobre%20todo%20cuando%20el%20analisis%20de%20cobertura%20no%20es%20viable%29%20%20Paso%202%29%20Implementar%20hasta%20que%20todos%20los%20tests%20pasen:%20http://github.com/tario/unparse_tree/tree/48c9a997%20%20Cambios%20hasta%20que%20funcione,%20algunos%20%22harcodean%22%20o%20ponen%20%22magic%20values%22,%20otros%20agregan%20funcionalidad%20a%20conciencia,%20lo%20importante%20es%20que%20cada%20commit%20disminuye%20el%20numero%20de%20errors%20+%20failures%20reportados%20y%20no%20se%20modifican%20los%20tests%20%20Paso%203%29%20Refactoring:%20%20En%20esta%20etapa%20se%20modificara%20el%20codigo%20hasta%20que%20se%20vea%20minimamente%20%22bien%22,%20es%20decir,%20se%20eliminara%20codigo%20duplicado,%20se%20implementaran%20las%20cosas%20%22de%20verdad%22%20en%20lugar%20de%20usar%20%22magic%20values%22,%20%22harcodeos%22%20o%20%22if%20extra%C3%83%C2%B1os%22%20y%20cualquier%20cambio%20que%20mejore%20el%20dise%C3%83%C2%B1o/la%20distribucion%20del%20codigo,%20de%20mas%20esta%20decir%20que%20por%20cada%20cambio%20todos%20los%20tests%20siempre%20tienen%20que%20pasar.%20Todavia%20no%20alcance%20esta%20etapa%20en%20el%20proyecto...%20ya%20llegara.%20%20Paso%204%29%20Vuelta%20al%20paso%201:%20%20Con%20nuevos%20requerimientos%20y/o%20bugs%20encontrados,%20se%20genera%20una%20nueva%20bateria%20de%20tests%20y%20el%20ciclo%20vuelve%20a%20comenzar.%20%20De%20todo%20esto,%20en%20la%20practica%20me%20encuentro%20con%20las%20siguientes%20ventajas%20de%20usar%20TDD:%20%20*%20La%20validacion%20de%20si%20el%20codigo%20funciona%20es%20automatica,%20con%20solo%20ejecutar%20un%20comando%20puedo%20saber%20si%20%22rompi%22%20el%20codigo%20o%20si%20estoy%20progresando%20*%20TDD%20guia%20a%20escribir%20el%20codigo%20de%20manera%20%22correcta%22%20o%20por%20lo%20menos%20mas%20prolija%20*%20Se%20puede%20testear%20un%20numero%20mas%20grande%20de%20casos,%20con%20lo%20que%20se%20cubren%20mayor%20cantidad%20de%20posibilidades%20%20Y,%20como%20%20todo,%20tiene%20sus%20desventajas%20%28aunque%20se%20mitigan%20y%20son%20evidentamente%20superadas%20por%20las%20ventajas%29%20%20*%20Hay%20que%20programar%20las%20pruebas%20que%20si%20no%20se%20usara%20TDD,%20no%20se%20tendrian%20que%20programar%20%28de%20todas%20maneras,%20con%20o%20sin%20TDD%20siempre%20hay%20que%20testear%20el%20software,%20y%20sin%20TDD%20se%20hace%20de%20forma%20manual%29%20*%20Las%20pruebas%20no%20garantizan%20cobertura%20total,%20es%20decir,%20pueden%20ser%20%100%20exitosas%20las%20pruebas%20y%20el%20software%20fallar%20en%20la%20practica%20al%20haber%20omitido%20algo%20%28esta%20claro%20que%20la%20idea%20en%20principio%20no%20es%20confiar%20ciegamente%20en%20las%20pruebas,%20mas%20bien%20TDD%20tiene%20que%20basarse%20en%20la%20construccion%20de%20pruebas%29%20*%20Durante%20la%20fase%20de%20desarrollo,%20%20me%20doy%20cuenta%20de%20errores%20que%20se%20ven%20en%20el%20codigo%20o%20al%20escribir%20el%20codigo,%20pero%20no%20puedo%20corregirlos%20si%20no%20existen%20tests%20que%20pasen%20como%20resultado%20de%20esa%20correccion%20%28para%20resolver%20esto%20se%20puede%20optar%20principalmente%20por%20dos%20alternativas,%20una%20seria%20registrar%20como%20un%20%22ticket%22%20la%20necesidad%20de%20agregar%20el%20test%20para%20el%20proximo%20ciclo,%20la%20otra%20seria%20agregar%20el%20test%20en%20ese%20mismo%20momento,%20aunque%20eso%20se%20alejaria%20del%20espiritu%20del%20TDD%20y%20superpondria%20los%20pasos%201%20y%202%29%20%20Cabe%20destacar%20que%20las%20ventajas%20del%20TDD%20asi%20como%20otras%20metodologias%20son%20apreciables%20a%20mediano%20y%20largo%20plazo%20%28TDD%20mas%20que%20otras%29,%20ya%20que%20a%20medida%20que%20avancen%20los%20ciclos%20de%20TDD,%20los%20tests%20desarrollados%20en%20ciclos%20anteriores%20cumpliran%20el%20rol%20de%20automatizar%20las%20regresiones,%20es%20decir,%20que%20si%20se%20modifica%20el%20codigo%20en%20un%20proyecto%20que%20tiene%208%20meses%20de%20vida,%20las%20pruebas%20automaticas%20rebelaran%20si%20se%20rompio%20funcionalidad%20implementada%20al%20principio%20del%20proyecto,%20tres%20meses%20atras,%20dos%20meses%20atras,%20que%20implemento%20otra%20persona,%20etc...%20%20Enlaces%20%20http://en.wikipedia.org/wiki/Test-driven_development"&gt;http://en.wikipedia.org/wiki/Test-driven_development&lt;/a&gt;&lt;br /&gt;&lt;a href="http://github.com/tario/unparse_tree/tree/0ca29f14"&gt;http://github.com/tario/unparse_tree/tree/0ca29f14&lt;/a&gt; (tests creados en el primer ciclo de unparse_tree)&lt;br /&gt;&lt;a href="http://github.com/tario/unparse_tree"&gt;http://github.com/tario/unparse_tree&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-3961615959062181785?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/3961615959062181785/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=3961615959062181785' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/3961615959062181785'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/3961615959062181785'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2010/08/la-magia-del-tdd-un-ejemplo-real-en.html' title='La magia del TDD: un ejemplo real en ruby'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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/_T12nVzD4aEs/TGlr-ZMw8rI/AAAAAAAAAEA/6prlAXZW2r4/s72-c/TestDrivenGameDevelopment.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1354794578842586233.post-2955544407387391931</id><published>2010-08-10T22:31:00.004-03:00</published><updated>2010-08-10T22:35:13.657-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='blog'/><title type='text'>Soy malo para los nombres de blogs</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.sektor4.com/blogger-logo.jpg"&gt;&lt;img style="float: right; margin: 0pt 0pt 10px 10px; cursor: pointer; width: 158px; height: 156px;" src="http://www.sektor4.com/blogger-logo.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;He creado un &lt;a href="http://soymaloparalosnombresdeblogs.blogspot.com/"&gt;nuevo blog&lt;/a&gt;, llamado Soy malo para los nombres de blogs, sera el sumidero de las sobras de todos los blogs, no entren ahi&lt;br /&gt;&lt;br /&gt;Enlaces:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;a href="http://soymaloparalosnombresdeblogs.blogspot.com/"&gt;http://soymaloparalosnombresdeblogs.blogspot.com/&lt;/a&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-2955544407387391931?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/2955544407387391931/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=2955544407387391931' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/2955544407387391931'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/2955544407387391931'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2010/08/soy-malo-para-los-nombres-de-blogs.html' title='Soy malo para los nombres de blogs'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-1910702475693816301</id><published>2010-06-22T22:38:00.009-03:00</published><updated>2010-06-22T23:29:02.332-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='sandbox'/><title type='text'>Sandbox de codigo ruby (remake 2010)</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_T12nVzD4aEs/TCFw2Nbp88I/AAAAAAAAADQ/YY7RPWbZIbE/s1600/sandbox.jpg"&gt;&lt;img style="float: right; margin: 0pt 0pt 10px 10px; cursor: pointer; width: 243px; height: 207px;" src="http://1.bp.blogspot.com/_T12nVzD4aEs/TCFw2Nbp88I/AAAAAAAAADQ/YY7RPWbZIbE/s320/sandbox.jpg" alt="" id="BLOGGER_PHOTO_ID_5485789897734878146" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Anteriormente en este mismo blog &lt;a href="http://nilclass.blogspot.com/2009/11/sandbox-de-codigo-ruby.html"&gt;anuncie&lt;/a&gt; la creacion de un sandbox para ruby. Ese proyecto se cancelo y quedo definitivamente incompleto. El proyecto se llamaba arena-ruby-sandbox.&lt;br /&gt;&lt;br /&gt;Hace un tiempo comenze el desarrollo de un nuevo sandbox (llamado shikashi), pero con un diseño y una idea totalmente distinta: mientras arena-ruby-sandbox es un intento de sandbox en codigo ruby puro, shikashi se implementa utilizando una modificacion al interprete de ruby hecha en C en formato de extension (llamada rallhook).&lt;br /&gt;&lt;br /&gt;Funciona mejor que su antecesor ademas de permitir usar casi todos los elementos del lenguaje como clases y metodos singleton cosa que arena-ruby-sandbox no permitia.&lt;br /&gt;&lt;br /&gt;Recientemente libere la version 0.7.1 de rallhook ademas de la version 0.1.0 del sandbox shikashi. La documentacion del gem (que incluye instrucciones de como instalarlo, ejemplos de uso y descripcion completa del API) esta en &lt;a href="http://tario.github.com/shikashi/doc/"&gt;http://tario.github.com/shikashi/doc/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;NOTA: tambien se puede instalar haciendo&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;gem install shikashi&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Cosa que no menciona el README y lo actualizare en proximos releases.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-1910702475693816301?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/1910702475693816301/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=1910702475693816301' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/1910702475693816301'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/1910702475693816301'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2010/06/sandbox-de-codigo-ruby-remake-2010.html' title='Sandbox de codigo ruby (remake 2010)'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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/_T12nVzD4aEs/TCFw2Nbp88I/AAAAAAAAADQ/YY7RPWbZIbE/s72-c/sandbox.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1354794578842586233.post-2754820676418927144</id><published>2010-06-19T11:51:00.005-03:00</published><updated>2010-06-19T12:25:07.737-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='debug'/><category scheme='http://www.blogger.com/atom/ns#' term='post-mortem'/><category scheme='http://www.blogger.com/atom/ns#' term='gdb'/><category scheme='http://www.blogger.com/atom/ns#' term='debugging'/><category scheme='http://www.blogger.com/atom/ns#' term='c'/><title type='text'>Post-mortem debugging en linux</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.lacasadelterror.com/imgs/img_articulos/MuseoRoswell.jpg"&gt;&lt;img style="float: right; margin: 0pt 0pt 10px 10px; cursor: pointer; width: 208px; height: 162px;" src="http://www.lacasadelterror.com/imgs/img_articulos/MuseoRoswell.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Que es el debugging post-mortem&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;El debugging post-mortem es una clasica tecnica de debugging que consiste en que el sistema operativo genera un volcado completo de los registros, los threads y la memoria de un proceso que termina de manera anomala (ya sea por SIGSEGV o por SIGABRT), en linux estos volcados se llaman  "cores" y se pueden examinar con gdb para ver en que punto del codigo ocurrio el error, los threads con sus backtraces, los registros, e incluso el valor de las variables (si se tiene informacion de debug) en el momento en que termino el proceso.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Como activarlo&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Por default, en la mayoria de los sistemas linux viene desactivado, pero activarlo es tan simple como ejecutar en la terminal:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;ulimit -c 4000000000&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Que determina que el limite maximo para el tamaño del core sera de aproximadamente 4Gb (valores mucho mayores pueden ser rechazados a no ser que se tenga privilegios de root).&lt;br /&gt;&lt;br /&gt;Esto solo tiene validez en la shell en la que se activo, si se necesita que este siempre activo para cualquier sesion, se podria agregar la linea "ulimit -c 4000000000" al final del archivo ~/.bashrc&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;echo ulimit -c 4000000000 &gt;&gt; ~/.bashrc&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Como verlo funcionando&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Se crea un programa de purebas, "mytest.c" que genera un error abort()&lt;br /&gt;&lt;pre name=code class=c &gt;&lt;br /&gt;#include "stdlib.h"&lt;br /&gt;&lt;br /&gt;int main()  {&lt;br /&gt;abort();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Se compila generando informacion de debug y se ejecuta:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;gcc -ggdb mytest.c -o mytest&lt;br /&gt;./mytest&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;El programa falla y seguramente anunciara que se genero el core (en mi caso solamente el archivo generado se llama "core", en algunos sistemas pone el pid o cosas asi)&lt;br /&gt;&lt;br /&gt;Se puede usar gdb para analizar el core, tambien hay que pasarle como parametro el ejecutable que genero el core para poder ver la informacion de debug:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;gdb -c core mytest&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;A partir de entonces se puede examinar el estado que tenia el programa en el momento de finalizar como si se tratara de un debug normal:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(gdb) bt&lt;br /&gt;#0  0x00007f55e7ef3a75 in raise () from /lib/libc.so.6&lt;br /&gt;#1  0x00007f55e7ef75c0 in abort () from /lib/libc.so.6&lt;br /&gt;#2  0x000000000040052d in main () at mytest.c:4&lt;br /&gt;(gdb) info threads&lt;br /&gt;* 1 Thread 4352  0x00007f55e7ef3a75 in raise () from /lib/libc.so.6&lt;br /&gt;(gdb) disass main&lt;br /&gt;Dump of assembler code for function main:&lt;br /&gt;   0x0000000000400524 &lt;+0&gt;: push   %rbp&lt;br /&gt;   0x0000000000400525 &lt;+1&gt;: mov    %rsp,%rbp&lt;br /&gt;   0x0000000000400528 &lt;+4&gt;: callq  0x400418 &lt;abort@plt&gt;&lt;br /&gt;End of assembler dump.&lt;br /&gt;(gdb) print/x $rcx&lt;br /&gt;$4 = 0xffffffffffffffff&lt;br /&gt;(gdb)&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/1354794578842586233-2754820676418927144?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/2754820676418927144/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=2754820676418927144' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/2754820676418927144'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/2754820676418927144'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2010/06/post-mortem-debugging-en-linux.html' title='Post-mortem debugging en linux'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-7946857536168133443</id><published>2010-06-18T18:18:00.017-03:00</published><updated>2010-06-18T19:53:20.585-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='git'/><title type='text'>Deshacer el push en git</title><content type='html'>&lt;b&gt;Actualizacion: Quick fix&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Alguien pusheo commits que no debia, o por alguna razon se pretende "deshacer" commits que ya se enviaron al servidor central.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Quick fix&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Buscar el commit a donde se pretende volver: (usar git log o git reflog, etc...), y despues hay que ejecutar estos commandos (donde a_donde_volver se reemplaza por el commit):&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;git reset a_donde_volver&lt;br /&gt;git checkout HEAD .&lt;br /&gt;git push --force&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Y a trabajar&lt;br /&gt;&lt;br /&gt;NOTA: usar --force solo para casos especificos como este, ya que directamente sobreescribe cambios en la rama remota (que es lo que se pretende hacer en este caso)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Narrado (for dummys) &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Todo lo que voy a explicar es asumiendo que se esta trabajando en la rama master (que es la default en git), si no estas trabajando en la rama master, el comando "git branch" muestra la rama de trabajo en la que estas trabajando&lt;br /&gt;&lt;br /&gt;Antes, que nada, se puede hacer un tag del master actual:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;git tag ultimo_master master&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Posteriormente, hay que encontrar el commit al cual se quiere volver, se pueden revisar los logs (el nombre de la rama es opcional, si no se indica usa la rama de trabajo actual):&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;git log [master]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Supongamos que el commit al que se quiere volver es 0123456789abcd..., puede ser util taguearlo para referenciaro facilmente mas adelante (aunque se puede hacer todo referenciando al commit, directamente)&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;git tag a_donde_volver 0123456789abcd...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Posteriormente, se hace un reset a para que la rama master &lt;b&gt;local&lt;/b&gt; referencie a ese commit, y despues un checkout para cambiar los archivos y que coincidan&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;git reset a_donde_volver&lt;br /&gt;git checkout HEAD .&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Despues, hay que sobreescribir la referencia master &lt;b&gt;remota&lt;/b&gt; con la actual, pero hay que usar --force para que git no verifique si se trata de un fast-forward (porque sino rechaza la operacion), recordar usar --force solamente en casos especificos como este.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;git push --force&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Y despues se puede seguir trabajando normalmente&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Bonus track&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Puede ser util crear un branch en el servidor a partir del master original antes de que se revierta (para poder analizarlo entre todos, etc...), para hacer esto:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;git push origin ultimo_master:refs/heads/old_master&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Y en este post explico como usar los branches:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://nilclass.blogspot.com/2009/08/branches-remotos-en-git.html"&gt;http://nilclass.blogspot.com/2009/08/branches-remotos-en-git.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-7946857536168133443?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/7946857536168133443/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=7946857536168133443' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/7946857536168133443'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/7946857536168133443'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2010/06/deshacer-el-push-en-git.html' title='Deshacer el push en git'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-3650020283409410624</id><published>2010-06-16T13:14:00.004-03:00</published><updated>2010-06-16T13:36:11.619-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='discos'/><category scheme='http://www.blogger.com/atom/ns#' term='e2fsck'/><title type='text'>Solucion a sectores dañados en linux. EXT2 y EXT3</title><content type='html'>&lt;span style="font-weight:bold;"&gt;Sintomas&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;El sistema se cuelga en tareas estupidas como reproducir una pelicula, instalar paquetes, configurar cosas, abrir determinados archivos para despues de un tiempo de estar "colgado" anunciar que hasta la tarea mas simple fallo por un "I/O error".&lt;br /&gt;&lt;br /&gt;Hace falta confirmarlo tambien con los logs, la informacion necesaria aparece en el syslog (en /var/log/syslog ), se encontraran lineas similares a estas:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Jun 16 16:17:56 ubuntu kernel: [ 6193.840250] Buffer I/O error on device sda1, logical block 155153547&lt;br /&gt;Jun 16 16:17:56 ubuntu kernel: [ 6193.840254] Buffer I/O error on device sda1, logical block 155153548&lt;br /&gt;Jun 16 16:17:56 ubuntu kernel: [ 6193.840258] Buffer I/O error on device sda1, logical block 155153549&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;O tambien de estas:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Jun 15 20:16:01 ubuntu kernel: [   25.636424] ata1.00: status: { DRDY ERR }&lt;br /&gt;Jun 15 20:16:01 ubuntu kernel: [   25.640935] ata1.00: configured for UDMA/133&lt;br /&gt;Jun 15 20:16:01 ubuntu kernel: [   25.640951] ata1: EH complete&lt;br /&gt;Jun 15 20:16:01 ubuntu kernel: [   29.172011] ata1.00: exception Emask 0x0 SAct 0x7fff SErr 0x0 action 0x0&lt;br /&gt;Jun 15 20:16:01 ubuntu kernel: [   29.172013] ata1.00: irq_stat 0x40000008&lt;br /&gt;Jun 15 20:16:01 ubuntu kernel: [   29.172016] ata1.00: failed command: READ FPDMA QUEUED&lt;br /&gt;Jun 15 20:16:01 ubuntu kernel: [   29.172022] ata1.00: cmd 60/08:28:a7:74:3f/00:00:09:00:00/40 tag 5 ncq 4096 in&lt;br /&gt;Jun 15 20:16:01 ubuntu kernel: [   29.172025] ata1.00: status: { DRDY ERR }&lt;br /&gt;Jun 15 20:16:01 ubuntu kernel: [   29.176722] ata1.00: configured for UDMA/133&lt;br /&gt;Jun 15 20:16:01 ubuntu kernel: [   29.176740] ata1: EH complete&lt;br /&gt;Jun 15 20:16:01 ubuntu kernel: [   32.440790] ata1.00: exception Emask 0x0 SAct 0x7fab SErr 0x0 action 0x0&lt;br /&gt;Jun 15 20:16:01 ubuntu kernel: [   32.440792] ata1.00: irq_stat 0x40000008&lt;br /&gt;Jun 15 20:16:01 ubuntu kernel: [   32.440795] ata1.00: failed command: READ FPDMA QUEUED&lt;br /&gt;Jun 15 20:16:01 ubuntu kernel: [   32.440801] ata1.00: cmd 60/08:48:a7:74:3f/00:00:09:00:00/40 tag 9 ncq 4096 in&lt;br /&gt;Jun 15 20:16:01 ubuntu kernel: [   32.440805] ata1.00: status: { DRDY ERR }&lt;br /&gt;Jun 15 20:16:01 ubuntu kernel: [   32.440807] ata1.00: error: { UNC }&lt;br /&gt;Jun 15 20:16:01 ubuntu kernel: [   32.445770] ata1.00: configured for UDMA/133&lt;br /&gt;Jun 15 20:16:01 ubuntu kernel: [   32.445785] ata1: EH complete&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Solucion&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Si algunos sectores del disco estan dañados sera inevitable que se pierda el disco entero tarde o temprano, por eso lo primero que se debe hacer es backup de toda la informacion.&lt;br /&gt;Posteriormente, para poder seguir usando el disco, se debe hacer una revision completa marcando los bloques dañados como tal, el comando que hay que ejecutar es:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;e2fsck -c /dev/sda1&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Reemplazando /dev/sda1 por la particion que tengan que reparar.&lt;br /&gt;&lt;br /&gt;Esto solo se puede hacer con la particion desmontada, para poder hacerlo asi recomiendo una de tres opciones:&lt;br /&gt;&lt;br /&gt;1) Usar un live-cd como los de ubuntu, que les permite acceder a las particiones, tienen los comandos basicos y hasta entorno grafico para que puedan, por ej, escribir articulos en su blog publicando la solucion (es mi caso)&lt;br /&gt;&lt;br /&gt;2) Usar una opcion de "rescue" (no estoy seguro si viene con ubuntu, pero viene con todos los fedora) eso les da una shell con privilegios de root pero nada de graficos, de ventanitas de gelatina, ni menos cubos de escritorio girando&lt;br /&gt;&lt;br /&gt;3) Inician el sistema normalmente, y con Ctrl+Alt+F1 pasan a la consola sin graficos, ejecutan:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;sudo init 1&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Para pasar a runlevel 1 que detiene todos los servicios (incluyendo el entorno grafico) y permite desmontar cualquier particion, ahi ejecutan el escaneo y cuando termine vuelven a montar la particion y hacen&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;sudo init 5&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Para volver a runlevel 5&lt;br /&gt;&lt;br /&gt;Esta ultima es mas para "hackers" pero es innecesariamente complicada y me fracture el dedo indice cuando quise hacerla.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-3650020283409410624?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/3650020283409410624/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=3650020283409410624' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/3650020283409410624'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/3650020283409410624'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2010/06/solucion-sectores-danados-en-linux-ext2.html' title='Solucion a sectores dañados en linux. EXT2 y EXT3'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-3370747315153429519</id><published>2010-06-13T18:05:00.009-03:00</published><updated>2010-06-13T18:33:30.432-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='blog'/><category scheme='http://www.blogger.com/atom/ns#' term='changelog'/><category scheme='http://www.blogger.com/atom/ns#' term='commit'/><category scheme='http://www.blogger.com/atom/ns#' term='css'/><title type='text'>Renovado diseño del blog</title><content type='html'>Tarde de domingo sin saber que hacer, renovacion visual del blog. Se hicieron los siguientes cambios.&lt;br /&gt;&lt;br /&gt;* Se cambiaron los colores blancos, claros de blogs de psicologia newbies por colores darks, bizarros propios del underground, el H4X0R1NG, el KRAK0RING y PRHEKIRING aunque el blog NO PUBLICARA ARTICULOS DE ESA CATEGORIA :P (para eso hay blogs muy buenos en la web)&lt;br /&gt;&lt;br /&gt;* Se cambiaron los colores del syntax highlighting en el style para que tenga sentido con los nuevos colores (todo dark) y se incluyo el style como tag en el template del blog para acelerar la carga de la pagina &lt;br /&gt;&lt;br /&gt;* Se incluyeron todos los Javascripts de highlighting en el template del blog (en los tags &lt;script&gt;&lt;/script&gt;) en lugar de que sean referencia remota al sitio donde estaban alojados, con esto se acelera por mucho la carga de la pagina.&lt;br /&gt;&lt;br /&gt;* Se cambio el fondo por uno de esos fondos "geeks" que hay en las opciones, pero como esto es ruby, se pinto de rojo (el original era azul)&lt;br /&gt;&lt;br /&gt;Lo que mas me ayudo fue el plugin firebug para probar como quedan los colores antes de grabar en el template, y analizar un poco el source code de la pagina.&lt;br /&gt;Tambien me sirvio bastante el irb para escapear el javascript, la libreria CGI:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="ruby"&gt;&lt;br /&gt;require "cgi"&lt;br /&gt;CGI.escapeHTML("&amp;lt;script&amp;gt;alert('hello world')&amp;lt;/script&amp;gt;");&lt;br /&gt;# =&gt; "&amp;amp;lt;script&amp;amp;gt;alert('hello world')&amp;amp;lt;/script&amp;amp;gt;"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Espero que la experiencia blogger sea mas ruby ahora&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-3370747315153429519?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/3370747315153429519/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=3370747315153429519' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/3370747315153429519'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/3370747315153429519'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2010/06/renovado-diseno-del-blog.html' title='Renovado diseño del blog'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-585736111194892902</id><published>2010-05-29T21:27:00.005-03:00</published><updated>2010-05-29T22:06:40.667-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='eval'/><title type='text'>Definicion de clases y metodos en un eval</title><content type='html'>Una de las miles de cualidades que tiene ruby como lenguaje dinamico es la ejecucion de codigo ruby contenido en un string mediante el uso de la funcion &lt;span style="font-weight:bold;"&gt;eval&lt;/span&gt;.&lt;br /&gt;Asi se pueden hacer cosas bastante interesantes ejecutando codigo ingresado dinamicamente ^_^&lt;br /&gt;No obstante es necesario conocer como sortear determinados obstaculos en la ejecucion de codigo dinamico&lt;br /&gt;&lt;br /&gt;&lt;pre name=code class=ruby&gt;&lt;br /&gt;class Runner&lt;br /&gt;    def run(code)&lt;br /&gt;        eval(code)&lt;br /&gt;    end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;runner = Runner.new&lt;br /&gt;&lt;br /&gt;# ¡¡FAIL!! :(, no se puede definir classes desde adentro de un metodo (Runner#run)&lt;br /&gt;runner.run("&lt;br /&gt;    class X&lt;br /&gt;        def foo&lt;br /&gt;            print \"hello world\n\"&lt;br /&gt;        end&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    x = X.new&lt;br /&gt;    x.foo&lt;br /&gt;    ")&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Lo que se intento hacer en el ejemplo anterior, para el interprete es equivalente a:&lt;br /&gt;&lt;br /&gt;&lt;pre name=code class=ruby&gt;&lt;br /&gt;class Runner&lt;br /&gt;    def run(code)&lt;br /&gt;       # いけない！!! &lt;br /&gt;       # en ruby no esta permitido definir clases adentro de metodos&lt;br /&gt;       # (aunque si permite hacer otras cosas locas XD )&lt;br /&gt;       class X &lt;br /&gt;           def foo&lt;br /&gt;                print \"hello world\n\"&lt;br /&gt;           end&lt;br /&gt;       end&lt;br /&gt;    &lt;br /&gt;       x = X.new&lt;br /&gt;       x.foo&lt;br /&gt;    end&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Para poder hacerlo correctamente hay que pasarle un segundo parametro a eval que es el "binding", un binding representa el contexto en ruby de donde se llama el binding, que incluye las variables locales, etc... mejor verlo en el ejemplo que explicarlo:&lt;br /&gt;&lt;br /&gt;&lt;pre name=code class=ruby&gt;&lt;br /&gt;class Runner&lt;br /&gt;    &lt;br /&gt;    class &lt;&lt; self&lt;br /&gt;        attr_accessor :runner_binding&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def run(code)&lt;br /&gt;        # se especifica un binding al eval para definir el contexto&lt;br /&gt;        # en el que se ejecuta el codigo&lt;br /&gt;        eval(code, Runner.runner_binding)&lt;br /&gt;    end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;# se copia el binding del contexto actual (fuera de cualquier clase o metodo)&lt;br /&gt;Runner.runner_binding = binding&lt;br /&gt;&lt;br /&gt;runner = Runner.new&lt;br /&gt;&lt;br /&gt;# se puede definir clases en el codigo pasado a eval, porque el binding&lt;br /&gt;# esta afuera de cualquier declaracion de clase o metodo y el eval se&lt;br /&gt;# llama con ese binding&lt;br /&gt;runner.run("&lt;br /&gt;    class X&lt;br /&gt;        def foo&lt;br /&gt;            print \"hello world\n\"&lt;br /&gt;        end&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    x = X.new&lt;br /&gt;    x.foo&lt;br /&gt;    ")&lt;br /&gt;    &lt;br /&gt;    &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Que para el interprete es lo mismo que reemplazar el codigo en donde se llama a binding en lugar de en donde se llama a eval:&lt;br /&gt;&lt;br /&gt;&lt;pre name=code class=ruby&gt;&lt;br /&gt;class Runner&lt;br /&gt;    &lt;br /&gt;    class &lt;&lt; self&lt;br /&gt;        attr_accessor :runner_binding&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def run(code)&lt;br /&gt;        # se especifica un binding al eval para definir el contexto&lt;br /&gt;        # en el que se ejecuta el codigo&lt;br /&gt;        eval(code, Runner.runner_binding)&lt;br /&gt;    end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;# よろしい&lt;br /&gt;# Runner.runner_binding = binding&lt;br /&gt;    class X&lt;br /&gt;        def foo&lt;br /&gt;            print \"hello world\n\"&lt;br /&gt;        end&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    x = X.new&lt;br /&gt;    x.foo&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Y ya que estamos, les cuento que otra cosa tiene el eval para hacer&lt;br /&gt;&lt;br /&gt;&lt;pre name=code class=ruby&gt;&lt;br /&gt;def bar&lt;br /&gt;  1/0 # ZeroDivisionError&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;def foo(code) # ¿porque siempre foo?&lt;br /&gt;eval(code)&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;foo("bar") # &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Resultado:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;test.rb:6:in `foo': test.rb:2:in `/': divided by 0 (ZeroDivisionError)&lt;br /&gt; from test.rb:2:in `bar'&lt;br /&gt; from (eval):1:in `foo'&lt;br /&gt; from test.rb:9:in `eval'&lt;br /&gt; from test.rb:6:in `foo'&lt;br /&gt; from test.rb:9&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Mejor, pasarle unos argumentos adicionales a eval especificando el "archivo" y el numero de linea de donde viene el codigo evaluado&lt;br /&gt;&lt;br /&gt;&lt;pre name=code class=ruby&gt;&lt;br /&gt;def bar&lt;br /&gt;  1/0 # ZeroDivisionError&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;def foo(code) # ¿porque siempre foo?&lt;br /&gt;eval(code, binding, "foo_eval.rb", 1)&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;foo("bar") # &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Resultado:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;test.rb:2:in `/': divided by 0 (ZeroDivisionError)&lt;br /&gt; from test.rb:2:in `bar'&lt;br /&gt; from foo_eval.rb:1:in `foo'&lt;br /&gt; from test.rb:6:in `foo'&lt;br /&gt; from test.rb:9&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Ahora se puede ver mejor en el backtrace de donde viene el codigo, con esto mejorada la trazabilidad cuando se usa eval.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-585736111194892902?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/585736111194892902/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=585736111194892902' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/585736111194892902'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/585736111194892902'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2010/05/definicion-de-clases-y-metodos-en-un.html' title='Definicion de clases y metodos en un eval'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-6993637237027901078</id><published>2010-05-06T10:01:00.007-03:00</published><updated>2010-05-06T10:13:09.593-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='radioactiva'/><category scheme='http://www.blogger.com/atom/ns#' term='humor'/><category scheme='http://www.blogger.com/atom/ns#' term='pizza'/><title type='text'>¡Cuidado! Pizza Radioctiva</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_T12nVzD4aEs/S-K-ypfbmXI/AAAAAAAAADA/Zz8WNJl8qmg/s1600/Imagen100.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 320px; height: 239px;" src="http://2.bp.blogspot.com/_T12nVzD4aEs/S-K-ypfbmXI/AAAAAAAAADA/Zz8WNJl8qmg/s320/Imagen100.jpg" alt="" id="BLOGGER_PHOTO_ID_5468142674921625970" border="0" /&gt;&lt;/a&gt;&lt;span style="font-weight: bold;"&gt;Ficha tecnica:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Radiancia: 5.9 Kilopluts a temp. ambiente&lt;br /&gt;Queso: 1.8 Kilogramos&lt;br /&gt;Tomate: 4.5 Terawatts&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_T12nVzD4aEs/S-K-m4Iat_I/AAAAAAAAAC4/1yGe4uQsleA/s1600/Imagen097.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 320px; height: 240px;" src="http://2.bp.blogspot.com/_T12nVzD4aEs/S-K-m4Iat_I/AAAAAAAAAC4/1yGe4uQsleA/s320/Imagen097.jpg" alt="" id="BLOGGER_PHOTO_ID_5468142472693200882" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_T12nVzD4aEs/S-K-MPmv_VI/AAAAAAAAACo/_k74r0nk_00/s1600/Imagen094.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 320px; height: 239px;" src="http://4.bp.blogspot.com/_T12nVzD4aEs/S-K-MPmv_VI/AAAAAAAAACo/_k74r0nk_00/s320/Imagen094.jpg" alt="" id="BLOGGER_PHOTO_ID_5468142015137971538" border="0" /&gt;&lt;/a&gt;Aceitunotones nominal: 2 (ya disipados)&lt;br /&gt;Vida Media: 9 minutos desde la salida del horno&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_T12nVzD4aEs/S-K-MPmv_VI/AAAAAAAAACo/_k74r0nk_00/s1600/Imagen094.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 320px; height: 239px;" src="http://4.bp.blogspot.com/_T12nVzD4aEs/S-K-MPmv_VI/AAAAAAAAACo/_k74r0nk_00/s320/Imagen094.jpg" alt="" id="BLOGGER_PHOTO_ID_5468142015137971538" 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/1354794578842586233-6993637237027901078?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/6993637237027901078/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=6993637237027901078' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/6993637237027901078'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/6993637237027901078'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2010/05/cuidado-pizza-radioctiva.html' title='¡Cuidado! Pizza Radioctiva'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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/_T12nVzD4aEs/S-K-ypfbmXI/AAAAAAAAADA/Zz8WNJl8qmg/s72-c/Imagen100.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1354794578842586233.post-8326340975780643621</id><published>2010-03-24T15:58:00.004-03:00</published><updated>2010-03-24T16:14:26.618-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='extension'/><category scheme='http://www.blogger.com/atom/ns#' term='c'/><category scheme='http://www.blogger.com/atom/ns#' term='gem'/><title type='text'>Como escribir una extension ruby en C en 5 minutos</title><content type='html'>Lo siguiente toma lugar entre las 15:51 pm y las 15:56 pm&lt;br /&gt;&lt;br /&gt;Para crear una extension en ruby lo primero que hay que hacer, es crear el "extconf.rb", basicamente tiene que tener el siguiente contenido:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="ruby"&gt;&lt;br /&gt;# extconf.rb&lt;br /&gt;require 'mkmf'&lt;br /&gt;&lt;br /&gt;dir_config("exttest")&lt;br /&gt;&lt;br /&gt;create_makefile("exttest")&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Posteriormente, hay que crear el archivo del codigo fuente en C de la extension, que minimamente tiene que haber uno, en este caso creamos uno de prueba, bastante resumido, el cual crea un modulo ruby y le define dos metodos, ambos implementados en C:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre name="code" class="c"&gt;&lt;br /&gt;// exttest.c&lt;br /&gt;&lt;br /&gt;#include "ruby.h"&lt;br /&gt;&lt;br /&gt;static VALUE foo(VALUE self) {&lt;br /&gt; printf("Foo invoqued\n");&lt;br /&gt; return Qnil;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;static VALUE sum(VALUE self, VALUE a, VALUE b) {&lt;br /&gt; return INT2NUM( NUM2INT(a) + NUM2INT(b) );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;void&lt;br /&gt;Init_exttest()&lt;br /&gt;{&lt;br /&gt; VALUE rb_exttest = rb_define_module("Exttest"); // definir el modulo&lt;br /&gt; &lt;br /&gt; rb_define_singleton_method(rb_exttest, // en que modulo&lt;br /&gt;   "foo", // nombre del metodo&lt;br /&gt;   foo, // puntero a la implementacion C del metodo&lt;br /&gt;   0 // cantidad de argumentos del metodo&lt;br /&gt;   );&lt;br /&gt;&lt;br /&gt; rb_define_singleton_method(rb_exttest, // en que modulo&lt;br /&gt;   "sum", // nombre del metodo&lt;br /&gt;   sum, // puntero a la implementacion C del metodo&lt;br /&gt;   2 // cantidad de argumentos del metodo&lt;br /&gt;   );&lt;br /&gt; &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Para generar el makefile (solo hay que hacer esto una vez), se ejecuta el script extconf.rb:&lt;br /&gt;&lt;pre name="code" class="sh"&gt;&lt;br /&gt;ruby extconf.rb&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Para construir la extension, se debe lanzar el siguiente comando:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="sh"&gt;&lt;br /&gt;make&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Eso genera, entre otros archivos intermedios, extconf.so, el cual contiene la extension misma compilada a codigo nativo de la plataforma donde estan corriendo todo, para instalarla en el sistema, hay que correr (como root):&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre name="code" class="sh"&gt;&lt;br /&gt;make install&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Para usar la extension:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="ruby"&gt;&lt;br /&gt;# test.rb&lt;br /&gt;require 'rubygems'&lt;br /&gt;require 'exttest'&lt;br /&gt;&lt;br /&gt;Exttest.foo # el metodo foo definido en exttest.c!!&lt;br /&gt;print Exttest.sum(4,9),"\n" # el metodo sum definido en exttest.c!!&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Posteriormente, se pueden hacer cosas mas interesantes como definir clases, clases anidadas en modulos, metodos, etc...&lt;br /&gt;Para la proxima voy a explicar como encapsular la extension como gem y distribuirla&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;links:&lt;br /&gt;&lt;br /&gt;* &lt;a href="http://www.blogger.com/*%20http://onlamp.com/pub/a/onlamp/2004/11/18/extending_ruby.html"&gt;http://onlamp.com/pub/a/onlamp/2004/11/18/extending_ruby.html&lt;/a&gt;: Fuente que inspiro este articulo y ejemplo practico de como wrappear la libreria GenX como libreria ruby GenX4r&lt;br /&gt;* &lt;a href="http://rhg.rubyforge.org/chapter04.html"&gt;http://rhg.rubyforge.org/chapter04.html&lt;/a&gt;: Tutorial que muestra como definir clases y modulos&lt;br /&gt;* &lt;a href="http://ruby-doc.org/doxygen/1.8.4/group__ruby__interp.html"&gt;http://ruby-doc.org/doxygen/1.8.4/group__ruby__interp.html&lt;/a&gt;: Documentacion completa de funciones C para definir extensiones de ruby incluyendo funciones de conversion de datos&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-8326340975780643621?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/8326340975780643621/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=8326340975780643621' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/8326340975780643621'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/8326340975780643621'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2010/03/como-escribir-una-extension-ruby-en-c.html' title='Como escribir una extension ruby en C en 5 minutos'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-7536839805085611711</id><published>2010-03-10T09:58:00.003-03:00</published><updated>2010-03-10T10:16:19.960-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='git'/><category scheme='http://www.blogger.com/atom/ns#' term='github'/><category scheme='http://www.blogger.com/atom/ns#' term='git-svn'/><category scheme='http://www.blogger.com/atom/ns#' term='svn'/><title type='text'>En github solo se tarda 60 SEGUNDOS</title><content type='html'>&lt;div style="text-align: justify;"&gt;Esta mañana, entre a la internet con la idea de migrar un proyecto que tenia en googlecode (con svn) a git (y el mas conocido repositorio gratuito en internet de git es github)&lt;br /&gt;El hecho de tener que migrar commits de svn a git ademas de la registracion, setup del repo git y demas cosas me hacian imaginar q seria una experiencia de&lt;span style="font-weight: bold;"&gt; trabajo&lt;/span&gt;.&lt;br /&gt;Pero me soprendi: no solo registrarse y crear el repositorio fueron tres simples clicks, sino que tambien &lt;span style="font-weight: bold;"&gt;hay literalmente un boton "migrar SVN a GIT" &lt;/span&gt;en el cual solo te pedia la url del servidor svn... tras la operatoria (que encima fue rapida), pude ver mis commits convertidos a git.&lt;br /&gt;Asi que el que este entusiasmado con git, sabe que no solo puede registrarse facilmente a un repositorio git gratuito sino que puede tambien migrar cualquier repositorio de svn para no perder la valiosa informacion de los commits en la mudanza.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Enlaces:&lt;br /&gt;&lt;br /&gt;GitHub:&lt;br /&gt;&lt;tt id="checkoutcmd"&gt;&lt;strong&gt;&lt;em&gt;&lt;/em&gt;&lt;/strong&gt;&lt;/tt&gt;&lt;span style="font-family:monospace;"&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;tt id="checkoutcmd"&gt;&lt;strong&gt;&lt;em&gt;&lt;/em&gt;&lt;/strong&gt;&lt;/tt&gt;&lt;a href="http://github.com/"&gt;http://github.com/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;GoogleCode ( Aun asi esta bueno si quieren usar un repo svn y el issue-tracker les puede gustar :) ):&lt;br /&gt;&lt;a href="http://code.google.com/"&gt;http://code.google.com/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-7536839805085611711?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/7536839805085611711/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=7536839805085611711' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/7536839805085611711'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/7536839805085611711'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2010/03/en-github-solo-se-tarda-60-segundos.html' title='En github solo se tarda 60 SEGUNDOS'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-5764398141970989231</id><published>2010-02-24T09:53:00.005-03:00</published><updated>2010-02-24T10:16:11.598-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='git'/><title type='text'>Analisis de mergeo en git</title><content type='html'>&lt;div style="text-align: justify;"&gt;Cada vez que se mergea una rama en otra, es necesario conocer que modificaciones se estarian  introduciendo concretamente en la rama de destino antes de proceder al mergeo mismo.&lt;br /&gt;&lt;br /&gt;El comando git-merge-base permite saber cual es el "common parent" de dos commits dados, es el "merge-base" el que define que segemento de cambios se incluiran al hacer el mergeo.&lt;br /&gt;&lt;br /&gt;Supongamos que se quiere mergear a la rama xxxxx, los cambios de la rama yyyyy, pero antes se desea conocer que cambios se incluiran&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;# se cambia la rama de trabajo a yyyyy&lt;br /&gt;$ git checkout yyyyy&lt;br /&gt;&lt;br /&gt;# se busca el "merge base&lt;br /&gt;$ git merge-base HEAD xxxxx&lt;br /&gt;123456789abcdef&lt;br /&gt;&lt;br /&gt;# se analizan los cambios que se incluiran viendo el segemento de cambios desde el merge-base&lt;br /&gt;# hasta el ultimo commit de xxxxx&lt;br /&gt;$ git log 123456789abcdef..xxxxx&lt;br /&gt;( aparece una enumeracion de los commits que se van a incluir si se procede al mergeo)&lt;br /&gt;&lt;br /&gt;# o tambien, se podria&lt;br /&gt;$ git log $(git merge-base HEAD xxxxx)..xxxxx&lt;br /&gt;( aparece la misma salida que del comando anterior)&lt;br /&gt;&lt;br /&gt;# si se aceptan los commits vistos en el log, se procede al mergeo&lt;br /&gt;git merge xxxxx&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;NOTA: Ademas de usar estos practicos comandos ayuda bastante mantener una nomeclatura y una gestion ordenada de las ramas que permitan tener en claro cuales son los "merge-base" de los mergeo que se ejecutaran.&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/1354794578842586233-5764398141970989231?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/5764398141970989231/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=5764398141970989231' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/5764398141970989231'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/5764398141970989231'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2010/02/analisis-de-mergeo-en-git.html' title='Analisis de mergeo en git'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-965277911783722857</id><published>2009-12-09T22:32:00.003-03:00</published><updated>2009-12-09T22:50:23.831-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='git'/><category scheme='http://www.blogger.com/atom/ns#' term='commit'/><category scheme='http://www.blogger.com/atom/ns#' term='lost'/><title type='text'>Recuperar commits "perdidos" en git</title><content type='html'>&lt;div style="text-align: justify;"&gt;Cada tanto puede pasar que de checkout en checkout, nos encontramos con:&lt;br /&gt;&lt;br /&gt;"¡oh no!, todos los commits que hice hoy no estan en la rama, incluso nisiquiera se donde estan"&lt;br /&gt;&lt;br /&gt;Pareciera que todo el trabajo del dia quedo "perdido", pero no es asi, si se commiteo, esos commits estan en alguna parte... quiza no apuntados por ninguna referencia, pero estan.&lt;br /&gt;&lt;br /&gt;Una de las maneras mas practicas de encontrarlo es usando el comando&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;git reflog&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Que da por salida un registro de las operaciones que se hicieron, algo como esto:&lt;br /&gt;&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;8705300... HEAD@{0}: commit: aplicado metodo para desactivar los metodos privado&lt;br /&gt;104683b... HEAD@{1}: commit: corregida restauracion de constantes&lt;br /&gt;0a714ab... HEAD@{2}: commit: corregido error&lt;br /&gt;f47b0e6... HEAD@{3}: commit: implementado metodo para activar y desactivar privi&lt;br /&gt;7760e03... HEAD@{4}: commit: definido metodo permit, para definir muy facilmente&lt;br /&gt;2936507... HEAD@{5}: commit: renombrado metodo para preguntar el permiso para ej&lt;br /&gt;93757af... HEAD@{6}: commit: agregados enable y disable privileges con prints&lt;br /&gt;4a2e9c3... HEAD@{7}: commit: agregado metodos para crear bloques unprivileged y&lt;br /&gt;f19eb66... HEAD@{8}: commit: completado holder de manera que puede tener el codi&lt;br /&gt;abc82d0... HEAD@{9}: commit: separado metodo create_holder&lt;br /&gt;5185142... HEAD@{10}: commit (initial): primer commit&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Incluye los "SHA1" de los commits hechos recientemente, de los cuales se pueden tomar los cambios y enviarlos al lugar correspondiente con git merge, crear branches o lo que sea necesario hacer.&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/1354794578842586233-965277911783722857?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/965277911783722857/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=965277911783722857' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/965277911783722857'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/965277911783722857'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2009/12/recuperar-commits-perdidos-en-git.html' title='Recuperar commits &quot;perdidos&quot; en git'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-5633398169026360755</id><published>2009-11-29T11:58:00.005-03:00</published><updated>2009-12-02T20:20:40.756-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='sandbox'/><title type='text'>Sandbox de codigo ruby</title><content type='html'>&lt;div style="text-align: justify;"&gt;La semana pasada empece el &lt;a href="http://www.blogger.com/arena-ruby-sandbox.googlecode.com"&gt;desarrollo&lt;/a&gt; de una libreria de ruby que permita crear "sandbox" de codigo ruby&lt;br /&gt;&lt;br /&gt;Un &lt;a href="http://en.wikipedia.org/wiki/Sandbox_%28computer_security%29"&gt;sandbox&lt;/a&gt; (traducido literalmente del ingles como "caja de arena") es un entorno "protegido" que permite ejecutar programas de una manera en la que no es posible que estos programas afecten a lo que esta "afuera" del sandbox (Por ej: ejecutar un programa de manera que no pueda tener acceso al sistema de archivos de la computadora en la que se esta ejecutando)&lt;br /&gt;&lt;span style="display: block;" id="formatbar_Buttons"&gt;&lt;span class="on down" style="display: block;" id="formatbar_CreateLink" title="Enlace" onmouseover="ButtonHoverOn(this);" onmouseout="ButtonHoverOff(this);" onmouseup="" onmousedown="CheckFormatting(event);FormatbarButton('richeditorframe', this, 8);ButtonMouseDown(this);"&gt;&lt;img src="http://www.blogger.com/img/blank.gif" alt="Enlace" class="gl_link" border="0" /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Para el caso particular de ruby, cuando se da, por ejemplo, el caso del desarrollo de una plataforma que ejecuta dinamicamente codigo enviado por muchos usuarios... es esperable que este codigo no pueda acceder al sistema de archivos o a la bases de datos de la aplicacion (el caso de una aplicacion Rails). En ese caso un "sandbox" que encierre al codigo en su ejecucion restringiria la ejecucion de codigo no deseado.&lt;br /&gt;&lt;br /&gt;En lo que se ve a simple vista en la web, no hay mucho desarrollo al respecto... y lo que hay pareciera ser plugins algo mas especificos de rails como &lt;a href="http://www.elctech.com/core/safely-exposing-your-app-to-a-ruby-sandbox"&gt;acts_as_runnable_code&lt;/a&gt;. Es por eso que comence el proyecto &lt;a href="http://arena-ruby-sandbox.googlecode.com/"&gt;arena-ruby-sandbox&lt;/a&gt;, que define la posibilidad de ejecutar el codigo asi:&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="ruby"&gt;&lt;br /&gt;require "sandbox"&lt;br /&gt;&lt;br /&gt;class X&lt;br /&gt; def foo(a)&lt;br /&gt;  print "foo(#{a})\n"&lt;br /&gt;&lt;br /&gt;  # estoy afuera del sandbox, por lo tanto puedo&lt;br /&gt;  # hacer cosas "privilegiadas" como crear archivos&lt;br /&gt;  # cosa que no puede hacerse desde adentro del sandbox&lt;br /&gt;  File.open("foo.txt") do |f|&lt;br /&gt;   f.write "foo(#{a})\n"&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  a+5&lt;br /&gt; end&lt;br /&gt;&lt;br /&gt; def foo_no_invocable&lt;br /&gt;  print "foo_no_invocable\n"&lt;br /&gt; end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;# instanciar el sandbox&lt;br /&gt;s = Sandbox::Sandbox.new&lt;br /&gt;&lt;br /&gt;x = X.new&lt;br /&gt;&lt;br /&gt;s.serivice_provider = x&lt;br /&gt;# indica que el metodo foo se puede ejecutar desde adentro del sandbox&lt;br /&gt;s.permit :foo&lt;br /&gt;&lt;br /&gt;print s.run("2+2") # =&gt; 4&lt;br /&gt;&lt;br /&gt;print s.run("foo(2)") # =&gt; 7 (y escribe el archivo foo.txt con "foo(2)" )&lt;br /&gt;&lt;br /&gt;print s.run("foo_no_invocable") # =&gt; NoMethodError (nunca se especifico que foo_no_invocable se podia invocar)&lt;br /&gt;&lt;br /&gt;s.run("&lt;br /&gt; File.open('foo.txt') do |f|&lt;br /&gt;  f.write \"foo\n\"&lt;br /&gt; end&lt;br /&gt;")  # =&gt; NameError: uninitialized constant File&lt;br /&gt;  # ( la clase File no existe adentro del sandbox&lt;br /&gt;  # no se puede acceder al filesystem desde el sandbox&lt;br /&gt;&lt;/pre&gt;links&lt;br /&gt;&lt;br /&gt;&lt;a href="http://arena-ruby-sandbox.googlecode.com"&gt;http://arena-ruby-sandbox.googlecode.com&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-5633398169026360755?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/5633398169026360755/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=5633398169026360755' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/5633398169026360755'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/5633398169026360755'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2009/11/sandbox-de-codigo-ruby.html' title='Sandbox de codigo ruby'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-7630330315503787780</id><published>2009-11-24T20:11:00.005-03:00</published><updated>2009-11-24T20:32:16.250-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><category scheme='http://www.blogger.com/atom/ns#' term='perversion'/><category scheme='http://www.blogger.com/atom/ns#' term='const_missing'/><title type='text'>Autocarga perversa</title><content type='html'>Textualmente, la rdoc del core de ruby, dice asi:&lt;br /&gt;&lt;br /&gt;mod.const_missing(sym) =&gt; obj&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Invoked when a reference is made to an undefined constant in mod. It is passed a symbol for the undefined constant, and returns a value to be used for that constant. The following code is a (very bad) example: if reference is made to an undefined constant, it attempts to load a file whose name is the lowercase version of the constant (thus class Fred is assumed to be in file fred.rb). If found, it returns the value of the loaded class. &lt;span style="font-weight: bold;"&gt;It therefore implements a perverse kind of autoload facility&lt;/span&gt;.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre name="code" class="ruby"&gt;&lt;br /&gt; def Object.const_missing(name)&lt;br /&gt;   @looked_for ||= {}&lt;br /&gt;   str_name = name.to_s&lt;br /&gt;   raise "Class not found: #{name}" if @looked_for[str_name]&lt;br /&gt;   @looked_for[str_name] = 1&lt;br /&gt;   file = str_name.downcase&lt;br /&gt;   require file&lt;br /&gt;   klass = const_get(name)&lt;br /&gt;   return klass if klass&lt;br /&gt;   raise "Class not found: #{name}"&lt;br /&gt; end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Esa funcion puede utilizarse para implementar "alguna clase perversa de mecanismo de autocarga", para citar un ejemplo, rails lo utiliza como parte de su funcionamiento habitual para recargar las clases automaticamente sin necesidad de reiniciar el servidor ni ejecutar ningun comando explicito (¿rails = perversion?, esto me emociona).&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;links&lt;br /&gt;&lt;br /&gt;&lt;a href="http://ruby-doc.org/core/classes/Module.html#M001693"&gt;http://ruby-doc.org/core/classes/Module.html#M001693&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.google.com.ar/search?q=%22It+therefore+implements+a+perverse+kind+of+autoload+facility%22"&gt;http://www.google.com.ar/search?q=%22It+therefore+implements+a+perverse+kind+of+autoload+facility%22&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-7630330315503787780?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/7630330315503787780/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=7630330315503787780' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/7630330315503787780'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/7630330315503787780'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2009/11/autocarga-perversa.html' title='Autocarga perversa'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-4185947849379571065</id><published>2009-11-22T21:06:00.010-03:00</published><updated>2009-11-22T21:18:42.728-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='codepress'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>Web-Base Real Time Syntax Highlighting</title><content type='html'>Codepress es un editor de codigo fuente, que funciona 100% en javascript (del lado del browser) haciendolo muy simple de instalar y utilizar, por ejemplo, pueden editar el siguiente fragmento de codigo:&lt;br /&gt;&lt;br /&gt;NOTA: puede que el highlighting no sea tan "automagico", pero seguro se refresca cada vez que se teclean las comillas dobles... despues cualquier cosa se investiga mas la herramienta...&lt;br /&gt;&lt;br /&gt;NOTA2: Todavia no pude hacer andar bien el editor en el contexto del blog... pero al final estan todos los links a las paginas de prueba que muestran todo el potencial de la herramienta&lt;br /&gt;&lt;br /&gt;&lt;iframe src="http://codepress-test.coolpage.biz/codepress/prueba.html" height=300 width=700 &gt;&lt;br /&gt;&lt;/iframe&gt;  &lt;br /&gt;&lt;br /&gt;Pagina de demo de codepress: &lt;a href="http://bobdawg.org/codepress/"&gt;http://bobdawg.org/codepress/ &lt;/a&gt;&lt;br /&gt;Descarga del paquete: &lt;a href="http://sourceforge.net/projects/codepress/files/codepress/codepress-v.0.9.6/"&gt;http://sourceforge.net/projects/codepress/files/codepress/codepress-v.0.9.6/&lt;/a&gt;&lt;br /&gt;Mi pagina de prueba: &lt;a href="http://codepress-test.coolpage.biz/codepress/prueba.html"&gt;http://codepress-test.coolpage.biz/codepress/prueba.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-4185947849379571065?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/4185947849379571065/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=4185947849379571065' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/4185947849379571065'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/4185947849379571065'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2009/11/web-base-real-time-syntax-highlighting_22.html' title='Web-Base Real Time Syntax Highlighting'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-1360500862865726226</id><published>2009-08-31T10:47:00.007-03:00</published><updated>2011-07-20T18:32:09.218-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='git'/><title type='text'>Tags remotos en git</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Correccion: parametros de git push cambiados para que el envio de la ref sea mas propio&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Otro elemento importante que aporta el versionador git, son los tags... No es muy intuitivo tampoco como hacer que los tags sea remotos, pero es parecido a como se hacen los branches e incluso mas simple (ya que no hay nada que trackear)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;1) Enviar al repositorio central el ref de ese tag (en el ejemplo es el actual commit)&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="bash"&gt;git push origin HEAD:refs/tags/nombre_del_tag&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Este comando envio el "ref" local refs/tags/nombre_del_tag al servidor con el nombre refs/tags/nombre_del_tag&lt;br /&gt;Cuando alguien haga pull del repositorio central recibira los tags y va a poder trabajar con ellos como si los hubieran creado con git tag en su repositorio.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-1360500862865726226?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/1360500862865726226/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=1360500862865726226' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/1360500862865726226'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/1360500862865726226'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2009/08/tags-remotos-en-git.html' title='Tags remotos en git'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-4517704989022848337</id><published>2009-08-31T09:40:00.008-03:00</published><updated>2011-07-20T18:31:18.823-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='git'/><title type='text'>Branches remotos en git</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;a href="http://git.or.cz/"&gt;Git&lt;/a&gt; es un poderoso sistema de gestion de versiones, que entre otras cosas, esta pensado para gestionar branches ( cosa que por ej svn no tiene ), al ser git descentralizado y al ser de uso comun con varios repositorios para un mismo proyecto, surge la necesidad de crear ramas de manera distribuida tambien, algo que no es muy intuitivo.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;1) Con git push se crea el branch en el repositorio remoto (en este caso origin), asi de simple&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="bash"&gt;git push origin HEAD:refs/heads/nombre_del_branch&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;2) Despues tenemos que asegurarnos de tener actualizado el repositorio&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="bash"&gt;git fetch origin&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;3) Verificamos que el branch remoto ha sido creado&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="bash"&gt;git branch -r&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;4) Generar un branch local que "trackee" el branch remoto&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="bash"&gt;git checkout --track -b nombre_del_branch origin/nombre_del_branch&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Ese ultimo comando crea un branch local que "trackea" el branch que se creo antes en el repositorio remoto. Y con trackear implica que los cambios y commits del branch remoto vendran a este branch local al hacer git pull e iran de nuestro branch remoto al hacer git push.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Fuente: &lt;a href="http://www.zorched.net/2008/04/14/start-a-new-branch-on-your-remote-git-repository/"&gt;http://www.zorched.net/2008/04/14/start-a-new-branch-on-your-remote-git-repository/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-4517704989022848337?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/4517704989022848337/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=4517704989022848337' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/4517704989022848337'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/4517704989022848337'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2009/08/branches-remotos-en-git.html' title='Branches remotos en git'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-3130211303901940035</id><published>2009-07-16T23:44:00.003-03:00</published><updated>2009-07-16T23:58:52.848-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='raii'/><title type='text'>Ruby RAII</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;a href="http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization"&gt;RAII (Resource Acquisition Is Initialization)&lt;/a&gt; es una técnica aplicable en muchos lenguajes de programación como C++ y los lengujaes .net que sirve para asegurar que la liberación de un recurso siempre se llevara a cabo al cerrarse un bloque de código sin importar que evento ocurrise (retorno de una funcion, excepcion, etc...).  Ruby por supuesto que cuenta con esta posibilidad a través del uso de métodos con bloques de código (palabra clave yield)&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;He aqui un ejemplo:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="ruby"&gt;&lt;br /&gt;#&lt;br /&gt;# La clase X tiene un metodo open para inicializar (open)&lt;br /&gt;# Y uno para cerrar, seria una tragedia si el metodo open&lt;br /&gt;# se invocara y no se invoque el close correspondiente al final&lt;br /&gt;#&lt;br /&gt;#&lt;br /&gt;class X&lt;br /&gt; def open( argument1, argument2 )&lt;br /&gt;  print "open with argument1=#{argument1} and argument2=#{argument2}\n"&lt;br /&gt; end&lt;br /&gt;&lt;br /&gt; def operation1&lt;br /&gt;  print "running operation1\n"&lt;br /&gt; end&lt;br /&gt;&lt;br /&gt; def operation2&lt;br /&gt;  print "running operation2\n"&lt;br /&gt; end&lt;br /&gt;&lt;br /&gt; def close&lt;br /&gt;  print "closing\n"&lt;br /&gt; end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;#&lt;br /&gt;# Mejor usar RAII&lt;br /&gt;#&lt;br /&gt;&lt;br /&gt;class X&lt;br /&gt; def self.open( *args )&lt;br /&gt;  x_instance = X.new&lt;br /&gt;  x_instance.open( *args )&lt;br /&gt;  begin&lt;br /&gt;   yield(x_instance)&lt;br /&gt;  ensure&lt;br /&gt;   x_instance.close&lt;br /&gt;  end&lt;br /&gt; end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;#&lt;br /&gt;# Y se usa asi&lt;br /&gt;#&lt;br /&gt;X.open( "arg1", "arg2" ) do |x|&lt;br /&gt; x.operation1&lt;br /&gt; x.operation2&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Espero que os haya iluminado&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-3130211303901940035?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/3130211303901940035/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=3130211303901940035' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/3130211303901940035'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/3130211303901940035'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2009/07/ruby-raii.html' title='Ruby RAII'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-646337622238798193</id><published>2009-06-23T11:19:00.003-03:00</published><updated>2009-06-23T11:25:03.607-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='NilClass'/><title type='text'>NilClass horror</title><content type='html'>Un horror&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name='code' class='ruby'&gt;&lt;br /&gt;&lt;br /&gt;# el nil class es la clase de la cual nil es instancia&lt;br /&gt;class NilClass&lt;br /&gt;  # todo metodo desconocido que es invocado sobre el nil&lt;br /&gt;  def method_missing(method_obj,*args)&lt;br /&gt;     method_obj.to_s&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;print nil.koiiiewiiriieiw,"\n"&lt;br /&gt;&lt;br /&gt;print @oooooooooooooooooooooo.blahhhhhhhhhhhhhhhhhhhhhhhhh,"\n"&lt;br /&gt;print @ewewewwwewo.dakishimetakokoronokusumo,"\n"&lt;br /&gt;&lt;br /&gt;# un horror&lt;br /&gt;print $uqhwuiqwhrqrqwrkjwqhrjkqwhrqwkjrhqwrjkwqrhkqwrjqwrj.l,"\n"&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Un horror&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-646337622238798193?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/646337622238798193/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=646337622238798193' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/646337622238798193'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/646337622238798193'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2009/06/nilclass-horror.html' title='NilClass horror'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-5820042321896568617</id><published>2009-06-21T14:10:00.002-03:00</published><updated>2009-06-21T14:34:40.159-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><title type='text'>Comparacion de rangos</title><content type='html'>Es muy común al programar, encontrarse con la necesidad de verificar algún rango de algo:&lt;br /&gt;&lt;br /&gt;&lt;pre name='code' class='ruby'&gt;&lt;br /&gt;# la manera "dificil"&lt;br /&gt;if a &gt; 3 and a &lt; 9 then&lt;br /&gt;   print "a esta entre 3 y 9\n"&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Mejor asi, usando el operador === &lt;br /&gt;&lt;br /&gt;&lt;pre name='code' class='ruby'&gt;&lt;br /&gt;# la manera "canchera"&lt;br /&gt;if (3..9) === a then&lt;br /&gt;   print "a esta entre 3 y 9\n"&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Como si esto fuera poco, el operador === tiene todos los usos que uno se pueda imaginar, como por ej, para verificar si un texto matchea una expresion regular:&lt;br /&gt;&lt;br /&gt;&lt;pre name='code' class='ruby'&gt;&lt;br /&gt;# la manera "canchera"&lt;br /&gt;if  /^ruby/ === txt then&lt;br /&gt;   print "'#{txt}' tiene ruby al principio\n"&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Y si se les da la gana, pueden usar este operador en sus propias clases (también obviamente definirlo o redefinirlo para la clase existente que quieran)&lt;br /&gt;&lt;br /&gt;&lt;pre name='code' class='ruby'&gt;&lt;br /&gt;&lt;br /&gt;class X&lt;br /&gt;   def ===(a)&lt;br /&gt;      print a,"\n"&lt;br /&gt;   end&lt;br /&gt;end&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/1354794578842586233-5820042321896568617?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/5820042321896568617/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=5820042321896568617' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/5820042321896568617'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/5820042321896568617'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2009/06/comparacion-de-rangos.html' title='Comparacion de rangos'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-2580695125064898681</id><published>2009-06-05T10:33:00.004-03:00</published><updated>2009-06-05T10:56:41.187-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='sugar'/><category scheme='http://www.blogger.com/atom/ns#' term='blackmagic'/><category scheme='http://www.blogger.com/atom/ns#' term='hooking'/><title type='text'>Ruby hooking</title><content type='html'>&lt;div style="text-align: justify;"&gt;Les traigo un truco que los asombrara... con una tenica de &lt;a href="http://en.wikipedia.org/wiki/Hooking"&gt;hooking&lt;/a&gt; aplicada al ruby para poder enganchar los metodos que quieran de cualquier objeto y controlar su ejecucion, asi como registrar llamados a ese metodo , filtrar cosas, etc.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Aca el module q lo hace posible:&lt;br /&gt;&lt;br /&gt;hooking.rb&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="ruby"&gt;&lt;br /&gt;module Hook&lt;br /&gt; def hook( method_name, hook_name = nil, old_method_name = nil)&lt;br /&gt;  &lt;br /&gt;  obj = self&lt;br /&gt;  &lt;br /&gt;  # si no se le pasa el nombre de la funcion que controla el hook&lt;br /&gt;  # arma un nombre de funcion&lt;br /&gt;  hook_name ||= "#{method_name}_hook" &lt;br /&gt;  &lt;br /&gt;  #lo mismo con el nombre de la variable de instancia&lt;br /&gt;  # que almacena la referencia al metodo original&lt;br /&gt;  old_method_name ||= "__old__#{method_name}"&lt;br /&gt;  &lt;br /&gt;  # almacenar el metodo original&lt;br /&gt;  eval("@#{old_method_name} = self.method( method_name.to_sym)")&lt;br /&gt;  &lt;br /&gt;  # redefinir el metodo para que invoque el metodo de hook, pasandole&lt;br /&gt;  # un bloque de codigo que ejecute el metodo original, entonces el metodo&lt;br /&gt;  # de hook puede invocar al metodo original usando yield&lt;br /&gt;  eval("&lt;br /&gt;  def obj.#{method_name}(*x)&lt;br /&gt;   self.#{hook_name}(@#{old_method_name},*x) do |*x|&lt;br /&gt;    yield(*x) if block_given?&lt;br /&gt;   end&lt;br /&gt;  end&lt;br /&gt;  ")&lt;br /&gt;  &lt;br /&gt; end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;class Object&lt;br /&gt; # includir el modulo de Hook en Object para que se pueda aplicar a todo Object&lt;br /&gt; include Hook&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Y ahora un pequeño ejemplo de como podria usarse&lt;br /&gt;&lt;br /&gt;main.rb&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="ruby"&gt;&lt;br /&gt;require "hooking"&lt;br /&gt;&lt;br /&gt;class X&lt;br /&gt;&lt;br /&gt; def foo( num )&lt;br /&gt;  print "metodo foo invocado con num = #{num}\n"&lt;br /&gt; end&lt;br /&gt; &lt;br /&gt; def bar &lt;br /&gt;  print "metodo bar invocado\n"&lt;br /&gt;  [1,2,3].each do |x| yield(x) end&lt;br /&gt; end&lt;br /&gt; &lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;x = X.new&lt;br /&gt;&lt;br /&gt;x.hook(:foo)&lt;br /&gt;&lt;br /&gt;def x.foo_hook( foo_original, num )&lt;br /&gt; print "foo invocado\n"&lt;br /&gt; &lt;br /&gt; # se invoca al metodo original, pero alterando los parametros&lt;br /&gt; foo_original.call( num+1)&lt;br /&gt; &lt;br /&gt; print "fin de foo\n"&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;x.hook :bar&lt;br /&gt;def x.bar_hook(  bar_original )&lt;br /&gt; &lt;br /&gt; print "bar invocado\n"&lt;br /&gt; &lt;br /&gt; bar_original.call do |x|&lt;br /&gt;                # tambien se puede alterar y controlar&lt;br /&gt;                # el uso de yield del metodo&lt;br /&gt;  yield(x+2)&lt;br /&gt; end&lt;br /&gt; &lt;br /&gt; print "fin de bar\n"&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;x.foo(3)&lt;br /&gt;x.bar do |x|&lt;br /&gt; print x,"\n"&lt;br /&gt;end&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/1354794578842586233-2580695125064898681?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/2580695125064898681/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=2580695125064898681' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/2580695125064898681'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/2580695125064898681'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2009/06/ruby-hooking.html' title='Ruby hooking'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-7810892927725116356</id><published>2009-06-03T23:19:00.002-03:00</published><updated>2009-06-03T23:21:21.934-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rubik'/><title type='text'>Me olvide de mostrarles el mirror rubik</title><content type='html'>Salio hace com 80 mil años, jaja, vean este video:&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/MoVtjLZhOAU&amp;hl=es&amp;fs=1&amp;"&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/MoVtjLZhOAU&amp;hl=es&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;Y el video REVIEW:&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/HN8Ej0rc4VU&amp;hl=es&amp;fs=1&amp;"&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/HN8Ej0rc4VU&amp;hl=es&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-7810892927725116356?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/7810892927725116356/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=7810892927725116356' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/7810892927725116356'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/7810892927725116356'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2009/06/me-olvide-de-mostrarles-el-mirror-rubik.html' title='Me olvide de mostrarles el mirror rubik'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-304156696686031084</id><published>2009-04-21T14:04:00.008-03:00</published><updated>2009-04-21T14:27:35.514-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='boludeces'/><category scheme='http://www.blogger.com/atom/ns#' term='humor'/><title type='text'>Programacion ruby EN un celular :p</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_T12nVzD4aEs/Se4BrawynzI/AAAAAAAAAB8/F3YcGG5LBVM/s1600-h/h2620_marcado.JPG"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 219px; height: 228px;" src="http://4.bp.blogspot.com/_T12nVzD4aEs/Se4BrawynzI/AAAAAAAAAB8/F3YcGG5LBVM/s320/h2620_marcado.JPG" alt="" id="BLOGGER_PHOTO_ID_5327197254655844146" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;&lt;div style="text-align: justify;"&gt;No pude evitar observar la palabra clave del ruby "def" (se usa para DEFinir metodos en ruby) en una de las teclas del celular, asi que imagine: esto esta pensado para programadores de ruby, en seguida me puse a pensar como seria programar EN un celular:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="ruby"&gt;&lt;br /&gt;# para pner cmtrios ay q scrbrlos tods asi&lt;br /&gt;# est mtodo c pue d usr cmo print&lt;br /&gt;def abc(ghi)&lt;br /&gt;print ghi,"\n"&lt;br /&gt;#porq noay na tcla cn "end" en l celu?&lt;br /&gt;end&lt;br /&gt;abc "hla mndo!"&lt;br /&gt;abc "cmo ests"&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/1354794578842586233-304156696686031084?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/304156696686031084/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=304156696686031084' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/304156696686031084'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/304156696686031084'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2009/04/programacion-ruby-en-un-celular-p.html' title='Programacion ruby EN un celular :p'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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/_T12nVzD4aEs/Se4BrawynzI/AAAAAAAAAB8/F3YcGG5LBVM/s72-c/h2620_marcado.JPG' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1354794578842586233.post-6521631469079935528</id><published>2009-03-15T16:03:00.011-03:00</published><updated>2009-03-18T11:15:50.733-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='dev'/><category scheme='http://www.blogger.com/atom/ns#' term='git'/><category scheme='http://www.blogger.com/atom/ns#' term='git-svn'/><category scheme='http://www.blogger.com/atom/ns#' term='svn'/><title type='text'>Aprendiendo git-svn en 5 minutos</title><content type='html'>&lt;div style="text-align: justify;"&gt;Este finde estuve viendo las posibilidades que tiene git-svn, nunca use git pero me llamo mucho la atención el manejo que tiene de múltiples repositorios, cuya primera utilidad que le vi es poder trabajar "offline", es decir, sin acceso al repositorio central, y mantener la granularidad de los commits ya que se puede commitear al repositorio "local" cuantas veces se quiera hasta que en un momento se mandan todos los commits en un "push". En el caso de git-svn, se pueden visualizar y analizar en los logs del servidor SVN cada uno de esos commits como si hubiese mandando cada uno de ellos de manera "normal". git-svn también puede ser de agrado para los fanáticos de git cuando se vean forzados a trabajar con un repo svn y seguramente tiene un sin-fin de utilidades mas.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Actualizacion:&lt;/b&gt; Usuarios de svn pueden aprender git de una manera muy facil en &lt;a href="http://git.or.cz/course/svn.html"&gt;Git - Svn Crash Course&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Lo primero y principal para utilizar esta herramienta es instalarla, yo que uso fedora, me basto con:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre name="code" class="ruby"&gt;&lt;br /&gt;yum install git-svn&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Seguramente, para los usuarios de debian y afines sera suficiente (corrijanme si me equivoco):&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre name="code" class="ruby"&gt;&lt;br /&gt;apt-get install git-svn&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Posteriormente, se aprende como utilizar la herramienta para clonar un repositorio SVN para los usuarios de git, o "checkautear" usando git, para los usuarios de svn:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre name="code" class="ruby"&gt;&lt;br /&gt;git-svn clone $URL&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Donde $URL es la url completa del servidor svn como "file:///usr/srv/svn/proyecto" o "http:///www.websvn.com/svn/proyecto", lo que hace el comando, es crear una copia local del repositorio SVN, al estilo de git, esto equivale al checkout de svn y por lo tanto solo debe hacerse la primera vez, obviamente es necesario tener acceso al repositorio para poder hacer esto&lt;br /&gt;&lt;br /&gt;A partir de haber clonado el repositorio, ya se puede trabajar con el repositorio local, para los que sean usuarios de git es simple: es lo mismo que en git (guarda al final que no se pushean los cambios de la misma manera), y para los que no conocen el maravilloso mundo de git, también es sencillo, simplemente hay que ejecutar el siguiente comando con cada commit:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre name="code" class="ruby"&gt;&lt;br /&gt;git commit archivo -m 'mensaje' &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;El comando es igualito al de svn, pero tengan presente de que este comando "commitea" solo al repositorio local, el que se clono al principio, asi mismo NO requiere acceso al repositorio ni ninguna conexión con el, pueden hacer este commit todas las veces que hagan faltan sin necesidad de contactar al repositorio.&lt;br /&gt;&lt;br /&gt;Cuando logran conexión con el repositorio o cuando lo crean conveniente, llega la hora de hacer el "push" (mandar todos los commits que se hicieron local al repositorio central), el comando el siguiente:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre name="code" class="ruby"&gt;&lt;br /&gt;git-svn dcommit&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Cuando ejecuten el comando, verán como git-svn manda cada commit que se efecto localmente desde la que se clono el repo o se hizo el ultimo dcommit, y lo mas importante, lo que da todo el sentido a esto: a cada commit que efectuaste con "git commit", le corresponde UN commit de svn que puede analizarse y verse en los logs del servidor svn por cualquier otro usuario y con las herramientas svn clásicas.&lt;br /&gt;&lt;br /&gt;Bueno, esto fue git-svn para Fedora 32 y espero que les haya gustado. Chau!!!&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/1354794578842586233-6521631469079935528?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/6521631469079935528/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=6521631469079935528' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/6521631469079935528'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/6521631469079935528'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2009/03/aprendiendo-git-svn-en-5-minutos.html' title='Aprendiendo git-svn en 5 minutos'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-5154189205057141559</id><published>2009-03-11T22:10:00.002-02:00</published><updated>2009-03-11T22:22:12.476-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='blog'/><title type='text'>Try ruby (in the NilClass Blog)</title><content type='html'>Cableando algunos iframe por ahi logre incorporar el interprete de ruby que anuncie en el post anterior directamente inscrustado en ell blog, para ahorrarles ir a la otra pagina ;), prueben el ruby!!!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-5154189205057141559?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/5154189205057141559/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=5154189205057141559' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/5154189205057141559'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/5154189205057141559'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2009/03/try-ruby-in-nilclass-blog.html' title='Try ruby (in the NilClass Blog)'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-6136860583802352604</id><published>2009-03-11T21:37:00.003-02:00</published><updated>2011-11-12T13:11:17.547-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><title type='text'>Try ruby! (in your browser)</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;b&gt;Actualizacion: la nueva direccion de tryruby es &lt;/b&gt;&lt;a href="http://tryruby.org/"&gt;http://tryruby.org/&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Buscando algun applet o algo asi para acercarles el ruby en este blog para que puedan palpar la magia de ruby sin nececidad de que se instalen nada, me encontre con &lt;a href="http://tryruby.org/"&gt;http://tryruby.org/&lt;/a&gt;, una pagina muy curiosa que te ofrece un tutorial de ruby con interprete incluido en la pagina!, es decir, podes aprender ruby como &lt;a href="http://es.wikipedia.org/wiki/Yukihiro_Matsumoto"&gt;Yukihiro&lt;/a&gt; manda sin necesidad de bajarte ni instalar nada. En lo proximo.&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/1354794578842586233-6136860583802352604?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/6136860583802352604/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=6136860583802352604' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/6136860583802352604'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/6136860583802352604'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2009/03/blog-post.html' title='Try ruby! (in your browser)'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-1535225404305503158</id><published>2009-03-07T00:01:00.005-02:00</published><updated>2009-03-07T00:24:33.436-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mental'/><category scheme='http://www.blogger.com/atom/ns#' term='rsif'/><category scheme='http://www.blogger.com/atom/ns#' term='freemind'/><category scheme='http://www.blogger.com/atom/ns#' term='desarrollo'/><category scheme='http://www.blogger.com/atom/ns#' term='jugo'/><title type='text'>FreeMind, la exprimidora de jugo mental</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_T12nVzD4aEs/SbHaHGMa_eI/AAAAAAAAABM/EUkX7X4H9nQ/s1600-h/rsif.jpeg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 320px; height: 238px;" src="http://2.bp.blogspot.com/_T12nVzD4aEs/SbHaHGMa_eI/AAAAAAAAABM/EUkX7X4H9nQ/s320/rsif.jpeg" alt="" id="BLOGGER_PHOTO_ID_5310265251103178210" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;El Jueves que pasado, tratando de hacer algo bueno para el &lt;a href="http://rsif.blogspot.com/"&gt;rsif&lt;/a&gt;, no se me ocurria que cosa buena programar, ni ninguna parte del soft que diseñar, ni siquiera ideas que documentar. Ocasion ideal para utilizar la aplicacion que les voy a comentar: se trata del &lt;a href="http://freemind.sourceforge.net/wiki/index.php/Main_Page"&gt;Freemind&lt;/a&gt;. El freemind es un programa que te permite hacer brainstorming, es decir, volcar a algun lugar las ideas flotando en la intangibilidad de la conciencia antes de que migren a olvidolandia, tambien permite multiplicar facilmente las ideas de varios participantes en un grupo de trabajo. Para poder hacer eso, te permite crear "mapas" que son arboles (como el que se ve en la imagen) o una "mariposa" lleno de ideas que descargas directo de tu atormetado cerebro (o varios cerebros si es un grupo) por intermedio del teclado y mouse; los nodos del arbol que podes ir armando, contienen simplemente cualquier texto que se quiera poner, a los que se le pueden añadir cualquier cantidad de iconos. Al final, se obtendra como resultado un map "mariposa" cuyas alas estan hechas de las ideas que se crearon/escribieron y cuya utilidad es obvia.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Sitio oficial de freemind: &lt;a href="http://freemind.sourceforge.net/"&gt;http://freemind.sourceforge.net&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-1535225404305503158?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/1535225404305503158/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=1535225404305503158' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/1535225404305503158'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/1535225404305503158'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2009/03/freemind-la-exprimidora-de-jugo-mental.html' title='FreeMind, la exprimidora de jugo mental'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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/_T12nVzD4aEs/SbHaHGMa_eI/AAAAAAAAABM/EUkX7X4H9nQ/s72-c/rsif.jpeg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1354794578842586233.post-8851587645461364139</id><published>2009-03-05T21:42:00.005-02:00</published><updated>2009-03-05T22:09:13.480-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pentaminx'/><category scheme='http://www.blogger.com/atom/ns#' term='rubik'/><title type='text'>El pentaminx es una cosa de locos</title><content type='html'>&lt;div style="text-align: justify;"&gt;Es un rubik pero en version dodecaedro diabolico (con pentagrama en cada cara), por si el V-cube 6 del &lt;a href="http://nilclass.blogspot.com/2009/02/v-cube-6x6x6-resuelto-en-3-minutos-y-28.html"&gt;post anterior&lt;/a&gt; te parecia para bebes, podes disfrutar del reto que ofrece el Pentaminx, el cual consta de 12 hyper-enfermizas caras dividas en aproximadamente 100 partes de las cuales 20 de ellas son secciones de las puntas de la estrella central y una es un pentagono interior. El mounstruo esta hecho de un total de 975 piezas, y se dice que el record mundial de resolucion mas rapida fue de 75 horas&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;object width="637" height="516"&gt;&lt;param name="movie" value="http://www.youtube.com/v/ZLyFqm4D9tI&amp;amp;hl=es&amp;amp;fs=1"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/ZLyFqm4D9tI&amp;amp;hl=es&amp;amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-8851587645461364139?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/8851587645461364139/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=8851587645461364139' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/8851587645461364139'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/8851587645461364139'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2009/03/el-pentaminx-es-una-cosa-de-locos.html' title='El pentaminx es una cosa de locos'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-5640324879159872018</id><published>2009-03-04T21:29:00.004-02:00</published><updated>2009-03-04T21:42:52.220-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='finales'/><category scheme='http://www.blogger.com/atom/ns#' term='rsif'/><title type='text'>De finales a RSIF</title><content type='html'>&lt;div style="text-align: justify;"&gt;Complete la agonizante fase de examenes, sin entrar en detalles como me fue, solo voy a decir que lo unico que me interesa es volver al proyecto de &lt;a href="http://rsif.googlecode.com/"&gt;rsif&lt;/a&gt;, la vuelta a rsif va a ser con un nuevo planteo el cual van a poder conocer leyendo el &lt;a href="http://rsif.blogspot.com/"&gt;blog de rsif&lt;/a&gt; e implicara cambios muy importantes acerca de la metodologia de desarrollo apuntando a mejorar el uso, la utilidad, la flexibilidad y lograr objetivos practicos con el framework.&lt;br /&gt;&lt;br /&gt;El proyecto hara ignicion en un mega-post tras algunos dias de meditacion extrema, ruby testing y filosofia ruby  &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-5640324879159872018?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/5640324879159872018/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=5640324879159872018' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/5640324879159872018'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/5640324879159872018'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2009/03/de-finales-rsif.html' title='De finales a RSIF'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-4725571191745606832</id><published>2009-02-12T15:35:00.004-02:00</published><updated>2010-06-13T18:51:01.830-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vcube'/><category scheme='http://www.blogger.com/atom/ns#' term='rubik'/><title type='text'>V-Cube 6x6x6 Resuelto en 3 minutos y 28 segundos</title><content type='html'>Este chabon resuelve el V-Cube de 6x6x6 en 3 minutos y 28 segundos, por si no lo sabían, el de 6x6x6  existe materialmente e incluso hay algunos como los del video que resuelven asi:&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/eiMzqjKmILI&amp;hl=en&amp;fs=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/eiMzqjKmILI&amp;hl=en&amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-4725571191745606832?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/4725571191745606832/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=4725571191745606832' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/4725571191745606832'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/4725571191745606832'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2009/02/v-cube-6x6x6-resuelto-en-3-minutos-y-28.html' title='V-Cube 6x6x6 Resuelto en 3 minutos y 28 segundos'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-162970867333657628</id><published>2009-02-11T17:17:00.004-02:00</published><updated>2009-02-11T17:26:51.902-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='redes'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='vpn'/><category scheme='http://www.blogger.com/atom/ns#' term='openvpn'/><title type='text'>openVPN temporal rapida y practica en linux</title><content type='html'>Con estos comandos, pueden crear una vpn de manera muy rápida y sencilla con openvpn, y sin necesidad de "configuración", si por alguna urgencia necesitan vpn...&lt;br /&gt;&lt;br /&gt;En el server:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="ruby"&gt;&lt;br /&gt;openvpn --proto tcp-server --lport 9000 --dev tun0 --ifconfig 10.4.0.1 10.4.0.2&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;En el client&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="ruby"&gt;&lt;br /&gt;openvpn --proto tcp-client --rport 9000 --remote DIRECCIONIPREMOTA --dev tun0 --ifconfig 10.4.0.2 10.4.0.1&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;NOTA: asegúrense de que no colisionen las ips del ifconfig y que los puertos sean accesibles (en el ejemplo el 9000), &lt;br /&gt;&lt;br /&gt;NOTA: pueden no especificar el proto, y utiliza el protoclo por defecto UDP&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-162970867333657628?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/162970867333657628/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=162970867333657628' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/162970867333657628'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/162970867333657628'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2009/02/openvpn-temporal-rapida-y-practica-en.html' title='openVPN temporal rapida y practica en linux'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-3518188563317121500</id><published>2009-02-11T14:51:00.003-02:00</published><updated>2009-02-11T14:59:23.025-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><title type='text'>Forma elegante de expresar el codigo ascii de un caracter especifico</title><content type='html'>Simplemente hay que utilizar el operando "?", anteponiendo lo al carácter del cual se quiere obtener el código ASCII, en el siguiente ejemplo se usa "?A" para obtener el código ASCII de la letra A mayúscula&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="ruby"&gt;&lt;br /&gt;# el abecedario en mayúsculas&lt;br /&gt;# la funcion chr convierte un numero al carácter que representa en ASCII&lt;br /&gt;print (0..25).map{|x| (?A+x).chr}.join(" ")&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/1354794578842586233-3518188563317121500?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/3518188563317121500/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=3518188563317121500' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/3518188563317121500'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/3518188563317121500'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2009/02/forma-elegante-de-expresar-el-codigo.html' title='Forma elegante de expresar el codigo ascii de un caracter especifico'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-2016806937203349486</id><published>2009-02-06T15:43:00.005-02:00</published><updated>2009-02-06T15:47:34.929-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='trucos'/><title type='text'>Ampliar la funcionalidad de una clase existente</title><content type='html'>Hola, estamos viendo el ruby para PC, y hoy les voy a pasar un truco para agregarle funcionalidad a una clase ya existente en el lenguaje (también otra que se haya definido de la manera que sea, puede ser extendida )&lt;br /&gt;&lt;br /&gt;  Supongamos que no nos gusta que el metodo para convertir a entero de la clase String, se llame to_i, y nos parece mejor idea que se llame to_integer&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="ruby"&gt;&lt;br /&gt;&lt;br /&gt;class String&lt;br /&gt;   def to_integer&lt;br /&gt;      to_i&lt;br /&gt;   end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;print "99".to_integer + 1, "\n"&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Lo que hicimos fue definir de manera parcial la clase String, esto es, definirle los métodos que queramos a String, obviamente manteniendo también los métodos originales de la clase String&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Bueno, esto fue ruby para PC, y espero que les haya gustado, chau&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-2016806937203349486?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/2016806937203349486/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=2016806937203349486' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/2016806937203349486'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/2016806937203349486'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2009/02/ampliar-la-funcionalidad-de-una-clase.html' title='Ampliar la funcionalidad de una clase existente'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-5279534025195079593</id><published>2009-02-06T11:56:00.004-02:00</published><updated>2009-02-06T12:24:48.959-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='yield'/><title type='text'>Usa yield, por que si no lo usas se oxida</title><content type='html'>&lt;div style="text-align: justify;"&gt;Sin duda, yield es un elemento muy poderoso de estos lenguajes de programación "modernos", en definitiva, lo que yield hace es invocar el bloque de código que se le paso por parámetro a un método especifico. Un ejemplo&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="ruby"&gt;&lt;br /&gt;&lt;br /&gt;def foo(x)&lt;br /&gt;   if x &lt; 3&lt;br /&gt;      yield&lt;br /&gt;   end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;foo(2) { print "hola mundo" }&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Con la sola definición de yield no es sencillo darse cuenta rápidamente de como podría aplicarse, pero para que se den una idea, todos los métodos del array que reciben bloques estan implementados  usando yield, estos son (entre otros), each, inject, select, find, etc..., también métodos como &lt;a href="http://www.ruby-doc.org/core/classes/Mutex.html"&gt;synchronize del mutex&lt;/a&gt; usan yield con propósitos de &lt;a href="http://en.wikipedia.org/wiki/Resource_acquisition_is_initialization"&gt;RAII&lt;/a&gt; y con un sin fin de aplicaciones. Aca otro ejemplo:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre name="code" class="ruby"&gt;&lt;br /&gt;&lt;br /&gt;# compone cualquier funcion dos veces, toma como inicio el parámetro&lt;br /&gt;def compdouble(x)&lt;br /&gt;  yield(yield(x))&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;# devuelve x*x*x*x = 81 (composicion doble de x*x)&lt;br /&gt;print compdouble(3){ |x| x*x }, "\n"&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;también puede servir para pasar expresiones como parámetros, que solo seran evaluadas si se necesitan, la siguiente idea se aplico en el logger de &lt;a href="http://rsif.googlecode.com/"&gt;rsif&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre name="code" class="ruby"&gt;&lt;br /&gt;&lt;br /&gt;# invocamos logger.info con parametro normal, entonces el&lt;br /&gt;# interprete siempre evalúa la expresión&lt;br /&gt;# para pasarle el parámetro a logger.info,&lt;br /&gt;#sin importar si logger info vaya a loguear o no&lt;br /&gt;# aveces evaluar determinadas expresiones conlleva&lt;br /&gt;# a invocar metodos, accesar a bases de datos,&lt;br /&gt;# hacer calculos, etc..&lt;br /&gt;&lt;br /&gt;logger.info Locale.hello_world&lt;br /&gt;&lt;br /&gt;# Es mejor si en lugar de pasarle el paremetro&lt;br /&gt;# normalmente, se lo pasemos en un bloque&lt;br /&gt;# entonces el bloque solo sera invocado&lt;br /&gt;# si el parametro necesita ser evaluado, es decir&lt;br /&gt;# cuando el metodo decida que va a loguearlo, definitivamente&lt;br /&gt;&lt;br /&gt;logger.info { Locale.hello_world } # las llaves hacen que se pase el bloque de código&lt;br /&gt;&lt;br /&gt;# pseudo-codigo resumido de logger.info:&lt;br /&gt;&lt;br /&gt;def logger.info( x = nil )&lt;br /&gt;  if loguear&lt;br /&gt;     if block_given?&lt;br /&gt;         print yield,"\n"&lt;br /&gt;     else&lt;br /&gt;         print x,"\n"&lt;br /&gt;     end&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Otro ejemplo es la &lt;a href="http://www.dmh2000.com/cjpr/"&gt;implementación de visitor pattern usando ruby&lt;/a&gt;, con yield es muy cómoda de implementar y también de usar (el link que les pase hace la comparativa entre la implementación de lo mismo en varios lenguajes)&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Espero que les haya sido de utilidad, hasta el próximo post&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-5279534025195079593?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/5279534025195079593/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=5279534025195079593' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/5279534025195079593'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/5279534025195079593'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2009/02/usa-yield-por-que-si-no-lo-usas-se.html' title='Usa yield, por que si no lo usas se oxida'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-7144766554269748380</id><published>2009-02-02T19:12:00.004-02:00</published><updated>2009-02-03T10:57:25.629-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='security'/><title type='text'>¿Porque pasa? Grave vulnerabilidad de ejecucion de codigo en el kernel 2.6.28 (y otros)</title><content type='html'>Asi como le escucharon, salio un nueva vulnerabilidad del kernel 2.6.28 con impacto de ejecución remota de código ( o Denial of service, segun el caso ),  aca una copia de la nota original, de &lt;a href="http://www.watchmouse.com/es/security_news/Linux-Kernel-FWD-TSN-Chunk-Remote-Buffer-Overflow-Vulnerability.html"&gt;watchmouse&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;------------------------------------------------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;The Linux Kernel is prone to a remote buffer-overflow vulnerability because the software fails to perform adequate boundary checks on user-supplied data.&lt;br /&gt;&lt;br /&gt;An attacker can exploit this issue to execute arbitrary code with kernel-level privileges. Successfully exploiting this issue will result in the complete compromise of affected computers. Failed exploit attempts will result in a denial-of-service condition.&lt;br /&gt;&lt;br /&gt;The issue affects Linux Kernel 2.6.28; other versions may also be vulnerable.&lt;br /&gt;------------------------------------------------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Que bueno que en el software libre estas cosas se corrigen rapido, lo mas que podemos hacer es actualizar el kernel y ya hay una versión patcheada, o parchearlos nosotros mismos si esta a nuestro alcance&lt;br /&gt;&lt;br /&gt;La nota original de la pueden leer &lt;a href="http://www.watchmouse.com/es/security_news/Linux-Kernel-FWD-TSN-Chunk-Remote-Buffer-Overflow-Vulnerability.html"&gt;aca&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;En &lt;a href="http://www.securityfocus.com/bid/33113"&gt;securityfocus&lt;/a&gt; pueden ver mas información acerca de la vulnerabilidad, las versiones afectadas del kernel, etc...&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.net-security.org/vuln.php?id=6775"&gt;net-security&lt;/a&gt; también publico una nota&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-7144766554269748380?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/7144766554269748380/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=7144766554269748380' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/7144766554269748380'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/7144766554269748380'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2009/02/porque-pasa-grave-vulnerabilidad-de.html' title='¿Porque pasa? Grave vulnerabilidad de ejecucion de codigo en el kernel 2.6.28 (y otros)'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-1269670033916554882</id><published>2009-01-31T00:50:00.003-02:00</published><updated>2009-01-31T00:57:38.778-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='blog'/><category scheme='http://www.blogger.com/atom/ns#' term='rsif'/><title type='text'>Comenzo el proyecto RSIF (hace un rato)</title><content type='html'>&lt;div style="text-align: justify;"&gt;      Buscando una excusa interesante para hacer un proyecto en ruby, me encontre con que no habia ninguna herramienta de sql injection automatizado (hecha por mi). De ahi que comenze con el proyecto &lt;a href="http://rsif.googlecode.com/"&gt;Rsif&lt;/a&gt;. Rsif significa Rsif Sql Injection Framework, y es lo que dice (o mejor dicho, quiere ser :p ), y lo mas orientado posible a la participacion de cualquiera.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;            Si quieren mas informacion, pasense por el &lt;a href="http://rsif.blogspot.com/"&gt;blog de rsif&lt;/a&gt;, que es el que motivo este articulo, en primer lugar&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-1269670033916554882?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/1269670033916554882/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=1269670033916554882' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/1269670033916554882'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/1269670033916554882'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2009/01/comenzo-el-proyecto-rsif-hace-un-rato.html' title='Comenzo el proyecto RSIF (hace un rato)'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-783775576985131552</id><published>2009-01-29T22:53:00.007-02:00</published><updated>2009-02-05T00:32:02.516-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='reflection'/><title type='text'>El Ruby brilla y refleja: local_variables y demas</title><content type='html'>Para los que no saben, en el scope de cada metodo en ruby nacen las variables locales (y mueren si no "trascienden", pero eso es asunto de otro post), ruby tiene algunas variables predefinidas en toda funcion que pueden hacer cosas interesantes, una de ellas es "local_variables", la cual es un array de todas las variables locales definidas hasta el momento, se puede usar de la siguiente forma:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="ruby"&gt;&lt;br /&gt;a = 1&lt;br /&gt;b = 2&lt;br /&gt;c = 3&lt;br /&gt;&lt;br /&gt;local_variables.each do |vn|&lt;br /&gt;   print "#{vn}=#{eval(vn)}\n"&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;&lt;/pre name="code"&gt;&lt;br /&gt;&lt;br /&gt;eso devuelve por la salida:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;a=1&lt;br /&gt;b=2&lt;br /&gt;c=3&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Las utilidades que pueden darle a esto les dejo a su imaginacion&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-783775576985131552?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/783775576985131552/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=783775576985131552' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/783775576985131552'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/783775576985131552'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2009/01/el-ruby-brilla-y-refleja-localvariables.html' title='El Ruby brilla y refleja: local_variables y demas'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-489475182806049584</id><published>2009-01-19T22:33:00.010-02:00</published><updated>2009-02-05T00:36:54.554-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='boludeces'/><category scheme='http://www.blogger.com/atom/ns#' term='bsg'/><category scheme='http://www.blogger.com/atom/ns#' term='battlestargalactica'/><title type='text'>Todo mal, Diego Gomez es un clone, frakin cylon machine</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://cache.gawker.com/assets/images/valleywag/2008/06/cylon_centurion_spotted_on_google_campus.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 294px; height: 287px;" src="http://cache.gawker.com/assets/images/valleywag/2008/06/cylon_centurion_spotted_on_google_campus.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="text-align: justify;"&gt;  La verdad que no me esperaba una tragedia como esta, al parecer, mi amigo y compañero de trabajo tiene sangre de mentira en las venas, una fuente ATX en lugar de corazón y un destello rojo en vez de alma  :(, esto lo descubri &lt;a href="http://www.google.com.ar/search?q=Diego+Gomez+blog"&gt;buscando el blog de Dieguito por la web&lt;/a&gt; para encontrarme con que se vislumbran dos copias de este modelo de cylon:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;* &lt;a href="http//blog.dgomez.com.ar/"&gt;Diego Gomez "phantom"&lt;/a&gt;, tiene un blog, es aficionado a la tecnología, la web, el software libre y el humor (usa debian)&lt;br /&gt;&lt;br /&gt;* &lt;a href="http://diegogomezdeck.blogspot.com/"&gt;Diego Gomez "deck"&lt;/a&gt;, tiene un blog, es aficionado a la tecnología, la web, el software libre y el humor (seguro usa debian también)&lt;br /&gt;&lt;br /&gt;Para el que este desinformado acerca del tema de los &lt;a href="http://www.google.com.ar/?q=cylon"&gt;cylon&lt;/a&gt;, solo les digo que fueron construidos por el hombre, se rebelaron, y se ven como y creen que son humanos :(&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/1354794578842586233-489475182806049584?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/489475182806049584/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=489475182806049584' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/489475182806049584'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/489475182806049584'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2009/01/todo-mal-diego-gomez-es-un-clone-frakin.html' title='Todo mal, Diego Gomez es un clone, frakin cylon machine'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-1430282033883304771</id><published>2009-01-12T00:10:00.001-02:00</published><updated>2009-01-12T00:21:11.811-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='factorial'/><title type='text'>Factorial super compacto en ruby</title><content type='html'>Posiblemente algunos conoceran la clasica implementacion del factorial en ruby, para los que no, la posteo aca:&lt;br /&gt;&lt;br /&gt;&lt;pre name='code' class='ruby'&gt;&lt;br /&gt;&lt;br /&gt;def factorial(n)&lt;br /&gt; if n &gt; 1&lt;br /&gt;  # casos mayor que 1, se usa la formula recursiva&lt;br /&gt;  # n! = n*(n-1)!&lt;br /&gt;&lt;br /&gt;  n * factorial(n-1)&lt;br /&gt; else&lt;br /&gt;  # casos 0 y 1, devuelve 1&lt;br /&gt;  1&lt;br /&gt; end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Les presento una forma mas compacta de expresar el factorial&lt;br /&gt;&lt;br /&gt;&lt;pre name='code' class='ruby'&gt;&lt;br /&gt;&lt;br /&gt;def factorial(n)&lt;br /&gt;  # el metodo inject del rango 2..n multiplica&lt;br /&gt;  # todos los elementos del conjunto tal como indica&lt;br /&gt;  # el bloque de codigo que se le esta pasando&lt;br /&gt;  (2..n).inject{|x,y| x*y}&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;A donde sea que vayan, lleven un interprete de ruby con ustedes&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-1430282033883304771?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/1430282033883304771/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=1430282033883304771' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/1430282033883304771'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/1430282033883304771'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2009/01/factorial-super-compacto-en-ruby.html' title='Factorial super compacto en ruby'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-7117209417933463223</id><published>2009-01-02T23:40:00.008-02:00</published><updated>2009-01-03T17:50:25.658-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vmware'/><category scheme='http://www.blogger.com/atom/ns#' term='c'/><category scheme='http://www.blogger.com/atom/ns#' term='patch'/><title type='text'>Patch para VMware  Server 1.0.8 en linux kernel 2.6.27</title><content type='html'>&lt;div style="text-align: justify;"&gt;Termine  &lt;a href="http://vmware-robert-patches.googlecode.com/files/vmware-1.0.8-126538.i386-patch.tar.gz"&gt;una versión del patch&lt;/a&gt; para vmware bajo linux para kernels nuevos ( testeado en un fedora con kernel 2.6.27.9 ), básicamente este patch corrigen los problemas descriptos en &lt;a href="http://nilclass.blogspot.com/2008/12/vmware-108-126538-en-kernels-nuevos-una.html"&gt;este post&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;A las correcciones descriptas en el articulo anteriormente mencionado, se le suma la corrección de la deferencia de puntero nulo, la que producía el colapso del kernel (el de la maquina host :S ) y escupía este backtrace:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;[&amp;lt;f99e76a1&amp;gt;] HostIF_SetFastClockRate+0x8d/0x148 [vmmon]&lt;br /&gt;[&amp;lt;f99efd65&amp;gt;] Vmx86_SetHostClockRate+0xad/0xd5 [vmmon]&lt;br /&gt;[&amp;lt;f99e5a87&amp;gt;] LinuxDriver_Ioctl+0x4c6/0xdcd [vmmon]&lt;br /&gt;[&amp;lt;c0118694&amp;gt;] kmap_atomic_prot+0x102/0x137&lt;br /&gt;[&amp;lt;c0395846&amp;gt;] _spin_unlock+0x5/0x1c&lt;br /&gt;[&amp;lt;c017bd62&amp;gt;] mnt_drop_write+0x64/0xdd&lt;br /&gt;[&amp;lt;c01f0680&amp;gt;] rb_insert_color+0x4c/0xad&lt;br /&gt;[&amp;lt;c013260a&amp;gt;] enqueue_hrtimer+0xc9/0xd4&lt;br /&gt;[&amp;lt;c0132ba5&amp;gt;] hrtimer_start+0xf9/0x129&lt;br /&gt;[&amp;lt;c011a13c&amp;gt;] hrtick_start_fair+0xf7/0x123&lt;br /&gt;[&amp;lt;c0129e78&amp;gt;] group_send_sig_info+0x12/0x56&lt;br /&gt;[&amp;lt;c0129eed&amp;gt;] kill_pid_info+0x31/0x54&lt;br /&gt;[&amp;lt;c012a44e&amp;gt;] sys_kill+0x73/0x13e&lt;br /&gt;[&amp;lt;c0172b53...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Pasaba que en el archivo linux/hostif.c, en la funcion HostIF_SetFastClockRate, aproximadamente por la linea 3480, habia algo asi:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="c"&gt;&lt;br /&gt;&lt;br /&gt;res = filp-&gt;f_op-&gt;ioctl(filp-&gt;f_dentry-&gt;d_inode, filp, RTC_PIE_ON, 0);&lt;br /&gt;if (!cap) {&lt;br /&gt; cap_lower(current-&gt;cap_effective, CAP_SYS_RESOURCE);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Y aparentemente, en ocasiones, filp-&gt;f_op-&gt;ioctl (que es un puntero a una función, para los mas desprevenidos), tenia el valor de 0, es decir un puntero a nada, para solventar esto, simplemente cambie ese bloque de codigo por esto:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre name="code" class="c"&gt;&lt;br /&gt;&lt;br /&gt;// mejor verificamos si ioctl es un puntero nulo antes&lt;br /&gt;// de deferenciarlo como puntero funcion&lt;br /&gt;if (filp-&gt;f_op-&gt;ioctl == 0) {&lt;br /&gt;// si el puntero es nulo, hacemos de cuenta que&lt;br /&gt;// la función devolvió status de error&lt;br /&gt;res = -1;&lt;br /&gt;} else {&lt;br /&gt;// ojo, en esta seccion de esta deferencia ioctl como puntero&lt;br /&gt;// que bueno que ya se verifico&lt;br /&gt;res = filp-&gt;f_op-&gt;ioctl(filp-&gt;f_dentry-&gt;d_inode, filp, RTC_PIE_ON, 0);&lt;br /&gt;if (!cap) {&lt;br /&gt;   cap_lower(current-&gt;cap_effective, CAP_SYS_RESOURCE);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Y con eso se chequeo el puntero antes de deferenciarlo&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Uh, casi me olvidaba, aca esta el &lt;a href="http://vmware-robert-patches.googlecode.com/files/vmware-1.0.8-126538.i386-patch.tar.gz"&gt;patch&lt;/a&gt;, tengan en cuenta que es para la version 1.0.8-126538 (no se descarata que funcione en otras versiones de vmware, pero yo solo lo probe con esa), por favor, si lo prueban comenten a este articulo que tal les fue, si hubo problemas, para que version de vmware y linux (kernel) instalaron el patch, etc...&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-7117209417933463223?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/7117209417933463223/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=7117209417933463223' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/7117209417933463223'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/7117209417933463223'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2009/01/patch-para-vmware-en-linux-con-kernels.html' title='Patch para VMware  Server 1.0.8 en linux kernel 2.6.27'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-8100485354285539386</id><published>2009-01-01T00:54:00.001-02:00</published><updated>2009-01-01T00:55:59.772-02:00</updated><title type='text'>Feliz año nuevo</title><content type='html'>Feliz año 2009 para todos, y que todos sus proyectos se cumplan y sean de software libre.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-8100485354285539386?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/8100485354285539386/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=8100485354285539386' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/8100485354285539386'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/8100485354285539386'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2009/01/feliz-ao-nuevo.html' title='Feliz año nuevo'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-7155612484179013172</id><published>2008-12-29T19:50:00.010-02:00</published><updated>2009-01-03T00:24:12.948-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vmware'/><category scheme='http://www.blogger.com/atom/ns#' term='c'/><title type='text'>VMware 1.0.8-126538 en kernels nuevos, una odisea</title><content type='html'>&lt;b&gt;Actualizacion: &lt;/b&gt; los problemas de vmmon descriptos en este articulo y algunos mas se resolvieron en el patch que publico y describo en &lt;a href='http://nilclass.blogspot.com/2009/01/patch-para-vmware-en-linux-con-kernels.html' &gt;este post&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Desde hace unas semanas que me hice un tiempo e instale fedora 10 con kde4 y toda la magia, pero llego el momento en que necesite virtualización, ahí empezó una entretenida historia (entretenida ahora que termino bien :D )&lt;br /&gt;Si algunos de los que están leyendo esto comparten la experiencia de haber intentado instalar la ultima versión de VMware en uno de los últimos linux con el kernel 2.6.27.9 o alguna versión parecida, (encontré foros de personas que decían que este mismo problema pasa también en el ultimo ubuntu, seguro en otras distribuciones tambien ),  habrán leído en la pantalla unas groserías particulares, cuando ejecutaron el famoso vmware-config.pl:&lt;br /&gt;&lt;br /&gt;"/tmp/vmware-config1/vmmon-only/./include/compat_semaphore.h:23:27: error: asm/semaphore.h: No such file or directory"&lt;br /&gt;"/tmp/vmware-config24/vmmon-only/linux/driver.c:153: error: se especificó el campo desconocido ‘nopage’ en el inicializador"&lt;br /&gt;&lt;br /&gt;y asi...&lt;br /&gt;&lt;br /&gt;No aguante mas y entre a meter mano en el codigo, primero lo del semaphore.h, no era complejo, simplemente cambiaron al .h de lugar, ahora esta en linux/semaphore.h en lugar de asm/semaphore.h en el nuevo kernel:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="c"&gt;&lt;br /&gt;&lt;br /&gt;#if (LINUX_VERSION_CODE &lt; KERNEL_VERSION(2,6,19))&lt;br /&gt;#include "asm/semaphore.h"&lt;br /&gt;#else&lt;br /&gt;#include "linux/semaphore.h"&lt;br /&gt;#endif&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;respecto a lo de nopage, no se bien que significa :(, lo unico que hice fue comentar las dos lineas que causaban problemas:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre name="code" class="c"&gt;&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;static void LinuxDriverPollTimeout(unsigned long clientData);&lt;br /&gt;&lt;br /&gt;static struct vm_operations_struct vmuser_mops = {&lt;br /&gt;//      .nopage = LinuxDriverNoPage&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;struct vm_operations_struct vmuser_locked_mops = {&lt;br /&gt;//      .nopage = LinuxDriverLockedNoPage&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;static struct file_operations vmuser_fops;&lt;br /&gt;static struct timer_list tscTimer;&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Tomar nota de esto ultimo, queda pendiente evaluar el significado de todo eso&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Y eso no fue todo, como todo un clásico de la programación C, al corregir errores, el compilador revela los otros errores que antes no se mostraron al no llegar a compilar esas secciones, quedo un desbarajuste en la función smp_call_function, que según el smp.h del kernel, tomaba 3 argumentos, y en driver.c y hostif.c del codigo fuente de vmmon, lo llamaba pasando 4 parámetros, a esto, lo resolvi eliminando el tercer argumento de todas las llamadas a la función smp_call_function ( y compat_smp_call_function, que era un sinónimo en ese código ). Elimine el tercer parametro porque en la definición de la funcion smp_call_function en el código del kernel mas viejo era el "retry" el tercer parámetro extra que había demás en relacion al nuevo&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre name="code" class="c"&gt;&lt;br /&gt;&lt;br /&gt;// version nueva EN linux/smp.h&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt;* Call a function on all other processors&lt;br /&gt;*/&lt;br /&gt;int smp_call_function(void(*func)(void *info), void *info, int wait);&lt;br /&gt;&lt;br /&gt;// version vieja en linux/smp.h&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt;* Call a function on all other processors&lt;br /&gt;*/&lt;br /&gt;int smp_call_function(void(*func)(void *info), void *info, int retry, int wait);&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Por ultimo, queda una llamada a kill_proc en linux/hostif.c, que segun el compilador no existe un kill_proc definido, ahi simplemente comente la linea :p&lt;br /&gt;&lt;br /&gt;Y por ultimo, al compilar vmnet, surge el mismo problema del semaphore.h, la solución es exactamente la misma que con la compilación del otro modulo&lt;br /&gt;&lt;br /&gt;Al final funciono todo, al punto que compilo todo, pude configurar todo lo que necesite y pude crear y bootear una maquina virtual, si embargo dos cosas (que habia mencionado antes) quedaron atadas con alambre:&lt;br /&gt;&lt;br /&gt;1) el .nopage = LinuxDriverNoPage comentado casi al principio de linux/driver.c&lt;br /&gt;2) el kill_proc comentado casi al final de linux/hostif.c&lt;br /&gt;3) La version del kernel que no supe precisar en el #if que incluye el semaphore.h&lt;br /&gt;&lt;br /&gt;Disculpen no haber subido el parche que genere, pero esos últimos dos puntos me parece que quedaron muy truchos y no quiero que cause problemas tratándose este código que toque de nada mas y nada menos que de módulos del kernel&lt;br /&gt;&lt;br /&gt;Lo probe un poco, y al parecer el cambio del kill_proc genera algunos problemas, ya que al correr la mayoria de las maquinas virtuales, vmserverd termina por un error causado en el kernel,&lt;br /&gt;&lt;br /&gt;con este problema:&lt;br /&gt;&lt;br /&gt;Kernel failure message 1:&lt;br /&gt;BUG: unable to handle kernel NULL pointer dereference at 0000000000000000&lt;br /&gt;IP: [&lt;0000000000000000&gt;] 0x0&lt;br /&gt;PGD 12944067 PUD 12942067 PMD 12941067 PTE 0&lt;br /&gt;Oops: 0010 [1] SMP&lt;br /&gt;&lt;br /&gt;y con este backtrace:&lt;br /&gt;&lt;br /&gt;[&lt;ffffffffa029b9a0&gt;] ? HostIF_SetFastClockRate+0xb0/0x137 [vmmon]&lt;br /&gt;[&lt;ffffffffa02a0634&gt;] Vmx86_SetHostClockRate+0xb4/0xc9 [vmmon]&lt;br /&gt;[&lt;ffffffffa029ad9e&gt;] LinuxDriver_Ioctl+0x3d3/0x923 [vmmon]&lt;br /&gt;[&lt;ffffffff8114093d&gt;] ? inode_has_perm+0x5b/0x61&lt;br /&gt;[&lt;ffffffff81033b79&gt;] ? __dequeue_entity+0x61/0x6a&lt;br /&gt;[&lt;ffffffff8105542a&gt;] ? remove_wait_queue+0x2f/0x39&lt;br /&gt;[&lt;ffffffff81140a8b&gt;] ? file_has_perm+0x83/0x8e&lt;br /&gt;[&lt;ffffffffa029b319&gt;] LinuxDriver_CompatIoctl+0x2b/0x40 [vmmon]&lt;br /&gt;&lt;br /&gt;Fijense que la funcion con problemas, es la que modifique comentando el kill_proc, se resolveria cuando encuentre una implementacion de kill_proc que use las posibilidades de este nuevo kernel&lt;br /&gt;&lt;br /&gt;&lt;/ffffffffa029b319&gt;&lt;/ffffffff81140a8b&gt;&lt;/ffffffff8105542a&gt;&lt;/ffffffff81033b79&gt;&lt;/ffffffff8114093d&gt;&lt;/ffffffffa029ad9e&gt;&lt;/ffffffffa02a0634&gt;&lt;/ffffffffa029b9a0&gt;&lt;div style="text-align: justify;"&gt;&lt;ffffffffa029b9a0&gt;&lt;ffffffffa02a0634&gt;&lt;ffffffffa029ad9e&gt;&lt;ffffffff8114093d&gt;&lt;ffffffff81033b79&gt;&lt;ffffffff8105542a&gt;&lt;ffffffff81140a8b&gt;&lt;ffffffffa029b319&gt;Después de un rato, corregí la función , reemplazando a kill_proc por su equivalente el nuevo kernel, tal como explica en &lt;a href="http://www.elotrolado.net/hilo_hilo-oficial-archlinux_1013979_s1000"&gt; esta pagina &lt;/a&gt;, cuando compilo, siguió existiendo el mismo error, buscando por la web, encontré algo acerca de &lt;a href="http://www.google.com.ar/search?q=53f1b1433da7eac2607a4a0898a221a4485fd732"&gt;please revert commit 53f1b1433da7eac2607a4...&lt;/a&gt;; aparentemente, un chabon hizo un commit, que crashea el kernel cuando cierta función se llama de cierta forma, espero que actualizando el kernel cuando se corrija o patcheandolo pueda solventar este problema&lt;/ffffffffa029b319&gt;&lt;/ffffffff81140a8b&gt;&lt;/ffffffff8105542a&gt;&lt;/ffffffff81033b79&gt;&lt;/ffffffff8114093d&gt;&lt;/ffffffffa029ad9e&gt;&lt;/ffffffffa02a0634&gt;&lt;/ffffffffa029b9a0&gt;&lt;br /&gt;&lt;ffffffffa029b9a0&gt;&lt;ffffffffa02a0634&gt;&lt;ffffffffa029ad9e&gt;&lt;ffffffff8114093d&gt;&lt;ffffffff81033b79&gt;&lt;ffffffff8105542a&gt;&lt;ffffffff81140a8b&gt;&lt;ffffffffa029b319&gt;&lt;/ffffffffa029b319&gt;&lt;/ffffffff81140a8b&gt;&lt;/ffffffff8105542a&gt;&lt;/ffffffff81033b79&gt;&lt;/ffffffff8114093d&gt;&lt;/ffffffffa029ad9e&gt;&lt;/ffffffffa02a0634&gt;&lt;/ffffffffa029b9a0&gt;&lt;/div&gt;&lt;ffffffffa029b9a0&gt;&lt;ffffffffa02a0634&gt;&lt;ffffffffa029ad9e&gt;&lt;ffffffff8114093d&gt;&lt;ffffffff81033b79&gt;&lt;ffffffff8105542a&gt;&lt;ffffffff81140a8b&gt;&lt;ffffffffa029b319&gt;&lt;br /&gt;&lt;/ffffffffa029b319&gt;&lt;/ffffffff81140a8b&gt;&lt;/ffffffff8105542a&gt;&lt;/ffffffff81033b79&gt;&lt;/ffffffff8114093d&gt;&lt;/ffffffffa029ad9e&gt;&lt;/ffffffffa02a0634&gt;&lt;/ffffffffa029b9a0&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-7155612484179013172?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/7155612484179013172/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=7155612484179013172' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/7155612484179013172'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/7155612484179013172'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2008/12/vmware-108-126538-en-kernels-nuevos-una.html' title='VMware 1.0.8-126538 en kernels nuevos, una odisea'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-7818367119151656864</id><published>2008-12-26T13:09:00.008-02:00</published><updated>2008-12-29T19:49:41.607-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><title type='text'>Extraccion de direcciones de mail de texto en dos lineas</title><content type='html'>DISCLAIMER: la siguiente información se difunde solo con fines educativos, el blog de NilClass NO fomenta el spam&lt;br /&gt;&lt;br /&gt;&lt;pre name='code' class='ruby' &gt;&lt;br /&gt;&lt;br /&gt;# El codigo consta de dos chainings, &lt;br /&gt;# el primero abre el archivo y escribe en el &lt;br /&gt;# (todo el codigo hasta el .write inclusive)&lt;br /&gt;&lt;br /&gt;# en el primer chaining&lt;br /&gt;&lt;br /&gt;# abre el archivo (File.new( "..." , "w") )&lt;br /&gt;# invoca el metodo write&lt;br /&gt;&lt;br /&gt;# en el segundo chaining&lt;br /&gt;&lt;br /&gt;# abre el archivo, para lectura&lt;br /&gt;# hace un read al archivo, para leer todo su contenido&lt;br /&gt;# hace un split, usando como divisor la expresion regular&lt;br /&gt;# la expresion regular especifica que matchee todo lo que&lt;br /&gt;# no sea ni letra minuscula ni letra mayuscula ni numero&lt;br /&gt;# ni esos caracteres que pueden tener las dir. de mail&lt;br /&gt;# despues el chaining hace un select de los strings que contienen&lt;br /&gt;# el caracter "@"&lt;br /&gt;# y por ultimo, efectua un join uniendo todas las cadenas&lt;br /&gt;# con el caracter de salto de linea (\n) de por medio&lt;br /&gt;&lt;br /&gt;ary = File.new("rawtext.txt").read.split(/[^a-zA-Z0-9@._-]/)&lt;br /&gt;File.new("mails-parsed.txt","w").write ary.select{ |x| x =~ /@/ }.join("n")&lt;br /&gt;&lt;br /&gt;# nota: esta claro que pude haber hecho todo en una sola linea&lt;br /&gt;# pero lo separe en dos para que quepa en la columna del post&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/1354794578842586233-7818367119151656864?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/7818367119151656864/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=7818367119151656864' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/7818367119151656864'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/7818367119151656864'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2008/12/extraccion-de-direcciones-de-mail-de.html' title='Extraccion de direcciones de mail de texto en dos lineas'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-4162521177916023174</id><published>2008-12-22T15:41:00.002-02:00</published><updated>2008-12-22T15:48:40.988-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><title type='text'>Conexion a bases de datos mysql via ruby</title><content type='html'>&lt;div style="text-align: justify;"&gt;Por razones que no vienen al caso encontré e instale una librería para ruby que permite conectarse a los motores de bases de datos mysql, la misma la pueden encontrar en &lt;a href="http://www.tmtm.org/en/ruby/mysql/"&gt;http://www.tmtm.org/en/ruby/mysql/&lt;/a&gt;, la libreria se puede usar mas o menos asi:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name='code' class='ruby'&gt;&lt;br /&gt;require "gramas"&lt;br /&gt;require "mysql"&lt;br /&gt;my = Mysql::new("localhost", "username", "password", "database")&lt;br /&gt;res = my.query("select name,surname from users")&lt;br /&gt;res.each do |row|&lt;br /&gt;  col1 = row[0]&lt;br /&gt;  col2 = row[1]&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/1354794578842586233-4162521177916023174?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/4162521177916023174/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=4162521177916023174' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/4162521177916023174'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/4162521177916023174'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2008/12/conexion-bases-de-datos-mysql-via-ruby.html' title='Conexion a bases de datos mysql via ruby'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-135574897570413751</id><published>2008-12-16T01:44:00.007-02:00</published><updated>2008-12-18T14:30:57.369-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><title type='text'>Como mantener una lista de subclasses en una clase</title><content type='html'>Definiendo el método de clase inherited, se pueden hacer muchas cosas cuando se hereda una clase, entre ellas esto:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="ruby"&gt;&lt;br /&gt;# defino un modulo para agrupar los métodos que se agregan a las clases&lt;br /&gt;module SubclassesRegister&lt;br /&gt; def subclasses&lt;br /&gt;  if @subclasses == nil&lt;br /&gt;   @subclasses = []&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  @subclasses&lt;br /&gt; end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;# la clase principal, la que implementa la funcionalidad de registrar las subclases&lt;br /&gt;class RegisteredClass&lt;br /&gt;&lt;br /&gt; def self.inherited(x)&lt;br /&gt;&lt;br /&gt;  # se le agregan los metodos para que mantenga la lista de superclases ( a la superclase de x)&lt;br /&gt;  x.superclass.extend SubclassesRegister unless x.superclass.include? SubclassesRegister&lt;br /&gt;&lt;br /&gt;  # cuando alguna clase hereda de esta, se registra la subclase (si la superclase no es esta)&lt;br /&gt;  if x.superclass != RegisteredClass&lt;br /&gt;   self.register_subclass(x)&lt;br /&gt;  end&lt;br /&gt; end&lt;br /&gt;&lt;br /&gt; def self.register_subclass(subclass)&lt;br /&gt;&lt;br /&gt;  superclass = subclass.superclass&lt;br /&gt;  print "registered #{subclass} as subclass of #{superclass}\n"&lt;br /&gt;&lt;br /&gt;  # agregar la clase subclass a la lista de subclases de su superclase&lt;br /&gt;  superclass.subclasses &lt;&lt; subclass&lt;br /&gt; end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;class Animal &lt; RegisteredClass&lt;br /&gt; def self.enu&lt;br /&gt;  # puedo obtener las subclases con solo usar el metodo "subclasses"&lt;br /&gt;  print "subclases de Animal: #{subclasses.join("; ")}\n"&lt;br /&gt; end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;class Perro &lt; Animal&lt;br /&gt; def self.enu&lt;br /&gt;  # cualquier clase de la jerarquia que extienda directa o indirectamente de RegisteredClass&lt;br /&gt;  # puede obtener la lista de sus subclases&lt;br /&gt;  print "subclases de Perro: #{subclasses.join("; ")}\n"&lt;br /&gt; end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;class Terrier &lt; Perro&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;class Dogo &lt; Perro&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;class Gato &lt; Animal&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Animal.enu&lt;br /&gt;Perro.enu&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Espero que les haya sido de utilidad&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-135574897570413751?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/135574897570413751/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=135574897570413751' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/135574897570413751'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/135574897570413751'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2008/12/como-mantener-una-lista-de-subclasses.html' title='Como mantener una lista de subclasses en una clase'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-1489301672157045260</id><published>2008-12-15T23:55:00.006-02:00</published><updated>2008-12-16T01:44:09.434-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='original'/><category scheme='http://www.blogger.com/atom/ns#' term='rubik'/><title type='text'>¡¡¡ Aleluya !!!, consegui el Rubik original</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_T12nVzD4aEs/SUcO5Jh-WVI/AAAAAAAAAAk/Uv4XPldWLyY/s1600-h/3x3_cube.gif"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 237px; height: 245px;" src="http://4.bp.blogspot.com/_T12nVzD4aEs/SUcO5Jh-WVI/AAAAAAAAAAk/Uv4XPldWLyY/s400/3x3_cube.gif" alt="" id="BLOGGER_PHOTO_ID_5280205463088945490" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Al principio crei que era un sueño, pero lo consegui, con empaque original y todo, en pocas palabras, el de la foto de la derecha&lt;br /&gt;Por si no lo sabian, en Argentina, durante un tiempo importante no hubo distribuidor oficial del cubo Rubik, y ahora es muy dificil de conseguir, y lo consegui.&lt;br /&gt;El cubo es mucho mas maleable que cualquier "imitacion" que se puede conseguir practicamente en cualquier negocio, aparentemente el plastico del que se componen las piezas tiene mayor calidad y por lo tanto dura mas; y los stickers tambien, en el  mismo tiempo de uso qu&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_T12nVzD4aEs/SUcPJgt99HI/AAAAAAAAAAs/ELTQNNpV2yk/s1600-h/REVENGE_4X4_HEX.gif"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 218px; height: 226px;" src="http://1.bp.blogspot.com/_T12nVzD4aEs/SUcPJgt99HI/AAAAAAAAAAs/ELTQNNpV2yk/s400/REVENGE_4X4_HEX.gif" alt="" id="BLOGGER_PHOTO_ID_5280205744191173746" border="0" /&gt;&lt;/a&gt;e en los otros cubos los stickers empezaban a perder el color, este sigue aparentando que no se uso !!!, es increible.&lt;br /&gt;Como bonus tambien me compre uno de 4x4 (code name: The Revenge of Rubik), el de la otra foto&lt;br /&gt;&lt;br /&gt;&lt;br /&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/1354794578842586233-1489301672157045260?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/1489301672157045260/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=1489301672157045260' title='3 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/1489301672157045260'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/1489301672157045260'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2008/12/aleluya-consegui-el-rubik-original.html' title='¡¡¡ Aleluya !!!, consegui el Rubik original'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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/_T12nVzD4aEs/SUcO5Jh-WVI/AAAAAAAAAAk/Uv4XPldWLyY/s72-c/3x3_cube.gif' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1354794578842586233.post-2851132892225082828</id><published>2008-12-12T13:09:00.004-02:00</published><updated>2008-12-12T13:26:55.026-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cookies'/><category scheme='http://www.blogger.com/atom/ns#' term='guerra'/><category scheme='http://www.blogger.com/atom/ns#' term='trabajo'/><title type='text'>La guerra de cookies</title><content type='html'>No se como describirlo, no se sabe como empiezo, en un instante dado, salto uno diciendo &lt;br /&gt;"Quiero editar cookies", y el otro dijo "No se puede, estan en el server", entonces , el otro dijo... Mejor pongo un guion:&lt;br /&gt;&lt;br /&gt;-&lt;br /&gt;&lt;br /&gt;Lo siguiente ocurre entre las 12:00 pm y las 13:00 pm&lt;br /&gt;&lt;br /&gt;Matt:       Quiero setear una cookie&lt;br /&gt;Diego:      No se puede, esta en el server&lt;br /&gt;Caco:       Podes usar javascript.cookie&lt;br /&gt;Matt:       Solo setea localhost, quiero setear para ese host&lt;br /&gt;Diego:      No tiene sentido setear una cookie, el server no la va a aceptar, el server genera la cookie&lt;br /&gt;Matt:       Quiero setear una cookie en el browser&lt;br /&gt;Robert:     Miren esto&lt;br /&gt;Diego:      Espera&lt;br /&gt;Matt:       Espera&lt;br /&gt;Diego:      No tiene sentido setear una cookie, el server no la va a aceptar, el server genera la cookie&lt;br /&gt;Matt:       ¡¡¡Quiero poner la cookie!!!&lt;br /&gt;Robert:     Miren esto&lt;br /&gt;Diego:      Espera&lt;br /&gt;Matt:       Espera&lt;br /&gt;Diego:      No tiene sentido setear una cookie, el server no la va a aceptar, el server genera la cookie&lt;br /&gt;Matt:       ¡¡¡Quiero poner la cookie!!!&lt;br /&gt;Robert:     Miren esto&lt;br /&gt;Diego:      Espera&lt;br /&gt;Matt:       Espera&lt;br /&gt;Diego:      No tiene sentido setear una cookie, el server no la va a aceptar, el server genera la cookie&lt;br /&gt;Gise:       BBAAAAAAAAAAAAASTAAAAAA!!!&lt;br /&gt;Matt:       ¡¡¡Quiero poner la cookie!!!&lt;br /&gt;Diego:      No tiene sentido setear una cookie, el server no la va a aceptar, el server genera la cookie&lt;br /&gt;Matt:       ¡¡¡Quiero poner la cookie!!!&lt;br /&gt;&lt;br /&gt;&lt;pre name='code' class='ruby'&gt;&lt;br /&gt;for i in (1..3000)&lt;br /&gt; print "Diego: NO se puede\n"&lt;br /&gt; print "Matt:  SI se puede\n"&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Robert:     Miren esto (mostrando el cuadro de agregar una cookie )&lt;br /&gt;Diego:      Espera&lt;br /&gt;Matt:       Espera. A ver...&lt;br /&gt;&lt;br /&gt;Robert:     Usa ADD N EDIT COOKIES para Firefox&lt;br /&gt;&lt;br /&gt;Matt:       Robert encontró lo que quería desde el principio&lt;br /&gt;Diego:      ¿eso era?&lt;br /&gt;&lt;br /&gt;&lt;pre name='code' class='ruby'&gt;&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/1354794578842586233-2851132892225082828?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/2851132892225082828/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=2851132892225082828' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/2851132892225082828'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/2851132892225082828'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2008/12/la-guerra-de-cookies.html' title='La guerra de cookies'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-2293564285050570604</id><published>2008-12-10T16:37:00.007-02:00</published><updated>2008-12-16T11:34:40.490-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='informatica'/><category scheme='http://www.blogger.com/atom/ns#' term='usuarios'/><title type='text'>He descubierto una funcion no documentada en dos sistemas operativos: AltTAB ReversO</title><content type='html'>&lt;div style="text-align: justify;"&gt;El fin de semana descubri algo muy loco. ¿ Alguno de ustedes se encontró altabulando en decenas de ventanas en el escritorio , y de repente se dan cuenta de que se pasaron la que querían, y por lo tanto se ven obligados a dar toda la vuelta ?. La solucion esta a milímetros del meñique, mientras mantienen apretada la tecla ALT, presionen y mantengan apretada la tecla SHIFT tambien, cuando presionen TAB, altabulearean en sentido reverso !!&lt;br /&gt;Lo curioso de esta técnica, es que funciona en los escritorios de Windows, en Kde y Gnome (si algún usuario de MacOS esta leyendo esto, por favor que deje un comentario acerca de si esto también sirve en el mundo bizarro) ; no solo eso, también funciona en el navegador Firefox para las pestañas (en este caso la tecla para cambiar de pestañas es control+tab, pero también sigue siendo el poderoso SHIFT, el agente reversor de la funcionalidad )&lt;br /&gt;&lt;br /&gt;Esto fue todo por hoy, espero que les haya gustado, chau&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-2293564285050570604?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/2293564285050570604/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=2293564285050570604' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/2293564285050570604'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/2293564285050570604'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2008/12/alttab-reverso.html' title='He descubierto una funcion no documentada en dos sistemas operativos: AltTAB ReversO'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-5870279157237112215</id><published>2008-12-10T11:03:00.003-02:00</published><updated>2008-12-10T11:43:46.101-02:00</updated><title type='text'>Lo que pasa cuando no se usan "captchas" y como te obligan a pagar linux</title><content type='html'>Miren todos los comentarios que dejaron de este articulo:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.todo-linux.com/modules.php?name=News&amp;file=article&amp;sid=416"&gt;&lt;br /&gt; http://www.todo-linux.com/modules.php?name=News&amp;file=article&amp;sid=416&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Hablando del tema en cuestion, espero que los "SGAE" locales ( i'am from Argentina ), no sean tan "creativos"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-5870279157237112215?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/5870279157237112215/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=5870279157237112215' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/5870279157237112215'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/5870279157237112215'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2008/12/lo-que-pasa-cuando-no-se-usan-captchas.html' title='Lo que pasa cuando no se usan &quot;captchas&quot; y como te obligan a pagar linux'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-1127194330545847808</id><published>2008-12-08T23:55:00.005-02:00</published><updated>2008-12-09T00:15:24.540-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><title type='text'>Hacer split de strings con expresiones regulares</title><content type='html'>Imaginense el caso:&lt;br /&gt;&lt;br /&gt;&lt;pre name='code' class='ruby'&gt;&lt;br /&gt;str = "hola como estan chau"&lt;br /&gt;str.split.each do |x|&lt;br /&gt; print x,"\n"&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Dara como resultado:&lt;br /&gt;&lt;br /&gt;hola&lt;br /&gt;como&lt;br /&gt;estan&lt;br /&gt;chau&lt;br /&gt;&lt;br /&gt;Pero si tuvieramos (agregando signos de puntuacion entre las palabra):&lt;br /&gt;&lt;br /&gt;&lt;pre name='code' class='ruby'&gt;&lt;br /&gt;str = "hola,como estan;chau"&lt;br /&gt;str.split.each do |x|&lt;br /&gt; print x,"\n"&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;La salida seria:&lt;br /&gt;&lt;br /&gt;hola,como&lt;br /&gt;estan;chau&lt;br /&gt;&lt;br /&gt;   Y en la mayoria de los casos, eso no es lo que buscamos, para obtener lo que queremos (separar todas las palabras, sin importar que las dividan), podemos recurrir a lo siguiente:&lt;br /&gt;&lt;br /&gt;&lt;pre name='code' class='ruby'&gt;&lt;br /&gt;str = "hola,como estan;chau"&lt;br /&gt;str.split(/,|\s|;/).each do |x|&lt;br /&gt; print x,"\n"&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;O mejor aun&lt;br /&gt;&lt;pre name='code' class='ruby'&gt;&lt;br /&gt;str = "hola,como estan;chau"&lt;br /&gt;str.split(/\W/).each do |x|&lt;br /&gt; print x,"\n"&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Eso retorna las cuatro palabras separadas. El argumento /,|\s|;/ que se le paso a split , es una expresion regular que matchea el caracter coma, el punto y coma o espacio indicandole que tiene que tomar cualquiera de estos como separador, en el segundo caso, la expresion regular indica que tome como separador cualquier caracter que no sea alfanumerico. Como imaginaran, esto es bastante util para extraer facilmente palabras de textos webs, txts, etc...&lt;br /&gt;&lt;br /&gt;Espero que les haya gustado, chau&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-1127194330545847808?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/1127194330545847808/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=1127194330545847808' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/1127194330545847808'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/1127194330545847808'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2008/12/hacer-split-de-strings-con-expresiones.html' title='Hacer split de strings con expresiones regulares'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-2389142370487007432</id><published>2008-12-07T23:23:00.004-02:00</published><updated>2008-12-08T00:25:28.723-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='boludeces'/><category scheme='http://www.blogger.com/atom/ns#' term='cyber'/><category scheme='http://www.blogger.com/atom/ns#' term='bardeo'/><title type='text'>El cyber de los cartoneros ocupas</title><content type='html'>Hoy fue uno de esos dias raros, en los que sali a la calle en busca de un cyber con internet, porque en casa se descompuso internet, y necesitaba enviar este post. Lo cierto que tras cuadras de recorrido, llegue al unico que encontre, el tipico negocio locutorio-kiosko-cyber-psicologo-verdulero, entre preguntando cuanto cuesta la hora, y me sorprendi al escuchar que dijo "setenta y cinco centavos", (precios como este solo los vi en la epoca pre-apocaliptica del 1 a 1). Lo cierto es que le di para adelante, y empuñando en alto mi usb, me dijo "usb anda a la 6".&lt;br /&gt;   Y en la seis, y en todas las demas, Windows 98 Edicion Cartonero, con buscaminas y solitario 2D !!!, con Intenet Exploder 6.0, msn 6.0 y mIRC version 0.01beta (este ultimo es falso, ni siquiera habia mIRC) todo un emergente mundo retro. Aun con todo esto, me quede ya que no habia otra, y tenia que lanzar urgente un tar.gz al cyber-espacio, cuando me disponia a colocar el pen-drive, observe pasmado que el gabinete AT , ¡¡¡estaba pidiendo EUTANASIA!!! por poco y tenia una entrada para floppy 5 1/4 ( se ve que se lo sacaron para poner un 3 1/2 en su lugar, que es mas moderno ).&lt;br /&gt;   El monitor por supuesto, a 640x480, porque era lo maximo que soportaba. En una carpeta que estaba por ahi, en una esquina, estaba el magnifico instalador del IE 6.0 (ya que win98 venia con IE 5.0 ), todo un reto, hacer que funcione algo, ahi, cualquier programa que traia en el usb, anunciaba "Windows 2000 or higher is needed for install..."&lt;br /&gt;   El cyber hecho por cartoneros ocupas, se hizo con toda la intencion (de hacer plata facil) recuperando maquinas DE LA BASURA, y por extension, instalando sistemas operativos DE LA BASURA TAMBIEN, pero a ese lugar no vuelvo, aunque me paguen 75 centavos la hora a mi en lugar de que yo les tenga que pagara ellos.&lt;br /&gt;   Aclaracion: no tengo nada en contra de los cartoneros, siempre y cuando no pongan cybers a cuadras del congreso&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-2389142370487007432?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/2389142370487007432/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=2389142370487007432' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/2389142370487007432'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/2389142370487007432'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2008/12/el-cyber-de-los-cartoneros-ocupas.html' title='El cyber de los cartoneros ocupas'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-4239680674750082327</id><published>2008-12-07T20:19:00.008-02:00</published><updated>2008-12-08T00:30:34.482-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='apophysis'/><category scheme='http://www.blogger.com/atom/ns#' term='flash'/><title type='text'>Programa para generar imagenes "flasheras"</title><content type='html'>Hoy estuve navegando por la web, y me tope con &lt;a href="http://arkano-nephilim.blogspot.com/search/label/apophysis" &gt;un articulo&lt;/a&gt; de un blog, el cual promovia y ensañaba el uso de un programa llamado &lt;a href="http://www.apophysis.org"&gt;apophysis&lt;/a&gt;. Esta aplicacion, servia para generar imagenes fractales, como esta:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_T12nVzD4aEs/STxXim4hW6I/AAAAAAAAAAU/qaGBrRhTuho/s1600-h/3071325012_91ab3c3b33.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 283px;" src="http://2.bp.blogspot.com/_T12nVzD4aEs/STxXim4hW6I/AAAAAAAAAAU/qaGBrRhTuho/s400/3071325012_91ab3c3b33.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5277189115436161954" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;En el primer link que inclui en este articulo hay muchos mas ejemplos, no los inclui todos en este post porque se ve que tienen alta resolucion y ocasionan gran cantidad de trabajo al browser :p&lt;br /&gt;Hasta el proximo articulo, van a conocer mis conclusiones acerca de esta herramienta cuando la pruebe&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-4239680674750082327?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/4239680674750082327/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=4239680674750082327' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/4239680674750082327'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/4239680674750082327'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2008/12/programa-para-generar-imagenes.html' title='Programa para generar imagenes &quot;flasheras&quot;'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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/_T12nVzD4aEs/STxXim4hW6I/AAAAAAAAAAU/qaGBrRhTuho/s72-c/3071325012_91ab3c3b33.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1354794578842586233.post-2959479138398222741</id><published>2008-12-05T22:04:00.000-02:00</published><updated>2008-12-05T22:18:10.954-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rubik'/><title type='text'>4x3x2 = FRACTURA EXPUESTA DE PULGAR</title><content type='html'>A mi sinceramente no se me hubiera ocurrio algo asi. Aparentemente el que manipula el &lt;a href="http://es.wikipedia.org/wiki/Ortoedro"&gt;paralelepipedo ortogonal&lt;/a&gt; rubik (no es un cubo, en terminos estrictos) se fracturo el pulgar jugando con eso (aun asi, sigue)&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/Ni1VJLDIts4&amp;hl=es&amp;fs=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/Ni1VJLDIts4&amp;hl=es&amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-2959479138398222741?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/2959479138398222741/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=2959479138398222741' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/2959479138398222741'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/2959479138398222741'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2008/12/4x3x2-locura.html' title='4x3x2 = FRACTURA EXPUESTA DE PULGAR'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-5301469982214912241</id><published>2008-12-05T20:46:00.000-02:00</published><updated>2008-12-05T21:47:46.041-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='NilClass'/><category scheme='http://www.blogger.com/atom/ns#' term='filosofia'/><title type='text'>el NilClass</title><content type='html'>Vean el siguiente ejemplo&lt;br /&gt;&lt;br /&gt;&lt;pre name='code' class='ruby'&gt;&lt;br /&gt;&lt;br /&gt;# un array asociativo&lt;br /&gt;array = { 1 =&gt; "Robert", 2 =&gt; "Ruby" }&lt;br /&gt;&lt;br /&gt;# imprimir las longitudes de las cadenas del array&lt;br /&gt;(1..3).each do |i|&lt;br /&gt; #  CUIDADO al tratar de procesar el string numero 3, se generara un error &lt;br /&gt; # "undefined method 'length' for nil:NilClass (NoMethodError)"&lt;br /&gt; print "longitud de la cadena #{i}: #{array[i].length}\n"&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;el elemento 3 del array asociativo, era un nil, por lo tanto devolvio ese error, pero, trato de invocar el metodo al objeto nil, que es de tipo NilClass, eso significa que se puede definir el metodo en el objeto&lt;br /&gt;&lt;br /&gt;&lt;pre name='code' class='ruby'&gt;&lt;br /&gt;&lt;br /&gt;# un array asociativo&lt;br /&gt;array = { 1 =&gt; "Robert", 2 =&gt; "Ruby" }&lt;br /&gt;&lt;br /&gt;# antes, puedo definir el metodo length del nil&lt;br /&gt;def nil.length&lt;br /&gt; 0&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;# imprimir las longitudes de las cadenas del array&lt;br /&gt;(1..3).each do |i|&lt;br /&gt; # Esta vez no genera ningun error&lt;br /&gt; print "longitud de la cadena #{i}: #{array[i].length}\n"&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Tambien es valido definir el metodo en el NilClass, por lo que conozco es lo mismo (NilClass es una clase cuya unica instancia es nil)&lt;br /&gt;&lt;br /&gt;&lt;pre name='code' class='ruby'&gt;&lt;br /&gt;# un array asociativo&lt;br /&gt;array = { 1 =&gt; "Robert", 2 =&gt; "Ruby" }&lt;br /&gt;&lt;br /&gt;# antes, puedo definir el metodo length en la clase NilClass&lt;br /&gt;class NilClass&lt;br /&gt; def length&lt;br /&gt;  0&lt;br /&gt; end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;# imprimir las longitudes de las cadenas del array&lt;br /&gt;(1..3).each do |i|&lt;br /&gt; # Esta vez no genera ningun error&lt;br /&gt; print "longitud de la cadena #{i}: #{array[i].length}\n"&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;En definitiva, para explicar lo ocurrido, nil es el objeto referenciado por las variables que no referencia a nada, es algo parecido al hecho de conceptualizar una entidad que creo la parte del universo que no fue creada por nadie, o la definicion del "eter" gas que conduce las ondas de luz que existe en todo el espacio exterior , donde se suponia que hay "vacio"&lt;br /&gt;A diferencia de lenguajes como java , o .net, los cuales admiten variables que no hagan referencia a *nada*, dando lugar a "NullPointerExceptions", en ruby esto no tiene sentido, por lo tanto no pueden existir variables que apunten a la nada, si existen variables que apuntan al objeto nil, que representa a la nada, lo cual nos lleva a que tanto los lenguajes mencionados anteriormente se rigen por el mismo principio: la nada en un contexto tan abstracto, tiene el mismo nivel de tangibilidad que cualquier algo (como clases, metodos y otras cosas), java define a esa nada como un "null", y ruby como un "nil". &lt;br /&gt;La diferencia que si existe, es que en java esa representacion de nada, es "especial", es algo mas, una cosa aparte; en cambio, en ruby, la representacion de la nada, es nil, que tambien es un objeto ya que en ruby todo es un objeto, por que lo "especial", se admite en la menor medida posible, ya que añade gran complejidad a esto.&lt;br /&gt;Al ser la representacion de nada un objeto como los demas, admite todo lo que los objetos admite: metodos, mas instancias, estado, etc..., si esto tiene sentido o no  definira el programador, si quiere usar estas funcionalidades o no, se puede decir tanto que no tiene sentido que la nada tenga "funcionalidades" como tambien se puede decir que no es correcto que la nada no pueda ser tratada como un concepto al igual que los demas, como las clases, metodos y variables&lt;br /&gt;Espero que les haya sido de utilidad, cerramos con otra exhibicion de nil, menos charla y mas accion:&lt;br /&gt;&lt;br /&gt;&lt;pre name='code' class='ruby'&gt;&lt;br /&gt;# ESTO NO SE PUEDE HACER, POR RAZONES ¿OBVIAS?&lt;br /&gt;# atencion: todas las lineas de codigo posteriores dan algun tipo de error&lt;br /&gt;&lt;br /&gt;# duplicamos el nil original, ya que es un objeto&lt;br /&gt;# esto no anda, no se puede duplicar el concepto de la nada&lt;br /&gt;# para crear otro concepto, el concepto de nada&lt;br /&gt;# es unico (el patron singleton)&lt;br /&gt;otronil = nil.dup &lt;br /&gt;&lt;br /&gt;# instanciamos otro nil usando la NilClass&lt;br /&gt;# no se puede fabricar distintos conceptos de nada&lt;br /&gt;# eso conlleva a la nada (valga la redundancia)&lt;br /&gt;otronilmas = NilClass.new&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Ahora algo que funcione&lt;br /&gt;&lt;br /&gt;&lt;pre name='code' class='ruby'&gt;&lt;br /&gt;&lt;br /&gt;# se le pueden definir los metodos que sean al NilClass&lt;br /&gt;# y tambien variables locales&lt;br /&gt;class NilClass&lt;br /&gt; def initialize&lt;br /&gt;  super&lt;br /&gt;  @vacio = 4&lt;br /&gt; end&lt;br /&gt;&lt;br /&gt; def vacio= (a)&lt;br /&gt;  @vacio = a&lt;br /&gt; end&lt;br /&gt; def vacio&lt;br /&gt;  @vacio&lt;br /&gt; end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;nil.vacio = 4&lt;br /&gt;print nil.vacio&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/1354794578842586233-5301469982214912241?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/5301469982214912241/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=5301469982214912241' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/5301469982214912241'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/5301469982214912241'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2008/12/el-nilclass.html' title='el NilClass'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-3382693944981963453</id><published>2008-12-05T12:04:00.000-02:00</published><updated>2008-12-05T12:46:31.991-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='filosofia'/><category scheme='http://www.blogger.com/atom/ns#' term='trabajo'/><title type='text'>Las viscicitudes y la esquizofrenia de proyectos "privativos" que emplean a la "gente del linux"</title><content type='html'>Estoy por a punto contraer esquizofrenia aguda si no resuelvo el siguiente:&lt;br /&gt;&lt;br /&gt;Estoy trabajando en una suite de proyecto$$$ de $oftware privativo$$$ (no hay problema en eso, el mundo es dinero) que esta empleando , como fuerza de trabajo tecnica principal, mucha "gente del linux" (me incluyo entre ellos) , seguidores de Richard Stallman (el tipo es un grosso) y sus enseñanzas filosoficas.&lt;br /&gt;Exitosamente ambas partes ( la parte $privativa$, y la parte GNUsera ) han logrado dejar totalmente de lado sus prejuicios ideologicos para convivir en armonia en un proyecto que progreso (y progresa) bastante, como dos equipos remando en la misma direccion, al unisono, pero hasta cierto limite.&lt;br /&gt;El limite surge cuando, se vislumbra una incompatibilidad de conceptos cuyas raices son esos profundos mandatos y estructuras ideologicas, conceptos de los que no se habla, pero se ven plasmado en los hechos.&lt;br /&gt;El principal ejemplo de esto, es la aplicacion del concepto del "producto de software privativo", con la "propiedad intelectual" ( de lo cual estoy en contra y a favor de eso (mas en contra ( pero no al punto de rechazar el proyecto ) ) ), lo cual genera un obvio y comprensible requerimiento por parte del cliente de un producto autonomo ( que no requiera administracion, solo talvez mantenimiento ) y que por lo tanto tenga una gran plusvalia. No estoy en contra de eso, mas bien quiero lograrlo, pero la parte GNUsera no comprende, a nivel subconsciente, lo que significa el "producto de software privativo y que no necesite administracion", por lo tanto, sin darse cuenta, estan rechazando el desarrollo de soft en torno en la funcionalidad con parches (como reiniciar los servicios automaticamente ante un problema) y estan privilegiando el desarrollo de herramientas de monitoreo y administracion del servicio (cuando segun la otra parte, el servicio deberia administrarse solo ) y tambien estan dando prioridad al analisis detallado de bugs o problemas para darle solucion definitiva (como todo buen desarrollador de software libre) , pero siendo que esto no es para este contexto. &lt;br /&gt;En este punto, si bien no tenemos a los dos equipos remando para sentidos opuestos y el barco girando sobre si mismo, no estan remando exactamente para la misma direccion, lo cual causa trayectorias circulares (de circulos bastante grandes), pero circulares al fin.&lt;br /&gt;No se puede definir con certeza cual es la direccion correcta, el planteo de un "servicio que no necesite administracion" es bastante cuestionable, pero al mismo tiempo dejar que un servicio dependa en exceso de sus desarrolladores tambien es cuestionable, al igual que pretender que un producto privativo de poco personal este a la altura de soluciones libres o de grandes empresas. Hasta ahora solo describi el problema y no la solucion, pero es probable que si no se resuelve este problema, el proyecto no supere ese limite y yo termine en un loquero hablando con visiones :(&lt;br /&gt;&lt;br /&gt;Comentarios acerca de posibles soluciones son bienvenidos&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-3382693944981963453?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/3382693944981963453/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=3382693944981963453' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/3382693944981963453'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/3382693944981963453'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2008/12/las-viscicitudes-y-la-esquizofrenia-de.html' title='Las viscicitudes y la esquizofrenia de proyectos &quot;privativos&quot; que emplean a la &quot;gente del linux&quot;'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-7636442374447379891</id><published>2008-12-05T11:08:00.000-02:00</published><updated>2008-12-05T11:17:45.953-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='blog'/><category scheme='http://www.blogger.com/atom/ns#' term='NilClass'/><title type='text'>Highlighting a los post</title><content type='html'>Gracias a los instructivos de un buen post de &lt;a href="http://yacoding.blogspot.com/2008/05/how-to-add-syntax-highlight-to-blogger.html"&gt;este blog&lt;/a&gt; cuya direccion me paso Caco_Patane (pasense por su blog), pude configurar el highlighthing de codigo para los posts, ahora si que da gusto publicar post con codigo, vean el "hola mundo" del highlighting:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="ruby"&gt;&lt;br /&gt;def holamundo&lt;br /&gt;    print "hola mundo!!!\n"&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;# los parentesis son un guiño&lt;br /&gt;# para los que programan en C ;)&lt;br /&gt;# son opcionales :D&lt;br /&gt;holamundo() &lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Tambien el mitico factorial en ruby:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="ruby"&gt;&lt;br /&gt;def factorial(n)&lt;br /&gt;    if n == 0&lt;br /&gt;       1&lt;br /&gt;    else&lt;br /&gt;       n*factorial(n-1)&lt;br /&gt;    end&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/1354794578842586233-7636442374447379891?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/7636442374447379891/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=7636442374447379891' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/7636442374447379891'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/7636442374447379891'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2008/12/highlighting-los-post.html' title='Highlighting a los post'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-8471864926766539286</id><published>2008-12-04T21:37:00.002-02:00</published><updated>2008-12-04T21:54:42.983-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='boludeces'/><category scheme='http://www.blogger.com/atom/ns#' term='rubik'/><title type='text'>Cubos rubiks siameses, para no creer</title><content type='html'>Pasen y vean este fenomeno, cruel error de la naturaleza ( bastante creativo ) al parecer el cubovulo fue inseminado con dos juegos de stickers en lugar de uno, pero no llego a dividirse por completo como para generar cubos gemelos, y el resultado fue esta anomalia:&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/ECpYUrTav4E&amp;hl=es&amp;fs=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/ECpYUrTav4E&amp;hl=es&amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;Un video de una resolucion bastante rapida del cubo:&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/MsLbPjOgds0&amp;hl=es&amp;fs=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/MsLbPjOgds0&amp;hl=es&amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;Tambien un video con los tips de como resolverlo:&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/XKQnHZ_yYJ0&amp;hl=es&amp;fs=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/XKQnHZ_yYJ0&amp;hl=es&amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-8471864926766539286?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/8471864926766539286/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=8471864926766539286' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/8471864926766539286'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/8471864926766539286'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2008/12/cubos-rubiks-siameses-para-no-creer.html' title='Cubos rubiks siameses, para no creer'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-8599665275483378312</id><published>2008-12-04T18:58:00.000-02:00</published><updated>2008-12-04T19:13:54.494-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='botella'/><category scheme='http://www.blogger.com/atom/ns#' term='boludeces'/><category scheme='http://www.blogger.com/atom/ns#' term='destino'/><title type='text'>Robert, fijate la botella del agua</title><content type='html'>¿Fue a caso mi culpa ??, ¿ la mala suerte ?, ¿ sera el destino acaso, si tal cosa existe ?, ¿ o talvez sera la ineludible voluntad de los Dioses ?, mis preguntas comienzan a partir de una conjura de hechos que me ubicaron en el poder y la responsabilidad de ser el guardian universal de la botella atada con un cordon de zapatillas. Pero mejor explico (con narrativa anacronica)&lt;br /&gt;    Cuenta la historia de una vieja que se queja del agua que cae desde el aire acondicionado de nuestra oficina (el aire imprescindible en estas epocas de clima infernal/invernal (el mundo se volvio loco)), la onda es que se quejo , se quejo hasta que no se como terminamos instalando un complejo sistema de tubulacion que redirige la salida estandar del aire acondicionado a la entrada estandar de la botella.&lt;br /&gt;    Una vez, en una epoca , mas o menos al principio del 2008, en la empresa donde trabajo, deciden realzar una instalacion masiva en todas sus sucursales e instalaciones locales, sin percaterse de la anomalia q se avecinaba.&lt;br /&gt;    En un futuro post-apocaliptico, todos en la empresa mueren en un misterioso incendio&lt;br /&gt;    Todo esto lo termino escribiendo en un blog, mientras alguien intenta apagarme la maquina para evitar que la verdad sea rebelada&lt;br /&gt;    Antes de todo eso mande un curriculum para entrar a la empresa.&lt;br /&gt;    Despues de leer toda esa historia en el blog, empiezo a darme cuenta de mi ignorancia acerca de los limites entre la casualidad y la causalidad respecto de porque mi nuevo puesto de trabajo se encuentra convenientemente a 30 centimetros de la famosa botella, y a raiz de entonces, a cada rato me dicen "Robert, fijate la botella de agua" y de ahi me insipiro a inscribir ese articulo del blog&lt;br /&gt;&lt;br /&gt;    FIN???&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-8599665275483378312?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/8599665275483378312/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=8599665275483378312' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/8599665275483378312'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/8599665275483378312'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2008/12/robert-fijate-la-botella-del-agua.html' title='Robert, fijate la botella del agua'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-4171774304645870895</id><published>2008-12-04T18:47:00.000-02:00</published><updated>2008-12-04T18:55:39.634-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='blog'/><title type='text'>Un blog agrego una referencia al mio</title><content type='html'>Es el blog de Diego Gomez, un compañero de laburo, les recomiendo este blog, es bastante completo y tiene todo lo bueno (solo le falta mas fedora y mas ruby, pero exceptuando eso es buenisimo)&lt;br /&gt;&lt;br /&gt;Ahi tienen el blog&lt;br /&gt;&lt;a href=http://blog.dgomez.com.ar/&gt; http://blog.dgomez.com.ar/ &lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Y aca tienen el articulo que referencia a este blog, cerrando de esa manera una referencia ciclica, un circulo infinito referencial:&lt;br /&gt;&lt;br /&gt;&lt;a href=http://blog.dgomez.com.ar/node/46&gt; http://blog.dgomez.com.ar/node/46 &lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-4171774304645870895?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/4171774304645870895/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=4171774304645870895' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/4171774304645870895'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/4171774304645870895'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2008/12/un-blog-agrego-una-referencia-al-mio.html' title='Un blog agrego una referencia al mio'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-4643131613309192032</id><published>2008-12-04T18:31:00.000-02:00</published><updated>2008-12-04T18:56:25.029-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='blog'/><title type='text'>Como me gusta escribir posts en este blog</title><content type='html'>Me gusta escribir post en un blog, sobre posts auto-referenciales como este, hoy empece un blog por presion, y al final estan presionando para que lo deje ¿?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-4643131613309192032?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/4643131613309192032/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=4643131613309192032' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/4643131613309192032'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/4643131613309192032'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2008/12/como-me-gusta-escribir-blogs.html' title='Como me gusta escribir posts en este blog'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-7739398731371424703</id><published>2008-12-04T18:25:00.000-02:00</published><updated>2008-12-04T18:40:51.690-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='boludeces'/><title type='text'>Carencia de syntax highlighthing</title><content type='html'>Dirigido a los millones de seguidores del recien instaurado blog, les ofrezco mis mas sinceras disculpas por haber suspendido los post que incluyen tips de programacion ruby o de otros lenguajes inferiores. Las razones de esta determinacion, es el desconcimiento por parte mia de como ofrecer codigo en el blog con syntax highlighting (y ademas automatico), que de no existir puede causar graves problemas oculares y mentales (cuando chico, en mis inicios, prograba sin highlighting). Es asi, que en favor de la salud ocular, mental, psicologica y espiritual de los lectores, decidi suspender el envio de post que tengan codigo fuente hasta que resualva definitivamente el tema del syntax highlighthing. Disculpen las molestias ocasionadas&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-7739398731371424703?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/7739398731371424703/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=7739398731371424703' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/7739398731371424703'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/7739398731371424703'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2008/12/carencia-de-syntax-highlighthing.html' title='Carencia de syntax highlighthing'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-3712788917354106639</id><published>2008-12-04T18:18:00.000-02:00</published><updated>2008-12-04T18:40:33.943-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='dns'/><category scheme='http://www.blogger.com/atom/ns#' term='bardeo'/><title type='text'>No soy un servidor DNS</title><content type='html'>Cada dos minutos recibo una peticion de resolucion de ip por chat, diciendo :&lt;br /&gt;"pasame la ip de tal servidor", o "dame la ip de tal otro", o "¿te acordas cual es la ip de ese servidor" ?, y yo les contesto con la ip en cuestion de segundos mirando mis tablas hostname =&gt; ip. Me tienen la swap llena, un dia de estos voy a redirigir sus dnss a sitios porno, a ver si se dan cuenta... ( si leen este post no dejen que se enteren... )&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-3712788917354106639?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/3712788917354106639/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=3712788917354106639' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/3712788917354106639'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/3712788917354106639'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2008/12/no-soy-un-servidor-dns.html' title='No soy un servidor DNS'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-3767325821741579888</id><published>2008-12-04T15:49:00.000-02:00</published><updated>2008-12-04T18:39:55.500-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='comentarios'/><category scheme='http://www.blogger.com/atom/ns#' term='boludeces'/><title type='text'>Comentarios del codigo del post anterior (sin el codigo incluido, para q los pongan ustedes hehehe)</title><content type='html'># leo el filename del primer argumento&lt;br /&gt;# leo la expresion en lenguaje ruby del segundo argumento&lt;br /&gt;# si no hay filename finalizo&lt;br /&gt;# leo blocksize del tercer argumento y si no vino le asigno el default de 1&lt;br /&gt;# leo init del cuarto argumento y si no vino le asigno el default de 1&lt;br /&gt;# leo fin del quinto argumento y si no vino le asigno el default de 10&lt;br /&gt;# abro el archivo para recorrerlo, de a bloques&lt;br /&gt;# ejecuto la expresion pasada como parametro, como codigo ruby !!!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-3767325821741579888?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/3767325821741579888/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=3767325821741579888' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/3767325821741579888'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/3767325821741579888'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2008/12/comentarios-del-codigo-del-post.html' title='Comentarios del codigo del post anterior (sin el codigo incluido, para q los pongan ustedes hehehe)'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-3930068327533862575</id><published>2008-12-04T15:39:00.000-02:00</published><updated>2008-12-05T11:19:50.383-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='hexadecimal'/><title type='text'>Como programar un editor hexadecimal programable en 15 minutos y usando menos lineas que el titulo de este post</title><content type='html'>Herramientas necesarias:&lt;br /&gt;* ruby&lt;br /&gt;* ruby&lt;br /&gt;* ruby&lt;br /&gt;* ganas de programar&lt;br /&gt;&lt;br /&gt;... les debo las instrucciones ...&lt;br /&gt;&lt;br /&gt;Codigo terminado:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="ruby"&gt;&lt;br /&gt;class App&lt;br /&gt;        def main( args )&lt;br /&gt;                filename = args[0]&lt;br /&gt;                expresion = args[1]&lt;br /&gt;&lt;br /&gt;                if filename == nil&lt;br /&gt;                        return&lt;br /&gt;                end&lt;br /&gt;&lt;br /&gt;                blocksize = ( args[2] || 1 ).to_i&lt;br /&gt;                init = (args[3] || 0).to_i&lt;br /&gt;                fin = (args[4] || 10).to_i&lt;br /&gt;&lt;br /&gt;                File.open(filename, "rb+") do |file|&lt;br /&gt;&lt;br /&gt;                        i = init&lt;br /&gt;                        while ( i &lt; fin )&lt;br /&gt;                                file.pos = i&lt;br /&gt;&lt;br /&gt;                                stream = file.read(blocksize)&lt;br /&gt;                                origstream = stream.clone&lt;br /&gt;&lt;br /&gt;                                eval(expresion)&lt;br /&gt;&lt;br /&gt;                                if stream != origstream&lt;br /&gt;&lt;br /&gt;                                        file.pos = i&lt;br /&gt;                                        file.write(stream)&lt;br /&gt;                                end&lt;br /&gt;&lt;br /&gt;                                i=i+1&lt;br /&gt;                        end&lt;br /&gt;                end&lt;br /&gt;        end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;App.new.main(ARGV)&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/1354794578842586233-3930068327533862575?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/3930068327533862575/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=3930068327533862575' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/3930068327533862575'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/3930068327533862575'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2008/12/como-programar-un-editor-hexadecimal.html' title='Como programar un editor hexadecimal programable en 15 minutos y usando menos lineas que el titulo de este post'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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-1354794578842586233.post-7510569656615862366</id><published>2008-12-04T15:35:00.000-02:00</published><updated>2008-12-04T18:39:07.961-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='blog'/><category scheme='http://www.blogger.com/atom/ns#' term='NilClass'/><title type='text'>NilClassBlog.new</title><content type='html'>Creado nuevo blog "NilClass", solo porque unos compañeros de laburo lo pidieron ( y creo q tenian razon ) ...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1354794578842586233-7510569656615862366?l=nilclass.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nilclass.blogspot.com/feeds/7510569656615862366/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1354794578842586233&amp;postID=7510569656615862366' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/7510569656615862366'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1354794578842586233/posts/default/7510569656615862366'/><link rel='alternate' type='text/html' href='http://nilclass.blogspot.com/2008/12/nilclassblognew.html' title='NilClassBlog.new'/><author><name>Dario</name><uri>http://www.blogger.com/profile/16298689275729539116</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></feed>
