<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom">
  <title>Magnus Holm</title>
  <subtitle>Thoughts on life, internet and programming</subtitle>
  <id>tag:judofyr.net,1992-10-15:/</id>
  
  <link rel="alternate" type="text/html" href="http://judofyr.net/" />
  <updated>2009-08-21T20:41:03+02:00</updated>
  <author>
    <name>Magnus Holm</name>
    <email>judofyr@gmail.com</email>
    <uri>http://judofyr.net</uri>
  </author>

  <link rel="self" href="http://feeds.feedburner.com/MagnusHolm" type="application/atom+xml" /><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.feedburner.com%2FMagnusHolm" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2FMagnusHolm" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://feeds.my.aol.com/add.jsp?url=http%3A%2F%2Ffeeds.feedburner.com%2FMagnusHolm" src="http://o.aolcdn.com/favorites.my.aol.com/webmaster/ffclient/webroot/locale/en-US/images/myAOLButtonSmall.gif">Subscribe with My AOL</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.bloglines.com/sub/http://feeds.feedburner.com/MagnusHolm" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.feedburner.com%2FMagnusHolm" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2FMagnusHolm" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2FMagnusHolm" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><entry>
    <title>Copy'n'Paste</title>
    <id>tag:judofyr.net,2009-06-05:1244205304</id>
    <link href="http://judofyr.net/posts/copy-paste-irb.html" />
    <updated>2009-06-05T12:35:04Z</updated>
    <published>2009-06-05T12:35:04Z</published>
    <content type="html"><![CDATA[<p>Mac:</p>
<pre class="sunburst">
<span class="Comment"><span class="Comment">#</span> stick in .irbrc</span>
<span class="Keyword">def</span> <span class="Entity">copy</span>(<span class="Variable">str</span>)
  <span class="Variable">IO</span>.<span class="Entity">popen</span>(<span class="String"><span class="String">'</span>pbcopy<span class="String">'</span></span>, <span class="String"><span class="String">'</span>w<span class="String">'</span></span>) { |<span class="Variable">f</span>| f <span class="Keyword">&lt;&lt;</span> str.<span class="Entity">to_s</span> }
<span class="Keyword">end</span>

<span class="Keyword">def</span> <span class="Entity">paste</span>
  <span class="String"><span class="String">`</span>pbpaste<span class="String">`</span></span>
<span class="Keyword">end</span>

<span class="Keyword">def</span> <span class="Entity">ep</span>
  <span class="Entity">eval</span>(paste)
<span class="Keyword">end</span>
</pre>
<p>Linux with xclip (thanks <a href="http://gist.github.com/124272">Bjørn Arild Mæland</a>):</p>
<pre class="sunburst">
<span class="Keyword">def</span> <span class="Entity">copy</span>(<span class="Variable">str</span>)
  <span class="Variable">IO</span>.<span class="Entity">popen</span>(<span class="String"><span class="String">'</span>xclip -i<span class="String">'</span></span>, <span class="String"><span class="String">'</span>w<span class="String">'</span></span>) { |<span class="Variable">f</span>| f <span class="Keyword">&lt;&lt;</span> str.<span class="Entity">to_s</span> }
<span class="Keyword">end</span>
 
<span class="Keyword">def</span> <span class="Entity">paste</span>
  <span class="String"><span class="String">`</span>xclip -o<span class="String">`</span></span>
<span class="Keyword">end</span>
</pre>]]></content>
  </entry>

  <entry>
    <title>GitHub.js</title>
    <id>tag:judofyr.net,2009-05-28:1243528045</id>
    <link href="http://judofyr.net/posts/github-js.html" />
    <updated>2009-05-28T16:27:25Z</updated>
    <published>2009-05-28T16:27:25Z</published>
    <content type="html"><![CDATA[<p><img src="http://www.quicksnapper.com/files/3880/6250845634A1EBC5B6F2A5_m.png" alt="" /></p>
<p>A few weeks ago, <a href="http://github.com/hakunin">hakunin</a> ruined my repo-followers-ratio, and in order to restore balance in my soul I now see no other options than to reveal one of the things I&#8217;ve been playing with lately: <a href="http://github.com/judofyr/github-js"><strong>GitHub.js</strong></a>.</p>
<p>It&#8217;s not very pretty, not very idiomatic and has a nasty dependency on JS.Class. Please remember that I&#8217;m still a novice when it comes to JavaScript, so feel free to <a href="http://github.com/judofyr/github-js">fork away</a> and turn this into something usable.</p>]]></content>
  </entry>

  <entry>
    <title>Nokogirl</title>
    <id>tag:judofyr.net,2009-03-04:1236186825</id>
    <link href="http://judofyr.net/posts/nokogirl.html" />
    <updated>2009-03-04T17:13:45Z</updated>
    <published>2009-03-04T17:13:45Z</published>
    <content type="html"><![CDATA[<p>Every time I play with Nokogiri, I get this weird error:</p>
<pre>
$ irb -rnokogirl
no such file to load -- nokogirl (LoadError)
</pre>
<p>My head just can&#8217;t accept it&#8217;s called <em>nokogiri</em> instead of <em>nokogirl</em>. Hopefully, this should teach me:</p>
<pre>
$ sudo gem install nokogirl
Building native extensions.  This could take a while...

********************************************
It's actually spelled nokogiri, not nokogirl
********************************************

Successfully installed nokogiri-1.2.1
Successfully installed nokogirl-1.0
2 gems installed

$ irb -rnokogirl

********************************************
It's actually spelled nokogiri, not nokogirl
********************************************

&gt;&gt; Nokogirl
=&gt; Nokogiri
</pre>]]></content>
  </entry>

  <entry>
    <title>Change</title>
    <id>tag:judofyr.net,2009-02-08:1234119353</id>
    <link href="http://judofyr.net/posts/change.html" />
    <updated>2009-02-08T18:55:53Z</updated>
    <published>2009-02-08T18:55:53Z</published>
    <content type="html"><![CDATA[<p>Every once in a while we need change. Not only when it comes to presidents and the placement of the telly, but also this specific blog. You see, I&#8217;m <em>proud</em> of this blog. I got subscribers and, once in a while, I get some decent traffic too.</p>
<p><img src="http://img.skitch.com/20090208-q6hmfc87smw59preu1r7i3x571.png" alt="" /></p>
<p>I&#8217;m also very satisfied with both the design and the concept. You start at the top and read until you reach the bottom. No sidebar. No distractions. The content <em>is</em> king. Black, white and red makes it clean; large fonts and line height makes it readable; narrow width makes the paragraphs look longer.</p>
<p>Still, it&#8217;s not perfect. The contrast in the header makes it stand out, almost drowning out the title of the post. The timestamps look like they were just throw on later (they were) and it&#8217;s pretty cramped in the &#8220;Wall of fame&#8221; at the bottom. And I haven&#8217;t styled &lt;h4&gt; at all.</p>
<hr>
<p>Welcome to the new version of <a href="http://judofyr.net">judofyr.net</a>! If you&#8217;re reading this from your feed reader, please come over and have a look. It&#8217;s a lot more cleaner: the title is definitly in focus, the timestamps blend nicely into the rest of the site and it&#8217;s a little more colorful with some blue and green.</p>
<p>It&#8217;s still not perfect. I&#8217;m not totally satisfied with the styling of the sub-headlines and the &#8220;Wall of fame&#8221; has maybe too low contrast. But hey, I&#8217;m a programmer &#8211; I&#8217;m not supposed to design sites.</p>
<p>So, readers, what do you think of this change? After all, this blog is worthless without you. Better? Worse?</p>]]></content>
  </entry>

  <entry>
    <title>Tailin' Ruby</title>
    <id>tag:judofyr.net,2009-01-25:1232892432</id>
    <link href="http://judofyr.net/posts/tailin-ruby.html" />
    <updated>2009-01-25T14:07:12Z</updated>
    <published>2009-01-25T14:07:12Z</published>
    <content type="html"><![CDATA[<p>Ruby doesn&#8217;t do tail call optimization. That sucks. However, quite a few month ago I managed to fake it:</p>
<pre class="sunburst">
<span class="Variable">RunAgain</span> <span class="Keyword">=</span> <span class="Support">Class</span>.<span class="Entity">new</span>(<span class="Variable">Exception</span>)
<span class="Keyword">def</span> <span class="Entity">fib</span>(<span class="Variable">i<span class="Variable">,</span> n <span class="Keyword">=</span> <span class="Constant">1</span><span class="Variable">,</span> result <span class="Keyword">=</span> <span class="Constant">0</span></span>)
  <span class="Keyword">if</span> i <span class="Keyword">==</span> <span class="Keyword">-</span><span class="Constant">1</span>
    result
  <span class="Keyword">else</span>
    <span class="Keyword">raise</span> <span class="Variable">RunAgain</span>
  <span class="Keyword">end</span>
<span class="Keyword">rescue</span> <span class="Variable">RunAgain</span>
  i, n, result <span class="Keyword">=</span> i <span class="Keyword">-</span> <span class="Constant">1</span>, n <span class="Keyword">+</span> result, n
  <span class="Keyword">retry</span>
<span class="Keyword">end</span>
</pre>
<p>It was <strong>extremely</strong> slow (see benchmark at the end of this post) since it has to build backtrace for each raise, but at least it worked! I was proud; <em>very</em> proud. Until I discovered <a href="http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/145593">this snippet</a>:</p>
<pre class="sunburst">
<span class="Keyword">class</span> <span class="JEntityNameType">Class</span>
<span class="Comment">  <span class="Comment">#</span> Sweet stuff!</span>
  <span class="Keyword">def</span> <span class="Entity">tailcall_optimize</span>(<span class="Variable"> <span class="Keyword">*</span>methods </span>)
    methods.<span class="Entity">each</span> <span class="Keyword">do </span>|<span class="Variable">meth</span>|
      org <span class="Keyword">=</span> <span class="Entity">instance_method</span>( meth )
      <span class="Entity">define_method</span>( meth ) <span class="Keyword">do </span>|*<span class="Variable">args</span>|
        <span class="Keyword">if</span> <span class="Support">Thread</span>.<span class="Entity">current</span>[ meth ]
          <span class="Keyword">throw</span>( <span class="Constant"><span class="Constant">:</span>recurse</span>, args )
        <span class="Keyword">else</span>
          <span class="Support">Thread</span>.<span class="Entity">current</span>[ meth ] <span class="Keyword">=</span> org.<span class="Entity">bind</span>( <span class="Variable">self</span> )
          result <span class="Keyword">=</span> <span class="Keyword">catch</span>( <span class="Constant"><span class="Constant">:</span>done</span> ) <span class="Keyword">do</span>
            <span class="Keyword">loop</span> <span class="Keyword">do</span>
              args <span class="Keyword">=</span> <span class="Keyword">catch</span>( <span class="Constant"><span class="Constant">:</span>recurse</span> ) <span class="Keyword">do</span>
                <span class="Keyword">throw</span>( <span class="Constant"><span class="Constant">:</span>done</span>, <span class="Support">Thread</span>.<span class="Entity">current</span>[ meth ].<span class="Entity">call</span>( <span class="Keyword">*</span>args ) )
              <span class="Keyword">end</span>
            <span class="Keyword">end</span>
          <span class="Keyword">end</span>
          <span class="Support">Thread</span>.<span class="Entity">current</span>[ meth ] <span class="Keyword">=</span> <span class="Constant">nil</span>
          result
        <span class="Keyword">end</span>
      <span class="Keyword">end</span>
    <span class="Keyword">end</span>
  <span class="Keyword">end</span>
<span class="Keyword">end</span>

<span class="Keyword">class</span> <span class="JEntityNameType">TCOTest</span>
<span class="Comment">  <span class="Comment">#</span> tail-recursive factorial</span>
  <span class="Keyword">def</span> <span class="Entity">fact</span>(<span class="Variable"> n<span class="Variable">,</span> acc <span class="Keyword">=</span> <span class="Constant">1</span> </span>)
    <span class="Keyword">if</span> n <span class="Keyword">&lt;</span> <span class="Constant">2</span> <span class="Keyword">then</span> acc <span class="Keyword">else</span> <span class="Entity">fact</span>( n<span class="Keyword">-</span><span class="Constant">1</span>, n<span class="Keyword">*</span>acc ) <span class="Keyword">end</span>
  <span class="Keyword">end</span>

<span class="Comment">  <span class="Comment">#</span> length of factorial</span>
  <span class="Keyword">def</span> <span class="Entity">fact_size</span>(<span class="Variable"> n </span>)
    <span class="Entity">fact</span>( n ).<span class="Entity">size</span>
  <span class="Keyword">rescue</span>
    <span class="Variable"><span class="Variable">$</span>!</span>
  <span class="Keyword">end</span>   
<span class="Keyword">end</span>

t <span class="Keyword">=</span> <span class="Variable">TCOTest</span>.<span class="Entity">new</span>

<span class="Comment"><span class="Comment">#</span> normal method</span>
puts t.<span class="Entity">fact_size</span>( <span class="Constant">10000</span> )  <span class="Comment"><span class="Comment">#</span> =&gt; stack level too deep</span>

<span class="Comment"><span class="Comment">#</span> enable tail-call optimization</span>
<span class="Keyword">class</span> <span class="JEntityNameType">TCOTest</span>
  tailcall_optimize <span class="Constant"><span class="Constant">:</span>fact</span>
<span class="Keyword">end</span>

<span class="Comment"><span class="Comment">#</span> tail-call optimized method</span>
puts t.<span class="Entity">fact_size</span>( <span class="Constant">10000</span> )  <span class="Comment"><span class="Comment">#</span> =&gt; 14808                                  </span>
</pre>
<p>Not only was it faster, you could also drop it in wherever you want. Sweet stuff, indeed. My (failed) attempt was sent to /dev/null immediately&#8230;</p>
<h3>The Ruby Programming Language arrives</h3>
<p>A few months later, I received my copy of <a href="http://www.amazon.com/Ruby-Programming-Language-David-Flanagan/dp/0596516177">The Ruby Programming Language</a> and started reading it. Suddenly, on page 151:</p>
<blockquote>
<p><cite>The Ruby Programming Language, page 151, 5.5.4 redo</cite>: The <code>redo</code> statement restarts the current iteration of a loop or iterator. This is not the same thing as <code>next</code>. <code>next</code> transfers control to the end of a loop or block so that the next iteration can begin, whereas <code>redo</code> transfers control back to the top of the loop or block so that the iteration can start over. If you come to Ruby from a C-like language, then <code>redo</code> is probably a new control structure for you.</p>
</blockquote>
<p>I&#8217;ve used Ruby for a long time, still I&#8217;ve never heard of <code>redo</code>&#8230; Here&#8217;s an example from the book:</p>
<pre class="sunburst">
puts <span class="String"><span class="String">&quot;</span>Please enter the first word you think of<span class="String">&quot;</span></span>
words <span class="Keyword">=</span> <span class="String"><span class="String">%w(</span>apple banana cherry<span class="String">)</span></span>
response <span class="Keyword">=</span> words.<span class="Entity">collect</span> <span class="Keyword">do </span>|<span class="Variable">word</span>|
<span class="Comment">  <span class="Comment">#</span> Control returns here when redo is executed</span>
  print word <span class="Keyword">+</span> <span class="String"><span class="String">&quot;</span>&gt; <span class="String">&quot;</span></span>               <span class="Comment"><span class="Comment">#</span> Prompt the user</span>
  response <span class="Keyword">=</span> gets.<span class="Entity">chop</span>            <span class="Comment"><span class="Comment">#</span> Get a response</span>
  <span class="Keyword">if</span> response.<span class="Entity">size</span> <span class="Keyword">==</span> <span class="Constant">0</span>           <span class="Comment"><span class="Comment">#</span> If user entered nothing</span>
    word.<span class="Entity">upcase!</span>                  <span class="Comment"><span class="Comment">#</span> Emphasize the prompt with uppercase</span>
    <span class="Keyword">redo</span>                          <span class="Comment"><span class="Comment">#</span> And skip to the top of the block</span>
  <span class="Keyword">end</span>
  response                        <span class="Comment"><span class="Comment">#</span> Return the response</span>
<span class="Keyword">end</span>
</pre>
<p>So I started thinking: The reason I used raise/rescue in my implementation was because I needed the <code>retry</code>-keyword&#8230; Maybe&#8230; What if?</p>
<pre class="sunburst">
<span class="Keyword">def</span> <span class="Entity">fib</span>(<span class="Variable">i<span class="Variable">,</span> n <span class="Keyword">=</span> <span class="Constant">1</span><span class="Variable">,</span> result <span class="Keyword">=</span> <span class="Constant">0</span></span>)
  <span class="Keyword">if</span> i <span class="Keyword">==</span> <span class="Keyword">-</span><span class="Constant">1</span>
    result
  <span class="Keyword">else</span>
    i, n, result <span class="Keyword">=</span> i <span class="Keyword">-</span> <span class="Constant">1</span>, n <span class="Keyword">+</span> result, n
    <span class="Keyword">redo</span>
  <span class="Keyword">end</span>
<span class="Keyword">end</span>

<span class="Entity">fib</span>(<span class="Constant">10000</span>)
</pre>
<p>Unfortunately, &#8220;The <code>redo</code> statement restarts the currentiteration of a <strong>loop</strong> or <strong>iterator</strong>&#8221;, so it only throws a LocalJumpError. However, don&#8217;t forget that we&#8217;re dealing with Ruby:</p>
<pre class="sunburst">
<span class="Comment"><span class="Comment">#</span>## Everything is possible in Ruby!</span>

<span class="Entity">define_method</span>(<span class="Constant"><span class="Constant">:</span>acc</span>) <span class="Keyword">do </span>|<span class="Variable">i</span>, <span class="Variable">n</span>, <span class="Variable">result</span>|
  <span class="Keyword">if</span> i <span class="Keyword">==</span> <span class="Keyword">-</span><span class="Constant">1</span>
    result
  <span class="Keyword">else</span>
    i, n, result <span class="Keyword">=</span> i <span class="Keyword">-</span> <span class="Constant">1</span>, n <span class="Keyword">+</span> result, n
    <span class="Keyword">redo</span>
  <span class="Keyword">end</span>
<span class="Keyword">end</span>

<span class="Keyword">def</span> <span class="Entity">fib</span>(<span class="Variable">i</span>)
  <span class="Entity">acc</span>(i, <span class="Constant">1</span>, <span class="Constant">0</span>)
<span class="Keyword">end</span>

<span class="Entity">fib</span>(<span class="Constant">10000</span>)  <span class="Comment"><span class="Comment">#</span> Yeah!</span>
</pre>
<h3>The Benchmark</h3>
<p>So, how fast is it? Take a look below:</p>
<p><iframe src="http://judofyr.github.com/recursive/" style="width:660px;height:460px;border:0"></iframe></p>
<ul>
	<li>You can zoom by marking in any of the graphs.</li>
	<li>When you un-tick a graph, mark in the lower graph to zoom in.</li>
	<li>Un-tick everything else than &#8220;Redo&#8221; and &#8220;Iterative&#8221; and notice how close they are to each other.</li>
	<li>Look how bad &#8220;Rescue&#8221; performs,</li>
	<li>and how early &#8220;Regular&#8221; fails.</li>
	<li>All the code is available at <a href="http://github.com/judofyr/recursive">GitHub</a>.</li>
</ul>
<p>Nifty, eh?</p>

]]></content>
  </entry>

  <entry>
    <title>When in Doubt, Turn to _why</title>
    <id>tag:judofyr.net,2009-01-20:1232484292</id>
    <link href="http://judofyr.net/posts/when-in-doubt.html" />
    <updated>2009-01-20T20:44:52Z</updated>
    <published>2009-01-20T20:44:52Z</published>
    <content type="html"><![CDATA[<p><a href="http://groups.google.com/group/rack-devel/browse_thread/thread/1a9b8dc431bff499">Rack can&#8217;t parse nested hash params.</a> That&#8217;s pretty annoying. So while we still can&#8217;t decide how to implement it in the best way, every other framework is cleaning up after Rack. My <a href="http://github.com/judofyr/camping/commit/95d2262c#L0R416">attempt</a> to do it in Camping is clearly a bad solution, so I decided to have a look at other implementations and steal some ideas.</p>
<h3>Let&#8217;s use Sinatra as an example</h3>
<p>Most of them are very similar to Sinatra&#8217;s (this is slightly modified for readability, but the idea still applies):</p>
<pre class="sunburst">
params.<span class="Entity">inject</span>({}) <span class="Keyword">do </span>|<span class="Variable">hash</span>, (<span class="Variable">key</span>, <span class="Variable">value</span>)|
  <span class="Keyword">if</span> key <span class="Keyword">=~</span> <span class="StringRegexp"><span class="StringRegexp">/</span></span><span class="StringRegexp"><span class="StringRegexpSpecial">\[</span>.*<span class="StringRegexpSpecial">\]</span></span><span class="StringRegexp"><span class="StringRegexp">/</span></span>
    parts <span class="Keyword">=</span> key.<span class="Entity">scan</span>(<span class="StringRegexp"><span class="StringRegexp">/</span></span><span class="StringRegexp"><span class="StringRegexp"><span class="StringRegexp">(</span>^<span class="StringRegexp"><span class="StringRegexp">[</span>^<span class="StringRegexpSpecial">\[</span><span class="StringRegexp">]</span></span>+<span class="StringRegexp">)</span></span>|<span class="StringRegexpSpecial">\[</span><span class="StringRegexp"><span class="StringRegexp">(</span><span class="StringRegexp"><span class="StringRegexp">[</span>^<span class="StringRegexpSpecial">\]</span><span class="StringRegexp">]</span></span>+<span class="StringRegexp">)</span></span><span class="StringRegexpSpecial">\]</span></span><span class="StringRegexp"><span class="StringRegexp">/</span></span>).<span class="Entity">flatten</span>.<span class="Entity">compact</span>
    head, last <span class="Keyword">=</span> parts[<span class="Constant">0</span>..<span class="Keyword">-</span><span class="Constant">2</span>], parts[<span class="Keyword">-</span><span class="Constant">1</span>]
    head.<span class="Entity">inject</span>(hash){ |<span class="Variable">s</span>,<span class="Variable">v</span>| s[v] <span class="Keyword">||=</span> {} }[last] <span class="Keyword">=</span> value
  <span class="Keyword">else</span>
    hash[key] <span class="Keyword">=</span> value
  <span class="Keyword">end</span>
  res
<span class="Keyword">end</span>   
</pre>
<p><strong>Update:</strong> As Ryan has written in the comments, I better give some credz to the real author of the snippet above: Sinatra&#8217;s nested params implementation was taken from an example posted to the Rack ML by <strong>Michael Fellinger</strong> (of Ramaze fame). For the background on the patch that went into Sinatra: take a look <a href="http://sinatra.lighthouseapp.com/projects/9779/tickets/70">the ticket</a> over at their bug tracker.</p>
<p>We&#8217;re looping through each of the params and doing some stuff if the key includes [something] and therefore is nested. If it&#8217;s nested, we need to find the parts:</p>
<pre class="sunburst">
parts <span class="Keyword">=</span> key.<span class="Entity">scan</span>(<span class="StringRegexp"><span class="StringRegexp">/</span></span><span class="StringRegexp"><span class="StringRegexp"><span class="StringRegexp">(</span>^<span class="StringRegexp"><span class="StringRegexp">[</span>^<span class="StringRegexpSpecial">\[</span><span class="StringRegexp">]</span></span>+<span class="StringRegexp">)</span></span>|<span class="StringRegexpSpecial">\[</span><span class="StringRegexp"><span class="StringRegexp">(</span><span class="StringRegexp"><span class="StringRegexp">[</span>^<span class="StringRegexpSpecial">\]</span><span class="StringRegexp">]</span></span>+<span class="StringRegexp">)</span></span><span class="StringRegexpSpecial">\]</span></span><span class="StringRegexp"><span class="StringRegexp">/</span></span>).<span class="Entity">flatten</span>.<span class="Entity">compact</span>
</pre>
<p>The first part of the regex matches from the beginning to the first [, and the second matches each of the [parts]. Some cleanup is needed to flatten and remove nils (just try the line in IRB and you&#8217;ll see it quickly).</p>
<p>Next up, we&#8217;re splitting out the last part, and then comes the inject:</p>
<pre class="sunburst">
head.<span class="Entity">inject</span>(hash){ |<span class="Variable">s</span>,<span class="Variable">v</span>| s[v] <span class="Keyword">||=</span> {} }[last] <span class="Keyword">=</span> value  
</pre>
<p>Here, we&#8217;re building a Hash based on the params we&#8217;ve already cleaned up and the current param we&#8217;re working on. Then, finally, we&#8217;re setting the value.</p>
<h3>The _why way</h3>
<p>All of this makes sense. I wrote approximately the same when trying to cleanup my broken version. However, while I was looking for the way Ramaze did it, I found an excellent link to RedHanded: <a href="http://redhanded.hobix.com/inspect/injectingAHashBackwardsAndTheMergeBlock.html">Injecting a Hash Backwards and the Merge Block</a>. That version is just <strong>awesome</strong> (this is also slightly modified):</p>
<pre class="sunburst">
m <span class="Keyword">=</span> proc {|<span class="Variable">_</span>,<span class="Variable">o</span>,<span class="Variable">n</span>|o.<span class="Entity">merge</span>(n,<span class="Keyword">&amp;</span>m)}
params.<span class="Entity">inject</span>({}) <span class="Keyword">do </span>|<span class="Variable">hash</span>, (<span class="Variable">key</span>, <span class="Variable">value</span>)|
  parts <span class="Keyword">=</span> key.<span class="Entity">split</span>(<span class="StringRegexp"><span class="StringRegexp">/</span></span><span class="StringRegexp"><span class="StringRegexp"><span class="StringRegexp">[</span><span class="StringRegexpSpecial">\]</span><span class="StringRegexpSpecial">\[</span><span class="StringRegexp">]</span></span>+</span><span class="StringRegexp"><span class="StringRegexp">/</span></span>)
  hash.<span class="Entity">merge</span>(parts.<span class="Entity">reverse</span>.<span class="Entity">inject</span>(value) { |<span class="Variable">x</span>, <span class="Variable">i</span>| {i =&gt; x} }, <span class="Keyword">&amp;</span>m) 
<span class="Keyword">end</span>    
</pre>
<p>Notice the sweet, micro way to split out the parts: If we got a key like: &#8220;first[second][third]&#8221; we can simply split by any numbers of [ and ]. Of course, we&#8217;re going to fail on stuff like &#8220;this]is]really]one]key&#8221;, but if you&#8217;re writing like that, you deserve it!</p>
<p>Now, the next is what makes this so different and awesome. Let&#8217;s look at first part of it:</p>
<pre class="sunburst">
parts.<span class="Entity">reverse</span>.<span class="Entity">inject</span>(value) { |<span class="Variable">x</span>, <span class="Variable">i</span>| {i =&gt; x} }
</pre>
<p>We&#8217;re <strong>reversing</strong> it and building it backwards. The inject starts with our original value and then we build our way out by creating Hashes:</p>
<pre class="sunburst">
parts <span class="Keyword">=</span> [<span class="String"><span class="String">&quot;</span>first<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>second<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>third<span class="String">&quot;</span></span>]
value <span class="Keyword">=</span> <span class="Constant">123</span>

<span class="Comment"><span class="Comment">#</span> first run of inject:</span>
x <span class="Keyword">=</span> <span class="Constant">123</span>
i <span class="Keyword">=</span> <span class="String"><span class="String">&quot;</span>third<span class="String">&quot;</span></span>
<span class="Keyword">return</span> { <span class="String"><span class="String">&quot;</span>third<span class="String">&quot;</span></span> =&gt; <span class="Constant">123</span> }

<span class="Comment"><span class="Comment">#</span> second run of inject:</span>
x <span class="Keyword">=</span> { <span class="String"><span class="String">&quot;</span>third<span class="String">&quot;</span></span> =&gt; <span class="Constant">123</span> }
i <span class="Keyword">=</span> <span class="String"><span class="String">&quot;</span>second<span class="String">&quot;</span></span>
<span class="Keyword">return</span> { <span class="String"><span class="String">&quot;</span>second<span class="String">&quot;</span></span> =&gt; { <span class="String"><span class="String">&quot;</span>third<span class="String">&quot;</span></span> =&gt; <span class="Constant">123</span> } }

<span class="Comment"><span class="Comment">#</span> second run of inject:</span>
x <span class="Keyword">=</span> { <span class="String"><span class="String">&quot;</span>second<span class="String">&quot;</span></span> =&gt; { <span class="String"><span class="String">&quot;</span>third<span class="String">&quot;</span></span> =&gt; <span class="Constant">123</span> } }
i <span class="Keyword">=</span> <span class="String"><span class="String">&quot;</span>first<span class="String">&quot;</span></span>
<span class="Keyword">return</span> { <span class="String"><span class="String">&quot;</span>first<span class="String">&quot;</span></span> =&gt; { <span class="String"><span class="String">&quot;</span>second<span class="String">&quot;</span></span> =&gt; { <span class="String"><span class="String">&quot;</span>third<span class="String">&quot;</span></span> =&gt; <span class="Constant">123</span> } } }
</pre>
<p>So when we got this little recursive Hash, we need to merge it with the rest. Most of you, including me, would say that it would be a hard task, since we also need to merge it recursively:</p>
<pre class="sunburst">
params <span class="Keyword">=</span> { <span class="String"><span class="String">&quot;</span>first<span class="String">&quot;</span></span> =&gt; { <span class="String"><span class="String">&quot;</span>second<span class="String">&quot;</span></span> =&gt; { <span class="String"><span class="String">&quot;</span>third<span class="String">&quot;</span></span> =&gt; <span class="Constant">123</span> } } }
current_param <span class="Keyword">=</span> { <span class="String"><span class="String">&quot;</span>first<span class="String">&quot;</span></span> =&gt; { <span class="String"><span class="String">&quot;</span>another<span class="String">&quot;</span></span> =&gt; <span class="Constant">456</span> } }

params.<span class="Entity">merge</span>(current_param) <span class="Comment"><span class="Comment">#</span> fail!</span>
current_param.<span class="Entity">merge</span>(params) <span class="Comment"><span class="Comment">#</span> fail!</span>
</pre>
<h3>Meet the Merge Block</h3>
<p>This was the first time I&#8217;ve ever <em>heard</em> of the merge block. It&#8217;s not even properly documented! But it&#8217;s a very simple and very powerful feature: If we get a merge conflict (same keys in both Hashes), it&#8217;s calling that block. Easy peasy!</p>
<pre class="sunburst">
params <span class="Keyword">=</span> { <span class="String"><span class="String">&quot;</span>first<span class="String">&quot;</span></span> =&gt; { <span class="String"><span class="String">&quot;</span>second<span class="String">&quot;</span></span> =&gt; { <span class="String"><span class="String">&quot;</span>third<span class="String">&quot;</span></span> =&gt; <span class="Constant">123</span> } } }
current_param <span class="Keyword">=</span> { <span class="String"><span class="String">&quot;</span>first<span class="String">&quot;</span></span> =&gt; { <span class="String"><span class="String">&quot;</span>another<span class="String">&quot;</span></span> =&gt; <span class="Constant">456</span> } }

params.<span class="Entity">merge</span>(current_param) <span class="Keyword">do </span>|<span class="Variable">key</span>, <span class="Variable">value_from_params</span>, <span class="Variable">value_from_current_param</span>|
<span class="Comment">  <span class="Comment">#</span> key is defined in both params and current_param</span>
  value_from_params.<span class="Entity">merge</span>(value_from_current_param)
<span class="Keyword">end</span>

<span class="Comment"><span class="Comment">#</span> =&gt;</span>
{ <span class="String"><span class="String">&quot;</span>first<span class="String">&quot;</span></span> =&gt; { <span class="String"><span class="String">&quot;</span>second<span class="String">&quot;</span></span> =&gt; { <span class="String"><span class="String">&quot;</span>third<span class="String">&quot;</span></span> =&gt; <span class="Constant">123</span> }, <span class="String"><span class="String">&quot;</span>another<span class="String">&quot;</span></span> =&gt; <span class="Constant">456</span> } }
</pre>
<p>And in order to merge it recursively, we build the block in advance and pass the block into the inner merge too:</p>
<pre class="sunburst">
m <span class="Keyword">=</span> proc {|<span class="Variable">_</span>,<span class="Variable">o</span>,<span class="Variable">n</span>|o.<span class="Entity">merge</span>(n,<span class="Keyword">&amp;</span>m)}
<span class="Comment"><span class="Comment">#</span> ...</span>
hash.<span class="Entity">merge</span>(recursive_hash, <span class="Keyword">&amp;</span>m) 
</pre>
<h3>Shorter? Faster?</h3>
<p>I believe the first, natural way is both faster and shorter (if we use the micro splitter), but I still think I&#8217;m going to put _why&#8217;s version in Camping. Not (only) because it&#8217;s _why&#8217;s, but also because it&#8217;s so wicked awesome and fits perfectly together with the other weird stuff in Camping. Some bytes have to be sacrificed for style; Camping is still far away from exceeding the limit.</p>


]]></content>
  </entry>

  <entry>
    <title>Copy Folders to a Branch</title>
    <id>tag:judofyr.net,2008-12-20:1229795434</id>
    <link href="http://judofyr.net/posts/copy-folders-to-a-branch.html" />
    <updated>2008-12-20T17:50:34Z</updated>
    <published>2008-12-20T17:50:34Z</published>
    <content type="html"><![CDATA[<p><a href="http://github.com/blog/272">GitHub Pages</a> is pretty cool. However, what do you do when you already got your website/docs/whatever in your master-branch? If you checkout the gh-pages branch, the folder disappears and you actually have to copy it to another place before you copy it to your new branch.</p>
<p>If it&#8217;s an automatically generated folder, it&#8217;s a bit easier, but still quite a few commands:</p>
<pre>
rake generate_some_docs
git checkout gh-pages
git add .
git commit
git push
</pre>
<p>It&#8217;s <a href="http://pages.github.com/">even harder</a> if you haven&#8217;t created the gh-pages branch yet.</p>
<h3>Grancher!</h3>
<p>Okey, enter Grancher (yeah, I know, lame name):</p>
<pre class="sunburst">
<span class="Comment"><span class="Comment">#</span> Install:</span>
<span class="Entity">system</span>(<span class="String"><span class="String">'</span>sudo gem install grancher<span class="String">'</span></span>)

<span class="Comment"><span class="Comment">#</span> Create a Rakefile:</span>
<span class="Keyword">require</span> <span class="String"><span class="String">'</span>grancher/task<span class="String">'</span></span>
<span class="Support">Grancher</span>::<span class="Entity">Task</span>.<span class="Entity">new</span> <span class="Keyword">do </span>|<span class="Variable">g</span>|
  g.<span class="Entity">branch</span> <span class="Keyword">=</span> <span class="String"><span class="String">'</span>gh-pages<span class="String">'</span></span>
  g.<span class="Entity">push_to</span> <span class="Keyword">=</span> <span class="String"><span class="String">'</span>origin<span class="String">'</span></span> <span class="Comment"><span class="Comment">#</span> automatically push too</span>
  
  g.<span class="Entity">directory</span> <span class="String"><span class="String">'</span>website<span class="String">'</span></span>
<span class="Keyword">end</span>
</pre>
<p>Do a <code>rake publish</code> and the folder will be copied to the gh-pages branch, committed and pushed. Easy peasy!</p>
<p>Have a look at <a href="http://judofyr.github.com/grancher">the documentation</a> which isn&#8217;t actually perfect, but should be enough to get started.</p>
<p>Oh, and it&#8217;s just a few hours old, so bugs will probably bite you! <em>When</em> they do, please report it at <a href="http://dojo.lighthouseapp.com/projects/22240-grancher/overview">lighthouse</a>.</p>


]]></content>
  </entry>

  <entry>
    <title>Cracking TootSweet's Masyu Format</title>
    <id>tag:judofyr.net,2008-12-13:1229200165</id>
    <link href="http://judofyr.net/posts/cracking-tootsweets-masyu-format.html" />
    <updated>2008-12-13T20:29:25Z</updated>
    <published>2008-12-13T20:29:25Z</published>
    <content type="html"><![CDATA[<p><em>This post is not exactly well written; it&#8217;s more like a dump of my brain at the moment. I&#8217;m sorry, but I didn&#8217;t have time (or interest) to write it properly. It&#8217;s a lot of information and writing stuff isn&#8217;t quite my thing.</em></p>
<blockquote>
<p><cite><a href="http://tootsweet.com/masyu">TootSweet Masyu</a></cite>: <strong>Masyu</strong> is played on a grid. It has a simple goal: to draw a single
nonintersecting loop through all of the circles in the grid.</p>
<p>The masyu grid contains two kinds of circles. Each adds a constraint to the
path of the loop.</p>
</blockquote>
<p>Masyu is a type of logic puzzle designed by the same guys behind Sudoku. Needless to say, it&#8217;s very fun and extremely addicting. Especially when you play it on your iPoid, thanks to TootSweet:</p>
<p><img src="http://img.skitch.com/20081213-r65y5bnwf9jkxt96cpbtwcxjcj.png" alt="" /></p>
<p>Of course, I didn&#8217;t like the thought of all those beautiful, hand-made puzzles should be stuck on the iPod, so I wanted to see how they were stored. After SSH-ing to the iPod, a simple <code>find /User/Applications/ -wholename *MasyuBug.app</code> revealed where the files to MasyuBug were stored:</p>
<p><img src="http://img.skitch.com/20081213-cups8uy4t6psuujd7qydmynddt.png" alt="" /></p>
<p>And there, right in Documents was a Puzzles.data. <code>head -c 6 Puzzles.data</code> revealed that it was a SQLite-file and only seconds later I got the schema:</p>
<pre>
CREATE TABLE properties ( 
  key text primary key,
  value text default null);

CREATE TABLE puzzles ( 
  id integer primary key autoincrement,
  puzzle text,
  name text default null, 
  size integer default 0,
  volume integer default 0,
  board text default null,
  checkpoint text default null,
  status integer default 0,
  solution_date default null);
</pre>
<p>The puzzles-database looks interesting. Let&#8217;s have a look:</p>
<pre>
sqlite&gt; SELECT id,puzzle,name,board,status FROM puzzles LIMIT 3;
 id | puzzle     | name    | board | status
  1 | 4:4:AgAQAA | Ladybug | ww:gq | 2
  2 | 4:4:CCQQQA | Aphid   | AA:IC | 1
  3 | 4:4:gAAECA | Cicada  | AA:AA | 0    
</pre>
<p>After some testing with <code>UPDATE</code>-statements I assumed this:</p>
<ul>
	<li>Puzzle contains the size and the puzzle</li>
	<li>Board contains the current lines</li>
	<li>Status: 2 = solved, 1 = started, 0 = not started</li>
</ul>
<h3>The Puzzle</h3>
<p>So I decided I wanted to crack the puzzle-field first and filled the field with various data:</p>
<ul>
	<li>AAAAAA = empty board</li>
	<li>BAAAAA = white circle in top-left corner</li>
	<li>ABAAAA = the white circle moved three squares right</li>
	<li>AABAAA = the white circle moved three squares right (wrapped by the 4&#215;4-board)</li>
	<li>AAABAA = the white circle moved another three squares right</li>
</ul>
<p>Obviously, each letter represented three squares, but what do they mean? After 52 UPDATE&#8217;s I ended up with this table:</p>
<p><img src="http://img.skitch.com/20081213-mtfekqwn3ypegkuufqeyxh6j7d.png" alt="" /></p>
<p>Can you spot how TootSweet&#8217;s converts letters to circles? It took me a while, but suddenly I realized it: it&#8217;s base-4. It&#8217;s in fact reversed base-4 where 0 and 3 = blank, 1 = white and 2 = white. Let me show you two examples:</p>
<p>The letter S is in the 18th position of our table (starting from zero), and 18 is 102 in base-4. Reverse it and you&#8217;ll get 201: One black, one blank and one white.</p>
<p>The letter X is in the 23th position, and 23 is 113 in base-4. Reverse it and you&#8217;ll get 311: One blank, two whites.</p>
<p>Ruby version:</p>
<pre class="sunburst">
<span class="Variable">ALPHA</span> <span class="Keyword">=</span> (<span class="String"><span class="String">'</span>A<span class="String">'</span></span>..<span class="String"><span class="String">'</span>Z<span class="String">'</span></span>).<span class="Entity">to_a</span> <span class="Keyword">+</span> (<span class="String"><span class="String">'</span>a<span class="String">'</span></span>..<span class="String"><span class="String">'</span>z<span class="String">'</span></span>).<span class="Entity">to_a</span>
<span class="Keyword">def</span> <span class="Entity">letter</span>(<span class="Variable">l</span>)
  num <span class="Keyword">=</span> <span class="Variable">ALPHA</span>.<span class="Entity">index</span>(l)
  num.<span class="Entity">to_s</span>(<span class="Constant">4</span>).<span class="Entity">rjust</span>(<span class="Constant">3</span>, <span class="String"><span class="String">'</span>0<span class="String">'</span></span>).<span class="Entity">reverse</span>.<span class="Entity">split</span>(<span class="String"><span class="String">'</span><span class="String">'</span></span>).<span class="Entity">map</span>{ |<span class="Variable">x</span>| x.<span class="Entity">to_i</span> <span class="Keyword">%</span> <span class="Constant">3</span> }
<span class="Keyword">end</span>
</pre>
<h3>The Lines</h3>
<p>Let&#8217;s see how TootSweet&#8217;s stores the lines you&#8217;ve drawn. I started drawing lines in the app and watched how the board-field changed:</p>
<ul>
	<li>AA:AA = no lines</li>
	<li>The first two letters changed when I draw a horizontal line</li>
	<li>The last two letters changed when I draw a vertical line</li>
	<li>The first letter changed when I draw a line on one of the six first places.</li>
	<li>Same with the second</li>
</ul>
<p>It made sense that each letter represented six lines. And, since I knew how TootSweet rolls, it made even more sense that it&#8217;s reversed base-2. I had to extend the ALPHA-list, since it needed 64 (2 ** 6) letters to represent every possibility from 000000 to 111111, through some more drawing on the iPod it turned out I just had to append 0 to 9 and + and /.</p>
<h4>Example</h4>
<p>0 is in the 52nd position of our new table (starting from zero), and 52 in base-2 is 110100. Reversed it&#8217;s 001011 and it would look like this (if we assumed that the 0 was in the first letter):</p>
<p><img src="http://img.skitch.com/20081213-m7sxgug2in8w1pigi17ubtbu2y.png" alt="" /></p>
<p>Ruby version:</p>
<pre class="sunburst">
<span class="Variable">ALPHA</span> <span class="Keyword">=</span> (<span class="String"><span class="String">'</span>A<span class="String">'</span></span>..<span class="String"><span class="String">'</span>Z<span class="String">'</span></span>).<span class="Entity">to_a</span> <span class="Keyword">+</span> (<span class="String"><span class="String">'</span>a<span class="String">'</span></span>..<span class="String"><span class="String">'</span>z<span class="String">'</span></span>).<span class="Entity">to_a</span> <span class="Keyword">+</span> (<span class="String"><span class="String">'</span>0<span class="String">'</span></span>..<span class="String"><span class="String">'</span>9<span class="String">'</span></span>).<span class="Entity">to_a</span> <span class="Keyword">+</span> <span class="String"><span class="String">%w(</span>+ /<span class="String">)</span></span>
<span class="Keyword">def</span> <span class="Entity">line</span>(<span class="Variable">l</span>)
  num <span class="Keyword">=</span> <span class="Variable">ALPHA</span>.<span class="Entity">index</span>(l)
  num.<span class="Entity">to_s</span>(<span class="Constant">2</span>).<span class="Entity">rjust</span>(<span class="Constant">6</span>, <span class="String"><span class="String">'</span>0<span class="String">'</span></span>).<span class="Entity">reverse</span>.<span class="Entity">split</span>(<span class="String"><span class="String">'</span><span class="String">'</span></span>).<span class="Entity">map</span> { |<span class="Variable">x</span>| x.<span class="Entity">to_i</span> }
<span class="Keyword">end</span>
</pre>
<h3>Don&#8217;t be evil, please</h3>
<p>I reengineered this just as a challenge. It was a lot of fun. However, if you ever want to write Masyu application, <strong>don&#8217;t</strong> steal TootSweet&#8217;s hand-made masyus. I&#8217;m sure they&#8217;ve spent a lot of time on this, and beside, it&#8217;s boring to solve the same puzzle twice.</p>
<p>What you <em>could</em> use this information to, is importing puzzles from people&#8217;s iPhones, so they can continue to solve the puzzle on their computer. Or, you can store your own puzzles in this format and this can end up as the standard way to store Masyu puzzles. Even though it&#8217;s a bit cryptic, the puzzles are quite small when they&#8217;re stored this way, and can then easily be shared over IRC and forums.</p>
<p>We&#8217;ll see if I ever will use this&#8230;</p>]]></content>
  </entry>

  <entry>
    <title>Morse.rb</title>
    <id>tag:judofyr.net,2008-10-19:1224440120</id>
    <link href="http://judofyr.net/posts/morse.html" />
    <updated>2008-10-19T18:15:20Z</updated>
    <published>2008-10-19T18:15:20Z</published>
    <content type="html"><![CDATA[<p>Some of you might have noticed my <a href="http://refactormycode.com/codes/513-morse-code-encoder-decoder#refactor_41227">little attempt on refactoring</a>. However, I quickly realized that it could be solved in a much simpler way:</p>
<pre class="sunburst">
<span class="Keyword">module</span>                    <span class="JEntityNameType">Morse</span>

 <span class="Variable">A</span>,<span class="Variable">B</span>,<span class="Variable">C</span><span class="Keyword">=</span>proc{<span class="Variable">M</span>.<span class="Entity">tr</span>(<span class="String"><span class="String">'</span> <span class="String">'</span></span>,<span class="String"><span class="String">'</span><span class="String">'</span></span>).<span class="Entity">gsub</span>(<span class="StringRegexp"><span class="StringRegexp">/</span></span><span class="StringRegexp"><span class="StringRegexpSpecial"><span class="StringRegexpSpecial">#{</span><span class="StringVariable"><span class="StringVariable">$</span>/</span><span class="StringRegexpSpecial">}</span></span>+</span><span class="StringRegexp"><span class="StringRegexp">/</span></span>,<span class="Variable"><span class="Variable">$</span>/</span>).<span class="Entity">split</span>(<span class="Variable"><span class="Variable">$</span>/</span>).<span class="Entity">map</span>{|<span class="Variable">x</span>|
x[<span class="StringRegexp"><span class="StringRegexp">/</span></span><span class="StringRegexp"><span class="StringRegexp"><span class="StringRegexp">(</span>.<span class="StringRegexp">)</span></span><span class="StringRegexp"><span class="StringRegexp">(</span>.+<span class="StringRegexp">)</span></span><span class="StringRegexp"><span class="StringRegexp">(</span>.<span class="StringRegexp">)</span></span>.*<span class="StringRegexpSpecial">\1</span><span class="StringRegexpSpecial">\2</span><span class="StringRegexpSpecial">\3</span></span><span class="StringRegexp"><span class="StringRegexp">/</span></span>,<span class="Constant">2</span>].<span class="Entity">to_i</span>(<span class="Constant">16</span>)}},proc{|<span class="Variable">c</span>|<span class="Variable">A</span>[][c<span class="Keyword">-</span><span class="Constant">65</span>].<span class="Entity">to_s</span>(<span class="Constant">2</span>
    )[<span class="Constant">1</span>..<span class="Keyword">-</span><span class="Constant">1</span>].<span class="Entity">tr</span>(<span class="String"><span class="String">'</span>10<span class="String">'</span></span>,<span class="String"><span class="String">'</span>-.<span class="String">'</span></span>)},proc{|<span class="Variable">m</span>|(<span class="Variable">A</span>[].<span class="Entity">index</span>((<span class="String"><span class="String">&quot;</span>1<span class="String">&quot;</span></span><span class="Keyword">+</span>m.<span class="Entity">tr</span>(
              <span class="String"><span class="String">'</span>-.<span class="String">'</span></span>,<span class="String"><span class="String">'</span>10<span class="String">'</span></span>)).<span class="Entity">to_i</span>(<span class="Constant">2</span>))<span class="Keyword">||</span><span class="Keyword">return</span>)<span class="Keyword">+</span><span class="Constant">65</span>}              

<span class="Keyword">def</span>                  <span class="Entity">self.encode</span>(<span class="Variable">str</span>)
         str.<span class="Entity">upcase</span>.<span class="Entity">split</span>(<span class="StringRegexp"><span class="StringRegexp">/</span></span><span class="StringRegexp"></span><span class="StringRegexp"><span class="StringRegexp">/</span></span>).<span class="Entity">map</span>{|<span class="Variable">c</span>|(<span class="Constant">65</span>..<span class="Constant">90</span>)<span class="Keyword">===</span>
      (c<span class="Keyword">=</span>c[<span class="Constant">0</span>])<span class="Constant">?B</span>[c]<span class="Constant"><span class="Constant">:</span>c</span><span class="Keyword">==</span><span class="Constant">32</span>?<span class="String"><span class="String">'</span>|<span class="String">'</span></span><span class="Constant"><span class="Constant">:</span>nil</span>}.<span class="Entity">compact</span>.<span class="Entity">join</span>(<span class="String"><span class="String">'</span> <span class="String">'</span></span>)
                                                          <span class="Keyword">end</span>

<span class="Keyword">def</span>                  <span class="Entity">self.decode</span>(<span class="Variable">str</span>)
 str.<span class="Entity">split</span>(<span class="String"><span class="String">'</span> <span class="String">'</span></span>).<span class="Entity">map</span>{|<span class="Variable">m</span>|m[<span class="Constant">0</span>]<span class="Keyword">==</span><span class="Constant">?|</span><span class="Constant">?'</span> <span class="String"><span class="String">'</span>:(m=C[m])&amp;&amp;m.chr}.join</span>
<span class="String">                                                          end</span>
<span class="String"></span>
<span class="String">                   self.methods(false).</span>
<span class="String">               map{|m|class&lt;&lt;self;self;end.</span>
<span class="String">            send(:define_method,m+&quot;_file&quot;){|f|</span>
<span class="String">      File.readlines(f).map{|l|send(m,l)}.join $/}}</span>
<span class="String"></span>
<span class="String"></span>
<span class="String">M =              &lt;&lt;-<span class="String">'</span></span><span class="Variable">LETS</span> <span class="Variable">GO</span> <span class="Variable">MORSING</span>!<span class="String"><span class="String">'</span></span>
<span class="String">   3DC5D1BBFBE596573E0EE011500C2959ED1469891C5D9120EA8</span>
<span class="String">   D18A6BF9C806A8A15A77A5788575BD18A0233578435B20884FE</span>
<span class="String"></span>
<span class="String">                       A1AAAAAA1AA </span>
<span class="String">                   BCD             BCD</span>
<span class="String">                   123             123</span>
<span class="String">              412C127               140C127</span>
<span class="String">                      87EB9557EB757      </span>
<span class="String"></span>
<span class="String">         7103B03517D082301871039DD318B6ABEB04981</span>
<span class="String">         2A44EFBD92A0B694FE1ECC094F42E7F7DF37AF7</span>
<span class="String">         9781      765A3C96E24326A0F58      1764</span>
<span class="String">         2D3C        3399D0D588D492D        3A95</span>
<span class="String">         AB74          D14522116D1          45E3</span>
<span class="String">         6833      7     A807B37     A      F32E</span>
<span class="String">         BD57      4F      C61      EC      613F</span>
<span class="String">         07EF      733E     F     7DEA      540F</span>
<span class="String">         E285      04F691       656291      6595</span>
<span class="String">         85EC      1D8343A     C1D82A1      9F95</span>
<span class="String">         F5A3      7F8D02D25A357BEDC75      4958</span>
<span class="String">         86C8      61F6679FFEB2DF19CEC      8673</span>
<span class="String">         0706      DC3C81C810CBEBA76FC      CC3C </span>
<span class="String">         32B7      91791ADFE02C7664F6E      7D51</span>
<span class="String">         1111      656B15AA24FF66461FD      1111</span>
<span class="String">         0BD60F270C533AE418A5A99E65950BD26D003CF</span>
<span class="String">         1BC023CDEBA3CE19D0CF7E0B50607C7E19DD396</span>
<span class="String"></span>
<span class="String"></span>
<span class="String">   11B878DCDAEAE1AE136657420A26AF87356FCD6DA11B80CDD4F</span>
<span class="String">   22C2201C00354CD948A67CAAA92566A7E4515CAADADC8FA01C0</span>
<span class="String">                     LETS GO MORSING!</span>
<span class="String">                                                          end </span>
</pre>]]></content>
  </entry>

  <entry>
    <title>It's a Gash, Gash, Gash</title>
    <id>tag:judofyr.net,2008-09-27:1222517387</id>
    <link href="http://judofyr.net/posts/its-a-gash-gash-gash.html" />
    <updated>2008-09-27T12:09:47Z</updated>
    <published>2008-09-27T12:09:47Z</published>
    <content type="html"><![CDATA[
<pre>sudo gem install gash</pre>
<ul>
	<li>Gash lets you access a Git-repo as a Hash.</li>
	<li>Gash doesn&#8217;t touch your working directory</li>
	<li>Gash only cares about the data, not the commits.</li>
	<li>Gash only cares about the <em>latest</em> data.</li>
	<li>Gash can commit.</li>
	<li>Gash will automatically create branches if they don&#8217;t exist.</li>
	<li>Gash only loads what it needs, so it handles large repos well.</li>
	<li>Gash got <a href="http://dojo.rubyforge.org/gash">pretty good documentation</a>.</li>
	<li>Gash got <a href="http://dojo.lighthouseapp.com/projects/17529-gash">a bug tracker</a>.</li>
	<li>Gash is being <a href="http://github.com/judofyr/gash">developed at GitHub</a>.</li>
</ul>
<h3>Let me show you what I mean&#8230;</h3>
<pre class="sunburst">
<span class="Keyword">require</span> <span class="String"><span class="String">'</span>gash<span class="String">'</span></span>
wiki <span class="Keyword">=</span> <span class="Support">Gash</span>.<span class="Entity">new</span>(<span class="String"><span class="String">&quot;</span>~/programming/sources/gash/.git<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>wiki<span class="String">&quot;</span></span>)

<span class="Comment"><span class="Comment">#</span> See, it doesn't exists yet!</span>
wiki.<span class="Entity">branch_exists?</span> <span class="Comment"><span class="Comment">#</span> =&gt; false</span>

<span class="Comment"><span class="Comment">#</span> Lets add some files...</span>
wiki[<span class="String"><span class="String">&quot;</span>Start<span class="String">&quot;</span></span>] <span class="Keyword">=</span> <span class="String"><span class="String">&quot;</span>Welcome to this great [[Wiki]]!<span class="String">&quot;</span></span>
wiki[<span class="String"><span class="String">&quot;</span>Wiki<span class="String">&quot;</span></span>] <span class="Keyword">=</span> <span class="String"><span class="String">&quot;</span>Something everyone can edit.<span class="String">&quot;</span></span>

<span class="Comment"><span class="Comment">#</span> And commit them.</span>
wiki.<span class="Entity">commit</span>(<span class="String"><span class="String">&quot;</span>First verision<span class="String">&quot;</span></span>)

<span class="Comment"><span class="Comment">#</span> Now it exists!</span>
wiki.<span class="Entity">branch_exists?</span> <span class="Comment"><span class="Comment">#</span> =&gt; true</span>

<span class="Comment"><span class="Comment">#</span> We can use all the regular Hash-methods too:</span>
wiki.<span class="Entity">merge!</span>(<span class="String"><span class="String">&quot;</span>Start<span class="String">&quot;</span></span> =&gt; <span class="String"><span class="String">&quot;</span>Se our new section: [[Git]]<span class="String">&quot;</span></span>,
            <span class="String"><span class="String">&quot;</span>Git/About<span class="String">&quot;</span></span> =&gt; <span class="String"><span class="String">&quot;</span>An awesome SCM.<span class="String">&quot;</span></span>)

wiki[<span class="String"><span class="String">&quot;</span>GitSCM<span class="String">&quot;</span></span>] <span class="Keyword">=</span> wiki.<span class="Entity">delete</span>(<span class="String"><span class="String">&quot;</span>Git<span class="String">&quot;</span></span>)

wiki.<span class="Entity">commit</span>(<span class="String"><span class="String">&quot;</span>Adding a Git-section<span class="String">&quot;</span></span>)

<span class="Comment"><span class="Comment">#</span> And some special methods:</span>
wiki[<span class="String"><span class="String">&quot;</span>Git<span class="String">&quot;</span></span>].<span class="Entity">tree?</span>                         <span class="Comment"><span class="Comment">#</span> =&gt; true</span>
wiki[<span class="String"><span class="String">&quot;</span>Git/About<span class="String">&quot;</span></span>] <span class="Keyword">==</span> wiki[<span class="String"><span class="String">&quot;</span>Git<span class="String">&quot;</span></span>][<span class="String"><span class="String">&quot;</span>About<span class="String">&quot;</span></span>] <span class="Comment"><span class="Comment">#</span> =&gt; true</span>
wiki[<span class="String"><span class="String">&quot;</span>Git/About<span class="String">&quot;</span></span>].<span class="Entity">blob?</span>                   <span class="Comment"><span class="Comment">#</span> =&gt; true</span>
wiki[<span class="String"><span class="String">&quot;</span>Git/About<span class="String">&quot;</span></span>].<span class="Entity">sha1</span>                    <span class="Comment"><span class="Comment">#</span> =&gt; &quot;123456789&quot;</span>
wiki[<span class="String"><span class="String">&quot;</span>Git/About<span class="String">&quot;</span></span>].<span class="Entity">mode</span>                    <span class="Comment"><span class="Comment">#</span> =&gt; &quot;100644&quot;</span>
</pre>

]]></content>
  </entry>
</feed>
