<?xml version="1.0" encoding="utf-8"?>
<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="self" type="application/atom+xml" href="http://judofyr.net/feed/atom.xml"/>
  <link rel="alternate" type="text/html" href="http://judofyr.net/"/>
  <updated>2010-05-03T20:26:05+02:00</updated>
  <author>
    <name>Magnus Holm</name>
    <email>judofyr@gmail.com</email>
    <uri>http://judofyr.net</uri>
  </author>

  <entry>
    <title>Chained Comparisons</title>
    <id>tag:judofyr.net,2010-05-03:1272910693</id>
    <link href="http://judofyr.net/posts/chained-comparisons.html"/>
    <updated>2010-05-03T18:18:13Z</updated>
    <published>2010-05-03T18:18:13Z</published>
    <content type="html"><![CDATA[<p>I think I could need some help to <a href="http://refactormycode.com/codes/1284-chained-comparisons-in-ruby">refactor this code&#8230;</a></p>
<pre class="sunburst">
<span class="Comment"><span class="Comment">#</span># Implementing chained comparisons in Ruby</span>

(<span class="Constant">1</span>..<span class="Constant">10</span>).<span class="Entity">each</span> <span class="Keyword">do </span>|<span class="Variable">x</span>|
  <span class="Keyword">case</span>
  <span class="Keyword">when</span> x <span class="Keyword">&lt;</span> <span class="Constant">3</span>
    puts <span class="String"><span class="String">&quot;</span><span class="StringEmbeddedSource"><span class="StringEmbeddedSource">#{</span>x<span class="StringEmbeddedSource">}</span></span> is quite low<span class="String">&quot;</span></span>
  <span class="Keyword">when</span> <span class="Constant">3</span> <span class="Keyword">&lt;=</span> x <span class="Keyword">&lt;</span> <span class="Constant">6</span>
    puts <span class="String"><span class="String">&quot;</span><span class="StringEmbeddedSource"><span class="StringEmbeddedSource">#{</span>x<span class="StringEmbeddedSource">}</span></span> is quite all right<span class="String">&quot;</span></span>
  <span class="Keyword">when</span> <span class="Constant">6</span> <span class="Keyword">&lt;=</span> x <span class="Keyword">&lt;</span> <span class="Constant">10</span>
    puts <span class="String"><span class="String">&quot;</span><span class="StringEmbeddedSource"><span class="StringEmbeddedSource">#{</span>x<span class="StringEmbeddedSource">}</span></span> is quite fine<span class="String">&quot;</span></span>
  <span class="Keyword">when</span> <span class="Constant">10</span> <span class="Keyword">&lt;=</span> x
    puts <span class="String"><span class="String">&quot;</span><span class="StringEmbeddedSource"><span class="StringEmbeddedSource">#{</span>x<span class="StringEmbeddedSource">}</span></span> is quite high<span class="String">&quot;</span></span>
  <span class="Keyword">end</span>
<span class="Keyword">end</span>


lets
  <span class="Keyword">BEGIN</span> {
        
<span class="Support">Object</span>.<span class="Entity">send</span>(<span class="Keyword">*</span>                                                           
  <span class="String"><span class="String">&quot;</span>ZGVmaW5lX21ldGhvZA=bWV0aG9kX21pc3Npbmc=<span class="String">&quot;</span></span>.<span class="Entity">unpack</span>(<span class="String"><span class="String">&quot;</span>mm<span class="String">&quot;</span></span>                      )
                                                                          ){|*|}
[[],[<span class="Constant">61</span>]].<span class="Entity">inject</span>([]){|<span class="Variable">_</span>,<span class="Variable">__</span>|_<span class="Keyword">&lt;&lt;</span>[<span class="Constant">60</span>,<span class="Keyword">*</span>__]<span class="Keyword">&lt;&lt;</span>[<span class="Constant">62</span>,<span class="Keyword">*</span>__]}.<span class="Entity">map</span>{|<span class="Variable">_</span>|_.<span class="Entity">pack</span>(<span class="String"><span class="String">&quot;</span>c*<span class="String">&quot;</span></span>        )}.
each { |<span class="Variable">a</span>| [<span class="Variable">Float</span>, <span class="Variable">Fixnum</span>, <span class="Variable">Comparable</span>].<span class="Entity">each</span> { |<span class="Variable">b</span>| b.<span class="Entity">class_eval</span>               {
c <span class="Keyword">=</span> <span class="Entity">instance_method</span>(a) <span class="Keyword">and</span> <span class="Entity">define_method</span>(a) { |<span class="Variable">d</span>| c.<span class="Entity">bind</span>(<span class="Variable">self</span>).<span class="Entity">call</span>(d) <span class="Keyword">and</span> d }
                                                                      
there                                                                        }
  is                                                                         }
    no              ;<span class="Support">FalseClass</span>.<span class="Entity">class_eval</span> <span class="String"><span class="String">&quot;</span>def %s(*) false end<span class="String">&quot;</span></span><span class="Keyword">%</span>a           }
      <span class="Keyword">END</span>                                                                   {}
                                                                            
to                                                                          
  this                                                                      
    madness                                                                  }
                                                                            
this
  is
    <span class="Variable">RUBY</span>!
      (<span class="Keyword">not</span> perl?)
</pre>]]></content>
  </entry>

  <entry>
    <title>Use the Gemspec</title>
    <id>tag:judofyr.net,2010-04-02:1270243397</id>
    <link href="http://judofyr.net/posts/gemspecs.html"/>
    <updated>2010-04-02T21:23:17Z</updated>
    <published>2010-04-02T21:23:17Z</published>
    <content type="html"><![CDATA[<p>You can say a lot about GitHub&#8217;s <a href="http://github.com/blog/515-gem-building-is-defunct">previous gem hosting</a>, but at least it helped us understanding one thing: the value of a gemspec.</p>
<p>The gemspec is the README of the bits and the bytes of your code. It can both be understood and changed by both computers and humans. We shouldn&#8217;t fear the gemspec; we should embrace it.</p>
<p>Storing the data in the Rakefile and generating the gemspec seems totally backwards to me. Rakefile is for tasks, let&#8217;s place the data where it belongs: <strong>in the gemspec</strong>.</p>
<p>Instead of building tools which generates the gemspec, let&#8217;s build tools that <em>uses</em> the gemspec.</p>
<p>Like <code>gem build rails.gemspec</code>.</p>
<p>Like the newest <a href="http://dojo.rubyforge.org/gemify">Gemify</a>:</p>
<pre>
$ gemify
Currently editing gemify.gemspec

Which task would you like to invoke?
1) Change name (required) = gemify
2) Change summary (required) = The lightweight gemspec editor
3) Change version (required) = 0.3
4) Change author = Magnus Holm
5) Change email = judofyr@gmail.com
6) Change homepage = http://dojo.rubyforge.org/
7) Set dependencies

s) Save
r) Reload (discard unsaved changes)
m) Rename
l) List files

x) Exit
</pre>
<hr>
<p>It&#8217;s not a solved problem though.</p>
<p>Rubygems can read any gemspec with Gem::Specification.load, but can only write it back again with #to_ruby in a normalized version.</p>
<p>Let&#8217;s have a look at <a href="http://yehudakatz.com/2010/04/02/using-gemspecs-as-intended/">Bundler&#8217;s excellent gemspec:</a></p>
<pre class="sunburst">
<span class="Comment"><span class="Comment">#</span> -*- encoding: utf-8 -*-</span>
lib <span class="Keyword">=</span> <span class="Support">File</span>.<span class="Entity">expand_path</span>(<span class="String"><span class="String">'</span>../lib/<span class="String">'</span></span>, <span class="Variable">__FILE__</span>)
<span class="Variable"><span class="Variable">$</span>:</span>.<span class="Entity">unshift</span> lib <span class="Keyword">unless</span> <span class="Variable"><span class="Variable">$</span>:</span>.<span class="Entity">include?</span>(lib)

<span class="Keyword">require</span> <span class="String"><span class="String">'</span>bundler/version<span class="String">'</span></span>

<span class="Support">Gem</span>::<span class="Entity">Specification</span>.<span class="Entity">new</span> <span class="Keyword">do </span>|<span class="Variable">s</span>|
  s.<span class="Entity">name</span>        <span class="Keyword">=</span> <span class="String"><span class="String">&quot;</span>bundler<span class="String">&quot;</span></span>
  s.<span class="Entity">version</span>     <span class="Keyword">=</span> <span class="Support">Bundler</span>::<span class="Entity">VERSION</span>
  s.<span class="Entity">platform</span>    <span class="Keyword">=</span> <span class="Support">Gem</span>::<span class="Entity">Platform</span>::<span class="Entity">RUBY</span>
  s.<span class="Entity">authors</span>     <span class="Keyword">=</span> [<span class="String"><span class="String">&quot;</span>Carl Lerche<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>Yehuda Katz<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>André Arko<span class="String">&quot;</span></span>]
  s.<span class="Entity">email</span>       <span class="Keyword">=</span> [<span class="String"><span class="String">&quot;</span>carlhuda@engineyard.com<span class="String">&quot;</span></span>]
  s.<span class="Entity">homepage</span>    <span class="Keyword">=</span> <span class="String"><span class="String">&quot;</span>http://github.com/carlhuda/bundler<span class="String">&quot;</span></span>
  s.<span class="Entity">summary</span>     <span class="Keyword">=</span> <span class="String"><span class="String">&quot;</span>The best way to manage your application's dependencies<span class="String">&quot;</span></span>

  s.<span class="Entity">required_rubygems_version</span> <span class="Keyword">=</span> <span class="String"><span class="String">&quot;</span>&gt;= 1.3.6<span class="String">&quot;</span></span>
  s.<span class="Entity">rubyforge_project</span>         <span class="Keyword">=</span> <span class="String"><span class="String">&quot;</span>bundler<span class="String">&quot;</span></span>

  s.<span class="Entity">add_development_dependency</span> <span class="String"><span class="String">&quot;</span>rspec<span class="String">&quot;</span></span>

  s.<span class="Entity">files</span>        <span class="Keyword">=</span> <span class="Support">Dir</span>.<span class="Entity">glob</span>(<span class="String"><span class="String">&quot;</span>{bin,lib}/**/*<span class="String">&quot;</span></span>) <span class="Keyword">+</span> <span class="String"><span class="String">%w(</span>LICENSE README.md ROADMAP.md CHANGELOG.md<span class="String">)</span></span>
  s.<span class="Entity">executables</span>  <span class="Keyword">=</span> [<span class="String"><span class="String">'</span>bundle<span class="String">'</span></span>]
  s.<span class="Entity">require_path</span> <span class="Keyword">=</span> <span class="String"><span class="String">'</span>lib<span class="String">'</span></span>
<span class="Keyword">end</span>
</pre>
<p>Short and concise. After running it through <code>Gem::Specification.load(file).to_ruby</code>:</p>
<pre class="sunburst">
<span class="Comment"><span class="Comment">#</span> -*- encoding: utf-8 -*-</span>

<span class="Support">Gem</span>::<span class="Entity">Specification</span>.<span class="Entity">new</span> <span class="Keyword">do </span>|<span class="Variable">s</span>|
  s.<span class="Entity">name</span> <span class="Keyword">=</span> <span class="String"><span class="String">%q{</span>bundler<span class="String">}</span></span>
  s.<span class="Entity">version</span> <span class="Keyword">=</span> <span class="String"><span class="String">&quot;</span>0.10.pre<span class="String">&quot;</span></span>

  s.<span class="Entity">required_rubygems_version</span> <span class="Keyword">=</span> <span class="Support">Gem</span>::<span class="Entity">Requirement</span>.<span class="Entity">new</span>(<span class="String"><span class="String">&quot;</span>&gt;= 1.3.6<span class="String">&quot;</span></span>) <span class="Keyword">if</span> s.<span class="Entity">respond_to?</span> <span class="Constant"><span class="Constant">:</span>required_rubygems_version=</span>
  s.<span class="Entity">authors</span> <span class="Keyword">=</span> [<span class="String"><span class="String">&quot;</span>Carl Lerche<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>Yehuda Katz<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>Andr<span class="StringConstant">\3</span>03<span class="StringConstant">\2</span>51 Arko<span class="String">&quot;</span></span>]
  s.<span class="Entity">date</span> <span class="Keyword">=</span> <span class="String"><span class="String">%q{</span>2010-04-03<span class="String">}</span></span>
  s.<span class="Entity">default_executable</span> <span class="Keyword">=</span> <span class="String"><span class="String">%q{</span>bundle<span class="String">}</span></span>
  s.<span class="Entity">email</span> <span class="Keyword">=</span> [<span class="String"><span class="String">&quot;</span>carlhuda@engineyard.com<span class="String">&quot;</span></span>]
  s.<span class="Entity">executables</span> <span class="Keyword">=</span> [<span class="String"><span class="String">&quot;</span>bundle<span class="String">&quot;</span></span>]
  s.<span class="Entity">files</span> <span class="Keyword">=</span> <span class="String"><span class="String">%w[</span>one huge array<span class="String">]</span></span>
  s.<span class="Entity">homepage</span> <span class="Keyword">=</span> <span class="String"><span class="String">%q{</span>http://github.com/carlhuda/bundler<span class="String">}</span></span>
  s.<span class="Entity">require_paths</span> <span class="Keyword">=</span> [<span class="String"><span class="String">&quot;</span>lib<span class="String">&quot;</span></span>]
  s.<span class="Entity">rubyforge_project</span> <span class="Keyword">=</span> <span class="String"><span class="String">%q{</span>bundler<span class="String">}</span></span>
  s.<span class="Entity">rubygems_version</span> <span class="Keyword">=</span> <span class="String"><span class="String">%q{</span>1.3.6<span class="String">}</span></span>
  s.<span class="Entity">summary</span> <span class="Keyword">=</span> <span class="String"><span class="String">%q{</span>The best way to manage your application's dependencies<span class="String">}</span></span>

  <span class="Keyword">if</span> s.<span class="Entity">respond_to?</span> <span class="Constant"><span class="Constant">:</span>specification_version</span> <span class="Keyword">then</span>
    current_version <span class="Keyword">=</span> <span class="Support">Gem</span>::<span class="Entity">Specification</span>::<span class="Entity">CURRENT_SPECIFICATION_VERSION</span>
    s.<span class="Entity">specification_version</span> <span class="Keyword">=</span> <span class="Constant">3</span>

    <span class="Keyword">if</span> <span class="Support">Gem</span>::<span class="Entity">Version</span>.<span class="Entity">new</span>(<span class="Support">Gem</span>::<span class="Entity">RubyGemsVersion</span>) <span class="Keyword">&gt;=</span> <span class="Support">Gem</span>::<span class="Entity">Version</span>.<span class="Entity">new</span>(<span class="String"><span class="String">'</span>1.2.0<span class="String">'</span></span>) <span class="Keyword">then</span>
      s.<span class="Entity">add_development_dependency</span>(<span class="String"><span class="String">%q&lt;</span>rspec<span class="String">&gt;</span></span>, [<span class="String"><span class="String">&quot;</span>&gt;= 0<span class="String">&quot;</span></span>])
    <span class="Keyword">else</span>
      s.<span class="Entity">add_dependency</span>(<span class="String"><span class="String">%q&lt;</span>rspec<span class="String">&gt;</span></span>, [<span class="String"><span class="String">&quot;</span>&gt;= 0<span class="String">&quot;</span></span>])
    <span class="Keyword">end</span>
  <span class="Keyword">else</span>
    s.<span class="Entity">add_dependency</span>(<span class="String"><span class="String">%q&lt;</span>rspec<span class="String">&gt;</span></span>, [<span class="String"><span class="String">&quot;</span>&gt;= 0<span class="String">&quot;</span></span>])
  <span class="Keyword">end</span>
<span class="Keyword">end</span>
</pre>
<p>Boom, there goes your nice VERSION constant. And no more Dir globbing for you.</p>
<hr>
<p>We need to make it possible to write interactive gemspec (heck, that&#8217;s why they are written in Ruby!) <strong>and</strong> make them easily readable by computers <strong>and</strong> make them easily <em>modified</em> by computers without losing the interactivity.</p>
<p>Anyone?</p>

]]></content>
  </entry>

  <entry>
    <title>Introducing SexpBuilder</title>
    <id>tag:judofyr.net,2010-02-12:1265999072</id>
    <link href="http://judofyr.net/posts/sexp-builder.html"/>
    <updated>2010-02-12T18:24:32Z</updated>
    <published>2010-02-12T18:24:32Z</published>
    <content type="html"><![CDATA[<p>I&#8217;m a dreamer. When I see something like this:</p>
<pre class="sunburst">
<span class="Keyword">def</span> <span class="Entity">process_call</span>(<span class="Variable">exp</span>)
<span class="Comment">  <span class="Comment">#</span> exp[1] =&gt; reciever.</span>
<span class="Comment">  <span class="Comment">#</span> exp[2] =&gt; method</span>
<span class="Comment">  <span class="Comment">#</span> exp[3] =&gt; (args)</span>
  exp[<span class="Constant">3</span>] <span class="Keyword">=</span> <span class="Entity">process</span>(exp[<span class="Constant">3</span>])
  <span class="Keyword">if</span> <span class="Entity">text?</span>(exp)
    s(<span class="Constant"><span class="Constant">:</span>parkaby</span>, <span class="Constant"><span class="Constant">:</span>text</span>, exp[<span class="Constant">3</span>])
  <span class="Keyword">elsif</span> tag <span class="Keyword">=</span> <span class="Entity">force_tag_call?</span>(exp) <span class="Keyword">||</span> <span class="Entity">tag_call?</span>(exp)
    s(<span class="Constant"><span class="Constant">:</span>parkaby</span>, <span class="Constant"><span class="Constant">:</span>tag</span>, <span class="Keyword">*</span>tag)
  <span class="Keyword">else</span>
    exp
  <span class="Keyword">end</span>
<span class="Keyword">end</span>
</pre>
<p>I just write down what I want it to look like:</p>
<pre class="sunburst">
rule <span class="Constant"><span class="Constant">:</span>tag_call</span> <span class="Keyword">do</span>
<span class="Comment">  <span class="Comment">#</span> Forced tag call</span>
  s(<span class="Constant"><span class="Constant">:</span>call</span>,
   s(<span class="Constant"><span class="Constant">:</span>call</span>, <span class="Constant">nil</span>, <span class="Constant"><span class="Constant">:</span>tag</span>, s(<span class="Constant"><span class="Constant">:</span>arglist</span>)),
   wild <span class="Keyword">%</span> <span class="Constant"><span class="Constant">:</span>name</span>,
   args <span class="Keyword">%</span> <span class="Constant"><span class="Constant">:</span>args</span>) <span class="Keyword">|</span>

<span class="Comment">  <span class="Comment">#</span> or regular tag call</span>
  s(<span class="Constant"><span class="Constant">:</span>call</span>,
  <span class="Constant">nil</span>,
  name <span class="Keyword">%</span> <span class="Constant"><span class="Constant">:</span>name</span>,
  args <span class="Keyword">%</span> <span class="Constant"><span class="Constant">:</span>args</span>)
<span class="Keyword">end</span>

rule <span class="Constant"><span class="Constant">:</span>text</span> <span class="Keyword">do</span>
  s(<span class="Constant"><span class="Constant">:</span>call</span>, <span class="Constant">nil</span>,      <span class="Constant"><span class="Constant">:</span>text</span>, s(<span class="Constant"><span class="Constant">:</span>arglist</span>, wild <span class="Keyword">%</span> <span class="Constant"><span class="Constant">:</span>content</span>)) <span class="Keyword">|</span>
  s(<span class="Constant"><span class="Constant">:</span>call</span>, s(<span class="Constant"><span class="Constant">:</span>self</span>), <span class="Constant"><span class="Constant">:</span>&lt;&lt;</span>,   s(<span class="Constant"><span class="Constant">:</span>arglist</span>, wild <span class="Keyword">%</span> <span class="Constant"><span class="Constant">:</span>content</span>))
<span class="Keyword">end</span>
</pre>
<p>Then I implement it.</p>
<p>Okay. The above examples aren&#8217;t quite equal, so let&#8217;s have a look at what I&#8217;m really trying to solve.</p>
<h3>Matching complex Sexp in Parkaby</h3>
<p>Parkaby is my little experiment to make a super-duper-freaky-fast Markaby replacement by parsing the source and &#8220;compiling&#8221; it. Ultimately, a template like:</p>
<pre class="sunburst">
h1 <span class="String"><span class="String">&quot;</span>Hello World!<span class="String">&quot;</span></span>
p <span class="String"><span class="String">&quot;</span>Welcome <span class="StringEmbeddedSource"><span class="StringEmbeddedSource">#{</span><span class="StringVariable"><span class="StringVariable">@</span>user</span><span class="StringEmbeddedSource">}</span></span><span class="String">&quot;</span></span>
</pre>
<p>Should be compiled into:</p>
<pre class="sunburst">
<span class="String"><span class="String">&quot;</span>&lt;h1&gt;Hello World!&lt;/h1&gt;&lt;p&gt;Welcome <span class="StringEmbeddedSource"><span class="StringEmbeddedSource">#{</span><span class="StringVariable"><span class="StringVariable">@</span>user</span><span class="StringEmbeddedSource">}</span></span>&lt;/p&gt;<span class="String">&quot;</span></span>
</pre>
<p>In Parkaby, this involes two steps: a <em>processor</em> which figures out what should be considered HTML-tags and what should be considered regular method calls, and a <em>generator</em> which compiles it into Ruby. An interesting aspect of Parkaby is that the processor actually is quite complex. For instance, it has to figure out that <code>div.post.clearfix.main!(:style =&gt; "display:none")</code> should be compiled to <code>&lt;div class="post clearfix" id="main" style =&gt; "display:none"&gt;&lt;/div&gt;</code>.</p>
<p>My original approach was to use SexpProcessor:</p>
<pre class="sunburst">
<span class="Keyword">def</span> <span class="Entity">process_call</span>(<span class="Variable">exp</span>)
<span class="Comment">  <span class="Comment">#</span> exp[1] =&gt; reciever.</span>
<span class="Comment">  <span class="Comment">#</span> exp[2] =&gt; method</span>
<span class="Comment">  <span class="Comment">#</span> exp[3] =&gt; (args)</span>
  exp[<span class="Constant">3</span>] <span class="Keyword">=</span> <span class="Entity">process</span>(exp[<span class="Constant">3</span>])
  <span class="Keyword">if</span> <span class="Entity">text?</span>(exp)
    s(<span class="Constant"><span class="Constant">:</span>parkaby</span>, <span class="Constant"><span class="Constant">:</span>text</span>, exp[<span class="Constant">3</span>])
  <span class="Keyword">elsif</span> tag <span class="Keyword">=</span> <span class="Entity">force_tag_call?</span>(exp) <span class="Keyword">||</span> <span class="Entity">tag_call?</span>(exp)
    s(<span class="Constant"><span class="Constant">:</span>parkaby</span>, <span class="Constant"><span class="Constant">:</span>tag</span>, <span class="Keyword">*</span>tag)
  <span class="Keyword">else</span>
    exp
  <span class="Keyword">end</span>
<span class="Keyword">end</span>
</pre>
<p>Every time it finds a method call, it checks if it&#8217;s a text-node or a HTML-tag and then turns it into a parkaby-sexp, or it just leaves it alone. The code ended up quite messy, and that&#8217;s before I even tried implementing CSS-proxy (tag.klass.klass.klass.id!): <a href="http://github.com/judofyr/parkaby/blob/237873/lib/parkaby/processor.rb">Parkaby before SexpBuilder.</a></p>
<p>Just thinking of implementing CSS-proxy got me a light headache, so I quickly realized that something had to be done.</p>
<h3>Adam Sanderson to the rescue!</h3>
<p>Ka-poof! Adam Sanderson writes <a href="http://github.com/adamsanderson/sexp_path">SexpPath</a>.</p>
<p>SexpPath is a DSL for matching Sexp. Let&#8217;s say we want to match <code>text "Hello"</code> and <code>self &lt;&lt; "Hello"</code>:</p>
<pre class="sunburst">
<span class="Comment"><span class="Comment">#</span> text &quot;Hello&quot;</span>
sexp1 <span class="Keyword">=</span> s(<span class="Constant"><span class="Constant">:</span>call</span>, <span class="Constant">nil</span>, <span class="Constant"><span class="Constant">:</span>text</span>, s(<span class="Constant"><span class="Constant">:</span>arglist</span>, s(<span class="Constant"><span class="Constant">:</span>str</span>, <span class="String"><span class="String">&quot;</span>Hello<span class="String">&quot;</span></span>)))
<span class="Comment"><span class="Comment">#</span> self &lt;&lt; &quot;Hello&quot;</span>
sexp2 <span class="Keyword">=</span> s(<span class="Constant"><span class="Constant">:</span>call</span>, s(<span class="Constant"><span class="Constant">:</span>self</span>), <span class="Constant"><span class="Constant">:</span>&lt;&lt;</span>, s(<span class="Constant"><span class="Constant">:</span>arglist</span>, s(<span class="Constant"><span class="Constant">:</span>str</span>, <span class="String"><span class="String">&quot;</span>Hello<span class="String">&quot;</span></span>)))

<span class="Comment"><span class="Comment">#</span> the old approach:</span>
<span class="Keyword">def</span> <span class="Entity">like_text?</span>(<span class="Variable">exp</span>)
  rec_meth <span class="Keyword">=</span> exp[<span class="Constant">1</span>..<span class="Constant">2</span>].<span class="Entity">to_a</span>
  rec_meth <span class="Keyword">==</span> [[<span class="Constant"><span class="Constant">:</span>self</span>], <span class="Constant"><span class="Constant">:</span>&lt;&lt;</span>] <span class="Keyword">||</span> rec_meth <span class="Keyword">==</span> [<span class="Constant">nil</span>, <span class="Constant"><span class="Constant">:</span>text</span>]
<span class="Keyword">end</span>

<span class="Keyword">def</span> <span class="Entity">text?</span>(<span class="Variable">exp</span>)
  <span class="Entity">like_text?</span>(exp) <span class="Keyword">and</span>
  exp[<span class="Constant">3</span>].<span class="Entity">length</span> <span class="Keyword">==</span> <span class="Constant">2</span>
<span class="Keyword">end</span>

<span class="Comment"><span class="Comment">#</span> the SexpPath approach:</span>
query <span class="Keyword">=</span> <span class="Variable">Q</span>? <span class="Keyword">do</span>
  s(<span class="Constant"><span class="Constant">:</span>call</span>, <span class="Constant">nil</span>,      <span class="Constant"><span class="Constant">:</span>text</span>, s(<span class="Constant"><span class="Constant">:</span>arglist</span>, wild <span class="Keyword">%</span> <span class="Constant"><span class="Constant">:</span>content</span>)) <span class="Keyword">|</span>
  s(<span class="Constant"><span class="Constant">:</span>call</span>, s(<span class="Constant"><span class="Constant">:</span>self</span>), <span class="Constant"><span class="Constant">:</span>&lt;&lt;</span>,   s(<span class="Constant"><span class="Constant">:</span>arglist</span>, wild <span class="Keyword">%</span> <span class="Constant"><span class="Constant">:</span>content</span>))
<span class="Keyword">end</span>
</pre>
<p>Isn&#8217;t that pretty? The vertical-bar means &#8220;or&#8221;, `wild` matches everything and the percent sign captures the value in a Hash. Exactly what I want.</p>
<h3>SexpBuilder</h3>
<pre class="sunburst">
gem install sexp_builder
</pre>
<p>Well, SexpPath alone wasn&#8217;t enough to solve my problem &#8211; I had to introduce a new library. SexpBuilder is a more complete solution to easily match and replace complex Sexp. Very much like a parser, you define matchers and rules, and by combining them with a rewriter it was breeze to implement CSS-proxy.</p>
<p>Have a look at <a href="http://dojo.rubyforge.org/">http://dojo.rubyforge.org/</a> for documentation, and <a href="http://github.com/judofyr/parkaby/blob/master/lib/parkaby/processor.rb">Parkaby::Processor</a> if you want a full example. There&#8217;s also <a href="http://github.com/judofyr/sexp_builder/blob/master/examples/andand.rb">Andand.rb</a> for a more traditional example/demo.</p>
<h3>What about Parkaby?</h3>
<p>Well, at the moment, Parkaby is resting. In order to fully support it on other platforms than MRI, I&#8217;ll have to start yet another project. And that&#8217;s not happening until I release a few other projects I&#8217;m working on (like SexpBuilder).</p>]]></content>
  </entry>

  <entry>
    <title>Continue that exception</title>
    <id>tag:judofyr.net,2010-01-18:1263833010</id>
    <link href="http://judofyr.net/posts/never-gonna-let-you-go.html"/>
    <updated>2010-01-18T16:43:30Z</updated>
    <published>2010-01-18T16:43:30Z</published>
    <content type="html"><![CDATA[<p>Imagine a world with Exception#continue:</p>
<pre class="sunburst">
<span class="Constant">10</span>.<span class="Entity">times</span> <span class="Keyword">do </span>|<span class="Variable">i</span>|
  <span class="Keyword">begin</span>
    <span class="Keyword">raise</span> <span class="String"><span class="String">&quot;</span>OH NO!<span class="String">&quot;</span></span>
    puts <span class="String"><span class="String">&quot;</span>OH YES! <span class="StringEmbeddedSource"><span class="StringEmbeddedSource">#{</span>i<span class="StringEmbeddedSource">}</span></span><span class="String">&quot;</span></span>
    i <span class="Keyword">+=</span> <span class="Constant">1</span>
  <span class="Keyword">rescue</span> =&gt; err
    <span class="Keyword">if</span> i <span class="Keyword">&lt;</span> <span class="Constant">5</span>
      err.<span class="Entity">continue</span>
    <span class="Keyword">else</span>
      <span class="Keyword">raise</span> err
    <span class="Keyword">end</span>
  <span class="Keyword">end</span>
<span class="Keyword">end</span>
</pre>
<p>Oh, that&#8217;s right. This is Ruby. Forty lines later:</p>
<pre class="sunburst">
<span class="Keyword">class</span> <span class="JEntityNameType">Exception</span>
  <span class="Keyword">class</span> <span class="JEntityNameType">NoContinuation<span class="EntityInheritedClass"> <span class="EntityInheritedClass">&lt;</span> StandardError</span></span>
  <span class="Keyword">end</span>
  
  <span class="Keyword">attr_accessor</span> <span class="Constant"><span class="Constant">:</span>continuation</span>
  
  <span class="Keyword">def</span> <span class="Entity">continue</span>
    <span class="Keyword">raise</span> <span class="Variable">NoContinuation</span> <span class="Keyword">unless</span> continuation.<span class="Entity">respond_to?</span>(<span class="Constant"><span class="Constant">:</span>call</span>)
    continuation.<span class="Entity">call</span>
  <span class="Keyword">end</span>
<span class="Keyword">end</span>

<span class="Keyword">module</span> <span class="JEntityNameType">NeverGonnaLetYouDown</span>
  <span class="Keyword">def</span> <span class="Entity">raise</span>(<span class="Variable">exception <span class="Keyword">=</span> <span class="Variable">RuntimeError</span><span class="Variable">,</span> string <span class="Keyword">=</span> <span class="Constant">nil</span><span class="Variable">,</span> array <span class="Keyword">=</span> caller</span>)
<span class="Comment">    <span class="Comment">#</span> With a single String argument, raises a</span>
<span class="Comment">    <span class="Comment">#</span> RuntimeError with the string as a message. </span>
    <span class="Keyword">if</span> exception.<span class="Entity">is_a?</span>(<span class="Variable">String</span>)
      string <span class="Keyword">=</span> exception
      exception <span class="Keyword">=</span> <span class="Variable">RuntimeError</span>
    <span class="Keyword">end</span>
    
    callcc <span class="Keyword">do </span>|<span class="Variable">cc</span>|
      obj <span class="Keyword">=</span> exception.<span class="Entity">exception</span>(string)
      obj.<span class="Entity">set_backtrace</span>(array)
      obj.<span class="Entity">continuation</span> <span class="Keyword">=</span> cc
      <span class="Keyword">super</span> obj
    <span class="Keyword">end</span>
  <span class="Keyword">end</span>
  
  <span class="Keyword">def</span> <span class="Entity">fail</span>(<span class="Variable">exception <span class="Keyword">=</span> <span class="Variable">RuntimeError</span><span class="Variable">,</span> string <span class="Keyword">=</span> <span class="Constant">nil</span><span class="Variable">,</span> array <span class="Keyword">=</span> caller</span>)
    <span class="Keyword">raise</span>(exception, string, array)
  <span class="Keyword">end</span>
<span class="Keyword">end</span>

<span class="Keyword">class</span> <span class="JEntityNameType">Object</span>
  <span class="Keyword">include</span> <span class="Variable">NeverGonnaLetYouDown</span>
<span class="Keyword">end</span>
</pre>]]></content>
  </entry>

  <entry>
    <title>Temple</title>
    <id>tag:judofyr.net,2009-12-12:1260643090</id>
    <link href="http://judofyr.net/posts/temple.html"/>
    <updated>2009-12-12T18:38:10Z</updated>
    <published>2009-12-12T18:38:10Z</published>
    <content type="html"><![CDATA[<p>I have a theory:</p>
<blockquote>
<p>Every compilable template can be compiled to ERB.</p>
</blockquote>
<p>Well, not ERB-the-syntax, but ERB-the-concept:</p>
<blockquote>
<p>Every compilable template consists of three elements:</p>
<ul>
	<li>Static text</li>
	<li>Dynamic text (pieces of Ruby which are evaluated and sent to the client)</li>
	<li>Blocks (pieces of Ruby which are evaluated and <em>not</em> sent to the client, but might change the control flow).
</blockquote></li>
</ul>
<p>Nothing revolutionary at all. Just a theory.</p>
<h3>Compiling it</h3>
<p>There are several ways to render such a template, but the fastest one is to compile it to pure Ruby:</p>
<pre>
Hello &lt;%= @world %&gt;!
&lt;% if @me.happy? %&gt;
  &lt;%= @greeting %&gt;
&lt;% end %&gt;
</pre>
<p>Becomes:</p>
<pre class="sunburst">
_buf <span class="Keyword">=</span> []
_buf <span class="Keyword">&lt;&lt;</span> <span class="String"><span class="String">&quot;</span>Hello <span class="String">&quot;</span></span>
_buf <span class="Keyword">&lt;&lt;</span> (<span class="Variable"><span class="Variable">@</span>world</span>)
_buf <span class="Keyword">&lt;&lt;</span> <span class="String"><span class="String">&quot;</span>!<span class="StringConstant">\n</span><span class="String">&quot;</span></span>
<span class="Keyword">if</span> <span class="Variable"><span class="Variable">@</span>me</span>.<span class="Entity">happy?</span>
_buf <span class="Keyword">&lt;&lt;</span> <span class="String"><span class="String">&quot;</span><span class="StringConstant">\n</span>  <span class="String">&quot;</span></span>
_buf <span class="Keyword">&lt;&lt;</span> (<span class="Variable"><span class="Variable">@</span>greeting</span>)
_buf <span class="Keyword">&lt;&lt;</span> <span class="String"><span class="String">&quot;</span><span class="StringConstant">\n</span><span class="String">&quot;</span></span>
<span class="Keyword">end</span>
_buf.<span class="Entity">join</span>
</pre>
<p>Probably you also want to optimize it:</p>
<pre class="sunburst">
_buf <span class="Keyword">=</span> []
_buf <span class="Keyword">&lt;&lt;</span> (<span class="String"><span class="String">&quot;</span>Hello <span class="StringEmbeddedSource"><span class="StringEmbeddedSource">#{</span><span class="StringVariable"><span class="StringVariable">@</span>world</span><span class="StringEmbeddedSource">}</span></span>!<span class="StringConstant">\n</span><span class="String">&quot;</span></span>)
<span class="Keyword">if</span> <span class="Variable"><span class="Variable">@</span>me</span>.<span class="Entity">happy?</span>
_buf <span class="Keyword">&lt;&lt;</span> (<span class="String"><span class="String">&quot;</span><span class="StringConstant">\n</span>  <span class="StringEmbeddedSource"><span class="StringEmbeddedSource">#{</span><span class="StringVariable"><span class="StringVariable">@</span>greeting</span><span class="StringEmbeddedSource">}</span></span><span class="StringConstant">\n</span><span class="String">&quot;</span></span>)
<span class="Keyword">end</span>
_buf.<span class="Entity">join</span>
</pre>
<p>Or maybe you rather want <code>_buf</code> to be a String? Or print it directly to stdout?</p>
<p>These options are already written and implemented in Erubis, but none of the other template engines can take advantage of that. Which is a shame, because we know that every compilable template can be compiled to ERB. So <em>technically</em> it shouldn&#8217;t be a problem to share such code.</p>
<h3>Abstractions</h3>
<p>The problem with today&#8217;s template engines is that they aren&#8217;t using enough abstractions. Mustache parses and compiles at the same time<sup class="footnote"><a href="#fn1">1</a></sup>. Haml does parsing/compiling/optimization in some tightly coupled modules. Parkaby separates parsing and compiling, but could share a lot of code with Haml since they&#8217;re both compiling HTML tags. While I haven&#8217;t checked it out, I assume the same applies to <a href="http://github.com/stonean/ruhl">RuHL</a>. Liquid doesn&#8217;t really compile (to Ruby) at all, but rather uses a VM approach.</p>
<p>Every template developers faces the same questions: Should I use an Array or String as buffer? How should I escape it? How can I optimize it? Or, they don&#8217;t even compile it at all.</p>
<h3>Enter the Temple</h3>
<p><a href="http://github.com/judofyr/temple">Temple</a> attempts to solve these problems. Your goal as a template developer is to end up with an Array like this:</p>
<pre class="sunburst">
[<span class="Constant"><span class="Constant">:</span>multi</span>,
 [<span class="Constant"><span class="Constant">:</span>static</span>, <span class="String"><span class="String">&quot;</span>Hello <span class="String">&quot;</span></span>],
 [<span class="Constant"><span class="Constant">:</span>dynamic</span>, <span class="String"><span class="String">&quot;</span>@world<span class="String">&quot;</span></span>],
 [<span class="Constant"><span class="Constant">:</span>static</span>, <span class="String"><span class="String">&quot;</span>!<span class="StringConstant">\n</span><span class="String">&quot;</span></span>],
 [<span class="Constant"><span class="Constant">:</span>block</span>, <span class="String"><span class="String">&quot;</span>if @me.happy?<span class="String">&quot;</span></span>],
 [<span class="Constant"><span class="Constant">:</span>static</span>, <span class="String"><span class="String">&quot;</span><span class="StringConstant">\n</span>  <span class="String">&quot;</span></span>],
 [<span class="Constant"><span class="Constant">:</span>dynamic</span>, <span class="String"><span class="String">&quot;</span>@greeting<span class="String">&quot;</span></span>],
 [<span class="Constant"><span class="Constant">:</span>static</span>, <span class="String"><span class="String">&quot;</span><span class="StringConstant">\n</span><span class="String">&quot;</span></span>],
 [<span class="Constant"><span class="Constant">:</span>block</span>, <span class="String"><span class="String">&quot;</span>end<span class="String">&quot;</span></span>]]
</pre>
<p>Then let Temple take over. You could use Temple::Filters::DynamicInliner to optimize sequential statics/dynamics into a single dynamic. Temple::Filters::Escapable handles escaping, and Temple::Core::ArrayBuffer generates the Ruby code.</p>
<p>The idea is to build an engine based on a chain of compilers. A compiler is simply a class which has a method called <em>#compile</em> which takes one arguments. It&#8217;s illegal for a compiler to mutate the argument, and it should be possible to use the same instance several times.</p>
<p>Very much like you have middlewares in Rack, you use compilers in Temple (except <em>everything</em> is a compiler in Temple):</p>
<pre class="sunburst">
<span class="Keyword">class</span> <span class="JEntityNameType">ERBEngine<span class="EntityInheritedClass"> <span class="EntityInheritedClass">&lt;</span> Temple::Engine</span></span>
  use <span class="Support">Temple</span>::<span class="Entity">Parsers</span>::<span class="Entity">ERB</span>
  use <span class="Support">Temple</span>::<span class="Entity">Filters</span>::<span class="Entity">DynamicInliner</span>
  use <span class="Support">Temple</span>::<span class="Entity">Core</span>::<span class="Entity">ArrayBuffer</span>
<span class="Keyword">end</span>  
</pre>
<h3>Step 1: The parser</h3>
<p>In Temple, a parser is also a compiler, because a compiler is just something that takes some input and produces some output. A parser is then something that takes a String and returns an Array.</p>
<p>A dead simple ERB parser could look like this:</p>
<pre class="sunburst">
<span class="Keyword">class</span> <span class="JEntityNameType">ERB</span>
  <span class="Keyword">def</span> <span class="Entity">compile</span>(<span class="Variable">src</span>)
    result <span class="Keyword">=</span> [<span class="Constant"><span class="Constant">:</span>multi</span>]
    <span class="Keyword">while</span> src <span class="Keyword">=~</span> <span class="StringRegexp"><span class="StringRegexp">/</span></span><span class="StringRegexp">&lt;%<span class="StringRegexp"><span class="StringRegexp">(</span>.*?<span class="StringRegexp">)</span></span>%&gt;</span><span class="StringRegexp"><span class="StringRegexp">/</span></span>
      result <span class="Keyword">&lt;&lt;</span> [<span class="Constant"><span class="Constant">:</span>static</span>, <span class="Variable"><span class="Variable">$</span>`</span>]
      <span class="Keyword">case</span> <span class="Variable"><span class="Variable">$</span>1</span>[<span class="Constant">0</span>]
      <span class="Keyword">when</span> <span class="Constant">?#</span>
        <span class="Keyword">next</span>
      <span class="Keyword">when</span> <span class="Constant">?=</span>
        text <span class="Keyword">=</span> <span class="Variable"><span class="Variable">$</span>1</span>[<span class="Constant">1</span>..<span class="Keyword">-</span><span class="Constant">1</span>].<span class="Entity">strip</span>
        head <span class="Keyword">=</span> <span class="Constant"><span class="Constant">:</span>dynamic</span>
      <span class="Keyword">else</span>
        text <span class="Keyword">=</span> <span class="Variable"><span class="Variable">$</span>1</span>
        head <span class="Keyword">=</span> <span class="Constant"><span class="Constant">:</span>block</span>
      <span class="Keyword">end</span>
      result <span class="Keyword">&lt;&lt;</span> [head, text]
      src <span class="Keyword">=</span> <span class="Variable"><span class="Variable">$</span>'</span>
    <span class="Keyword">end</span>
    result <span class="Keyword">&lt;&lt;</span> [<span class="Constant"><span class="Constant">:</span>static</span>, src]
    result
  <span class="Keyword">end</span>
<span class="Keyword">end</span>
</pre>
<p>It&#8217;s important to remember that the <em>parser should be dumb.</em> No optimization, no guesses. It should produce an Array that is as close to the source as possible. That means you&#8217;ll probably have to invent your own abstraction, but <em>that is exactly the point!</em></p>
<p>The Mustache parser compiles to an Array like this:</p>
<pre class="sunburst">
[<span class="Constant"><span class="Constant">:</span>multi</span>,
  [<span class="Constant"><span class="Constant">:</span>static</span>, <span class="String"><span class="String">&quot;</span>Hello <span class="String">&quot;</span></span>],
  [<span class="Constant"><span class="Constant">:</span>mustache</span>, <span class="Constant"><span class="Constant">:</span>evar</span>, <span class="Constant"><span class="Constant">:</span>world</span>],
  [<span class="Constant"><span class="Constant">:</span>mustache</span>, <span class="Constant"><span class="Constant">:</span>section</span>, <span class="Constant"><span class="Constant">:</span>happy?</span>, 
    [<span class="Constant"><span class="Constant">:</span>mustache</span>, <span class="Constant"><span class="Constant">:</span>evar</span>, <span class="Constant"><span class="Constant">:</span>greeting</span>]]]
</pre>
<p>And that&#8217;s fine. The parser should not care about how to compile this further down. That&#8217;s the job to a <em>filter</em>.</p>
<h3>Step N: Filters</h3>
<p>A filter is a compiler which takes an Array and returns an Array. It might turn convert it one step closer to the core-abstraction, it might create a new abstraction, or it might just optimize in the current abstraction. Ultimately, it&#8217;s still just a compiler which takes an Array and returns an Array.</p>
<p>Temple::<em>Filters</em>::Mustache takes an Array in the Mustache-abstraction and compiles it down to core. Then it has to be ran through Temple::Filters::Escapable which handles HTML escaping.</p>
<p>You might wonder <em>why</em> we split Mustache into a parser and a filter, and there are several reasons. Basically it&#8217;s because the parser shouldn&#8217;t need to worry about the code it should generate. Now it&#8217;s possible to benchmark, rewrite, test and improve the parser, and the parser only.</p>
<p>It&#8217;s also because there isn&#8217;t one definite way to go from a Mustache-string to the core-abstraction, but there is only one way to go from a Mustache-string to the Mustache-abstraction. If we want to experiment with another way of ending up at core, we can now write it without duplicating the parsing code.</p>
<p>Anyway, after you&#8217;ve run it through a few filters, you probably want to generate some Ruby code, and that&#8217;s what a generator does.</p>
<h3>Step N+1: The generator</h3>
<p>A generator is a compiler which takes an Array and returns a String. Generators, just like parsers, are dumb too. Here&#8217;s the ArrayBuffer:</p>
<pre class="sunburst">
<span class="Keyword">class</span> <span class="JEntityNameType">ArrayBuffer<span class="EntityInheritedClass"> <span class="EntityInheritedClass">&lt;</span> Generator</span></span>
  <span class="Keyword">def</span> <span class="Entity">buffer</span>(<span class="Variable">str <span class="Keyword">=</span> <span class="String"><span class="String">'</span><span class="String">'</span></span></span>)
    <span class="String"><span class="String">'</span>_buf<span class="String">'</span></span> <span class="Keyword">+</span> str
  <span class="Keyword">end</span>
  
  <span class="Keyword">def</span> <span class="Entity">preamble</span>;  buffer <span class="String"><span class="String">&quot;</span> = []<span class="StringConstant">\n</span><span class="String">&quot;</span></span> <span class="Keyword">end</span>
  <span class="Keyword">def</span> <span class="Entity">postamble</span>; buffer <span class="String"><span class="String">&quot;</span>.join<span class="String">&quot;</span></span>   <span class="Keyword">end</span>
  
  <span class="Keyword">def</span> <span class="Entity">on_static</span>(<span class="Variable">text</span>)
    buffer <span class="String"><span class="String">&quot;</span> &lt;&lt; <span class="StringEmbeddedSource"><span class="StringEmbeddedSource">#{</span>text<span class="StringEmbeddedSource"><span class="StringEmbeddedSource">.</span><span class="Entity">inspect</span></span><span class="StringEmbeddedSource">}</span></span><span class="StringConstant">\n</span><span class="String">&quot;</span></span>
  <span class="Keyword">end</span>
  
  <span class="Keyword">def</span> <span class="Entity">on_dynamic</span>(<span class="Variable">code</span>)
    buffer <span class="String"><span class="String">&quot;</span> &lt;&lt; (<span class="StringEmbeddedSource"><span class="StringEmbeddedSource">#{</span>code<span class="StringEmbeddedSource">}</span></span>)<span class="StringConstant">\n</span><span class="String">&quot;</span></span>
  <span class="Keyword">end</span>
  
  <span class="Keyword">def</span> <span class="Entity">on_block</span>(<span class="Variable">code</span>)
    code <span class="Keyword">+</span> <span class="String"><span class="String">&quot;</span><span class="StringConstant">\n</span><span class="String">&quot;</span></span>
  <span class="Keyword">end</span>
<span class="Keyword">end</span>
</pre>
<p>Temple includes Array, StringBuffer and Interpolation too, even though the last one works kinda funky with blocks and currently only works as expected with Mustache.</p>
<h3>Engines</h3>
<p>The user however would only see an engine, which is a chain of compilers:</p>
<pre class="sunburst">
<span class="Keyword">class</span> <span class="JEntityNameType">ERBEngine<span class="EntityInheritedClass"> <span class="EntityInheritedClass">&lt;</span> Temple::Engine</span></span>
<span class="Comment">  <span class="Comment">#</span> Here using some helpers, but it's important to remember that</span>
<span class="Comment">  <span class="Comment">#</span> it's only sugar around the #use method shown above.</span>
  parser <span class="Constant"><span class="Constant">:</span>ERB</span>
  filter <span class="Constant"><span class="Constant">:</span>DynamicInliner</span>
  generator <span class="Constant"><span class="Constant">:</span>ArrayBuffer</span>
<span class="Keyword">end</span>  
</pre>
<p>The core of Temple::Engine is simple. So simple I&#8217;d like to show it to you (without the helpers):</p>
<pre class="sunburst">
<span class="Keyword">class</span> <span class="JEntityNameType">Engine</span>
  <span class="Keyword">def</span> <span class="Entity">self.filters</span>
    <span class="Variable"><span class="Variable">@</span>filters</span> <span class="Keyword">||=</span> []
  <span class="Keyword">end</span>
  
  <span class="Keyword">def</span> <span class="Entity">self.use</span>(<span class="Variable">filter<span class="Variable">,</span> <span class="Keyword">*</span>args<span class="Variable">,</span> <span class="Keyword">&amp;</span>blk</span>)
    filters <span class="Keyword">&lt;&lt;</span> [filter, args, blk]
  <span class="Keyword">end</span>
  
  <span class="Keyword">def</span> <span class="Entity">initialize</span>
    <span class="Variable"><span class="Variable">@</span>chain</span> <span class="Keyword">=</span> <span class="Variable">self</span>.<span class="Entity">class</span>.<span class="Entity">filters</span>.<span class="Entity">map</span> <span class="Keyword">do </span>|<span class="Variable">filter</span>, <span class="Variable">args</span>, <span class="Variable">blk</span>|
      filter.<span class="Entity">new</span>(<span class="Keyword">*</span>args, <span class="Keyword">&amp;</span>blk)
    <span class="Keyword">end</span>
  <span class="Keyword">end</span>
  
  <span class="Keyword">def</span> <span class="Entity">compile</span>(<span class="Variable">thing</span>)
    <span class="Variable"><span class="Variable">@</span>chain</span>.<span class="Entity">inject</span>(thing) { |<span class="Variable">prev_thing</span>, <span class="Variable">compiler</span>| compiler.<span class="Entity">compile</span>(prev_thing) }
  <span class="Keyword">end</span>
<span class="Keyword">end</span>
</pre>
<p>No magic at all (as long as you understand how inject works). I really like how Temple contains many small pieces which does one thing, and they all easily stacks up and produce some fairy good Ruby code.</p>
<h3>Another abstraction: Haml and HTML</h3>
<p>Okay, so I&#8217;ve shown you two examples: ERB which compiles directly to core, and Mustache which uses one abstraction. Now let&#8217;s have a look at Haml.</p>
<p>Because Haml is so complex, going directly to core can be difficult. Instead it might be smart to introduce an HTML-abstraction:</p>
<pre class="sunburst">
[<span class="Constant"><span class="Constant">:</span>multi</span>,
  [<span class="Constant"><span class="Constant">:</span>html</span>, <span class="Constant"><span class="Constant">:</span>tag</span>,
    <span class="Constant"><span class="Constant">:</span>a</span>,
    [<span class="Constant"><span class="Constant">:</span>basicattr</span>, <span class="Constant"><span class="Constant">:</span>href</span>, <span class="String"><span class="String">&quot;</span>http://judofyr.net/<span class="String">&quot;</span></span>],
    [<span class="Constant"><span class="Constant">:</span>static</span>, <span class="String"><span class="String">&quot;</span>Magnus Holm's blog<span class="String">&quot;</span></span>]]]  
</pre>
<p>There can be several HTML-compilers. One aims for speed (Haml&#8217;s ugly option), one that aims for pretty indentation (Haml&#8217;s pretty option). And I can use the same compiler in Parkaby. If one of these compilers improves and generates better code, it&#8217;s going to improve performance in both Haml and Parkaby. Performance wars are going to be so boring!</p>
<p>Nathan Weizenbaum (the maintainer of Haml) told me targeting Haml could be difficult, but I&#8217;m quite optimistic. It&#8217;s better to try, fail and learn, than not try at all. And to be honest, I&#8217;m willing to bend things around to make Haml a happy citizen in Temple.</p>
<p>I&#8217;d also love to see how Liquid can fit into this mix.</p>
<h3>The goal</h3>
<p>So what do I want with all this? I want to experiment! I want to see if it&#8217;s possible to improve on the lowest level of the abstractions, and I&#8217;d like to see how it affects the upper layers. I&#8217;d like to learn more about different template engines; how they work, how they are parsed, how they perform. I simply want to learn. And I want to share the knowledge.</p>
<p>I want people to experiment and create new concepts in templating. I want to see Domain-Specific Template-Languages. I want people to realize that creating a template engine is just like creating a programming language, just on a smaller scale. Testing frameworks are so boring, why don&#8217;t try to create The Perfect Template Language™?</p>
<p>And, of course, I want <strong>fast</strong> template engines that shares code which each other.</p>
<p>But in the end, it&#8217;s just an experiment. Maybe it&#8217;s successful, probably not, it doesn&#8217;t matter so much as long as I have fun.</p>
<h3>Join the fun!</h3>
<p>I&#8217;m the dumb one here, and if you know <em>anything</em> about template engines I&#8217;d love to hear your thoughts on Temple. In fact, I&#8217;d love to hear <em>everybody&#8217;s</em> thoughts on Temple!</p>
<p>If you&#8217;re interested, please join <a href="http://groups.google.com/group/guardians-of-the-temple">the mailing list</a>. The documentation is pretty non-existing at the moment, if there are any questions at all, please do not hesitate to ask.</p>
<p>The code is available at <a href="http://github.com/judofyr/temple">github.com/judofyr/temple</a>.</p>
<ul class="footnotes"><li id="fn1"><sup>1</sup> I wrote that code though.</li></ul>




]]></content>
  </entry>

  <entry>
    <title>Parkaby</title>
    <id>tag:judofyr.net,2009-07-04:1246711417</id>
    <link href="http://judofyr.net/posts/parkaby.html"/>
    <updated>2009-07-04T12:43:37Z</updated>
    <published>2009-07-04T12:43:37Z</published>
    <content type="html"><![CDATA[<pre class="sunburst">
<span class="Variable">Parkaby</span> {
  html {
    head {
      title <span class="String"><span class="String">&quot;</span>happy title<span class="String">&quot;</span></span>
    }
    body {
      h1 <span class="String"><span class="String">&quot;</span>happy heading<span class="String">&quot;</span></span>
      a <span class="String"><span class="String">&quot;</span>a link<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>href<span class="String">&quot;</span></span> =&gt; <span class="String"><span class="String">&quot;</span>url<span class="String">&quot;</span></span>
    }
  }
}
</pre>
<p><a href="http://github.com/judofyr/parkaby">http://github.com/judofyr/parkaby</a></p>
<pre>
~&gt; ruby bench/run.rb simple 10000

                           user     system      total        real
Erubis                 0.030000   0.000000   0.030000 (  0.022264)
Haml                   0.110000   0.000000   0.110000 (  0.117887)
Parkaby (def_method)   0.130000   0.000000   0.130000 (  0.135996)
Parkaby (render)       0.150000   0.010000   0.160000 (  0.150680)
Parkaby (inline)       0.970000   0.000000   0.970000 (  0.988010)
Tagz                   3.250000   0.040000   3.290000 (  3.400699)
Markaby               12.610000   0.140000  12.750000 ( 13.067794)


~&gt; ruby bench/run.rb nasty 500

                           user     system      total        real
Erubis                 0.190000   0.010000   0.200000 (  0.198487)
Parkaby (def_method)   0.350000   0.000000   0.350000 (  0.363106)
Parkaby (render)       0.360000   0.010000   0.370000 (  0.365007)
Parkaby (inline)       0.570000   0.000000   0.570000 (  0.614286)
Haml                   2.490000   0.030000   2.520000 (  2.620025)
Tagz                   5.100000   0.060000   5.160000 (  5.394778)
Markaby                7.220000   0.090000   7.310000 (  7.630588)
</pre>
<p>Feel free to ask questions in the comments.</p>]]></content>
  </entry>

  <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>
</feed>
