<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"> 
   <channel> 
      <title>Things Aaron Made</title> 
      <link>http://thingsaaronmade.com/</link> 
      <description>The blog and website of Toronto software developer, Aaron Gough.</description> 
      <language>en-us</language> 
      <pubDate>Wed, 22 Jan 2014 06:50:40 PST</pubDate> 
      <managingEditor>aaron@aarongough.com (Aaron Gough)</managingEditor> 
      <webMaster>aaron@aarongough.com (Aaron Gough)</webMaster>
      
      
      <item> 
         <title>RSpec and Internal DSLs in Ruby</title> 
         <link>http://thingsaaronmade.com/blog/rspec_and_internal_dsls.html</link> 
         <description>
         &lt;blockquote&gt;
           &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; because these articles usually contain inline code examples 
           it is highly likely that they will not display properly in your feed reader.&lt;/p&gt;
           
           To see this article as it was originally written please visit: &lt;a href="http://thingsaaronmade.com/blog/rspec_and_internal_dsls.html"&gt;http://thingsaaronmade.com/blog/rspec_and_internal_dsls.html&lt;/a&gt;
         &lt;/blockquote&gt;
         
         &lt;p&gt;I had a developer email me the other day asking for advice on how to tackle a project that required parsing a natural language DSL (Domain Specific Language). He asked if maybe he should look at the parser for RSpec to get some ideas from there.&lt;/p&gt; &lt;p&gt;What some may not realize is that RSpec is a shining example of an ‘internal DSL’ ie: a DSL that is implemented using only the features of the parent language. Writing a DSL this way does not require that you create a separate parser and interpreter. This obviously saves a huge amount of development time in situations that allow using this style of DSL.&lt;/p&gt; &lt;p&gt;The down-side is that you can’t really expose a DSL written this way to un-trusted users. And by un-trusted users I really mean anyone that is not on the development team. The reason is that because an internal DSL makes use of the power of the parent language, it also generally allows users to execute arbitrary code, which is obviously a no-no.&lt;/p&gt; &lt;p&gt;Here’s a quick example of the style of code that RSpec uses to provide it’s natural syntax:&lt;/p&gt; &lt;div class=&#39;highlight&#39;&gt;&lt;pre&gt;&lt;code class=&#39;ruby&#39;&gt;&lt;span class=&#39;lineno&#39;&gt; 1&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;module&lt;/span&gt; &lt;span class=&#39;nn&#39;&gt;Kernel&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt; 2&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;def&lt;/span&gt; &lt;span class=&#39;nf&#39;&gt;should&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt; 3&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;return&lt;/span&gt; &lt;span class=&#39;no&#39;&gt;Handlers&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;::&lt;/span&gt;&lt;span class=&#39;no&#39;&gt;PositiveOperatorHandler&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;new&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nb&#39;&gt;self&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt; 4&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;end&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt; 5&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt; 6&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;def&lt;/span&gt; &lt;span class=&#39;nf&#39;&gt;should_not&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt; 7&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;return&lt;/span&gt; &lt;span class=&#39;no&#39;&gt;Handlers&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;::&lt;/span&gt;&lt;span class=&#39;no&#39;&gt;NegativeOperatorHandler&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;new&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nb&#39;&gt;self&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt; 8&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;end&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt; 9&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;end&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;10&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;11&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;module&lt;/span&gt; &lt;span class=&#39;nn&#39;&gt;Handlers&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;12&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;class&lt;/span&gt; &lt;span class=&#39;nc&#39;&gt;PositiveOperatorHandler&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;13&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;def&lt;/span&gt; &lt;span class=&#39;nf&#39;&gt;initialize&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;actual&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;14&lt;/span&gt; &lt;span class=&#39;vi&#39;&gt;@actual&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;actual&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;15&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;end&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;16&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;17&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;def&lt;/span&gt; &lt;span class=&#39;nf&#39;&gt;==&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;other&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;18&lt;/span&gt; &lt;span class=&#39;nb&#39;&gt;puts&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;Expected &amp;#39;&lt;/span&gt;&lt;span class=&#39;si&#39;&gt;#{&lt;/span&gt;&lt;span class=&#39;vi&#39;&gt;@actual&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;inspect&lt;/span&gt;&lt;span class=&#39;si&#39;&gt;}&lt;/span&gt;&lt;span class=&#39;s2&#39;&gt;&amp;#39; to equal &amp;#39;&lt;/span&gt;&lt;span class=&#39;si&#39;&gt;#{&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;other&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;inspect&lt;/span&gt;&lt;span class=&#39;si&#39;&gt;}&lt;/span&gt;&lt;span class=&#39;s2&#39;&gt;&amp;#39;&amp;quot;&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;unless&lt;/span&gt; &lt;span class=&#39;vi&#39;&gt;@actual&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;==&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;other&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;19&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;end&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;20&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;end&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;21&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;22&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;class&lt;/span&gt; &lt;span class=&#39;nc&#39;&gt;NegativeOperatorHandler&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;23&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;def&lt;/span&gt; &lt;span class=&#39;nf&#39;&gt;initialize&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;actual&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;24&lt;/span&gt; &lt;span class=&#39;vi&#39;&gt;@actual&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;actual&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;25&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;end&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;26&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;27&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;def&lt;/span&gt; &lt;span class=&#39;nf&#39;&gt;==&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;other&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;28&lt;/span&gt; &lt;span class=&#39;nb&#39;&gt;puts&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;Expected &amp;#39;&lt;/span&gt;&lt;span class=&#39;si&#39;&gt;#{&lt;/span&gt;&lt;span class=&#39;vi&#39;&gt;@actual&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;inspect&lt;/span&gt;&lt;span class=&#39;si&#39;&gt;}&lt;/span&gt;&lt;span class=&#39;s2&#39;&gt;&amp;#39; to not equal &amp;#39;&lt;/span&gt;&lt;span class=&#39;si&#39;&gt;#{&lt;/span&gt;&lt;span...
         </description> 
         <pubDate>Wed, 12 Sep 2012 00:00:00 PDT</pubDate> 
         <guid>http://thingsaaronmade.com/blog/rspec_and_internal_dsls.html</guid> 
      </item> 
      
      <item> 
         <title>Introducing Flea - A tiny Lisp written in Ruby</title> 
         <link>http://thingsaaronmade.com/blog/introducing-flea.html</link> 
         <description>
         &lt;blockquote&gt;
           &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; because these articles usually contain inline code examples 
           it is highly likely that they will not display properly in your feed reader.&lt;/p&gt;
           
           To see this article as it was originally written please visit: &lt;a href="http://thingsaaronmade.com/blog/introducing-flea.html"&gt;http://thingsaaronmade.com/blog/introducing-flea.html&lt;/a&gt;
         &lt;/blockquote&gt;
         
         &lt;p&gt;Flea is a tiny Lisp interpreter implemented in Ruby. Flea is designed to be an example of how simple it can be to bootstrap the core of a small flexible language. Flea essentially defines an informal subset of Scheme, just enough to be fun and interesting.&lt;/p&gt; &lt;h2 id=&quot;code_example&quot;&gt;Code example:&lt;/h2&gt; &lt;p&gt;Here is a version of the classic ‘guess-the-number’ game implemented using Flea:&lt;/p&gt; &lt;div class=&#39;highlight&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scheme&#39;&gt;&lt;span class=&#39;lineno&#39;&gt; 1&lt;/span&gt; &lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;k&#39;&gt;define &lt;/span&gt;&lt;span class=&#39;nv&#39;&gt;number&lt;/span&gt; &lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nb&#39;&gt;+ &lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nf&#39;&gt;rand&lt;/span&gt; &lt;span class=&#39;mi&#39;&gt;9&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;mi&#39;&gt;1&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;))&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt; 2&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt; 3&lt;/span&gt; &lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nb&#39;&gt;display &lt;/span&gt;&lt;span class=&#39;s&#39;&gt;&amp;quot;\n\nI&amp;#39;m thinking of a number between 1 and 10,\n&amp;quot;&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt; 4&lt;/span&gt; &lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nb&#39;&gt;display &lt;/span&gt;&lt;span class=&#39;s&#39;&gt;&amp;quot;try to guess it!\n\n&amp;quot;&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt; 5&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt; 6&lt;/span&gt; &lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;k&#39;&gt;define &lt;/span&gt;&lt;span class=&#39;nv&#39;&gt;user-guess&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt; 7&lt;/span&gt; &lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;k&#39;&gt;lambda &lt;/span&gt;&lt;span class=&#39;p&#39;&gt;()&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt; 8&lt;/span&gt; &lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nb&#39;&gt;display &lt;/span&gt;&lt;span class=&#39;s&#39;&gt;&amp;quot;Take a guess - &amp;quot;&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt; 9&lt;/span&gt; &lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;k&#39;&gt;define &lt;/span&gt;&lt;span class=&#39;nv&#39;&gt;guess&lt;/span&gt; &lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nf&#39;&gt;string-to-num&lt;/span&gt; &lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nf&#39;&gt;gets&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)))&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;10&lt;/span&gt; &lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;k&#39;&gt;if &lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nb&#39;&gt;equal? &lt;/span&gt;&lt;span class=&#39;nv&#39;&gt;guess&lt;/span&gt; &lt;span class=&#39;nv&#39;&gt;number&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;11&lt;/span&gt; &lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nb&#39;&gt;display &lt;/span&gt;&lt;span class=&#39;s&#39;&gt;&amp;quot;Good guess!\n&amp;quot;&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;12&lt;/span&gt; &lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nf&#39;&gt;begin&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;13&lt;/span&gt; &lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;k&#39;&gt;if &lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nf&#39;&gt;greater-than?&lt;/span&gt; &lt;span class=&#39;nv&#39;&gt;guess&lt;/span&gt; &lt;span class=&#39;nv&#39;&gt;number&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;14&lt;/span&gt; &lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nb&#39;&gt;display &lt;/span&gt;&lt;span class=&#39;s&#39;&gt;&amp;quot;Lower!\n&amp;quot;&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;15&lt;/span&gt; &lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nb&#39;&gt;display &lt;/span&gt;&lt;span class=&#39;s&#39;&gt;&amp;quot;Higher!\n&amp;quot;&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;))&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;16&lt;/span&gt; &lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nf&#39;&gt;user-guess&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)))))&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;17&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;18&lt;/span&gt; &lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nf&#39;&gt;user-guess&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;h2 id=&quot;installation&quot;&gt;Installation:&lt;/h2&gt; &lt;p&gt;For ease of use the Flea is packaged as a RubyGem. Providing you already have Ruby and RubyGems installing Flea is as easy as entering the following command in a terminal:&lt;/p&gt; &lt;div class=&#39;highlight&#39;&gt;&lt;pre&gt;&lt;code class=&#39;text&#39;&gt;&lt;span class=&#39;lineno&#39;&gt;1&lt;/span&gt; gem install flea &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Mac OS X and most Unix/Linux distributions come with an installation of Ruby and RubyGems. If you do not have Ruby and RubyGems installed please &lt;a href=&quot;http://www.ruby-lang.org/&quot;&gt;check the Ruby website for instructions&lt;/a&gt;.&lt;/p&gt; &lt;h2 id=&quot;usage&quot;&gt;Usage:&lt;/h2&gt; &lt;p&gt;After Flea is installed you can run a program by typing the following on the command line:&lt;/p&gt; &lt;div class=&#39;highlight&#39;&gt;&lt;pre&gt;&lt;code class=&#39;text&#39;&gt;&lt;span class=&#39;lineno&#39;&gt;1&lt;/span&gt; flea /path/to/program &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You can also launch Flea’s interactive shell by simply calling &lt;code&gt;flea&lt;/code&gt; with no arguments.&lt;/p&gt; &lt;p&gt;The entire API for the language is documented &lt;a href=&quot;http://github.com/aarongough/flea&quot;&gt;on the project page at GitHub&lt;/a&gt;.&lt;/p&gt; &lt;h2 id=&quot;experimenting_and_contributing&quot;&gt;Experimenting and contributing:&lt;/h2&gt; &lt;p&gt;Flea was designed as a learning tool, so with that in mind I strongly encourage you to pull it apart, play with it, and glue it back together in different ways. For an explanation of...
         </description> 
         <pubDate>Mon, 14 Mar 2011 00:00:00 PDT</pubDate> 
         <guid>http://thingsaaronmade.com/blog/introducing-flea.html</guid> 
      </item> 
      
      <item> 
         <title>Cheating your way to Lisp with Ruby</title> 
         <link>http://thingsaaronmade.com/blog/cheating-yor-way-to-lisp-with-ruby.html</link> 
         <description>
         &lt;blockquote&gt;
           &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; because these articles usually contain inline code examples 
           it is highly likely that they will not display properly in your feed reader.&lt;/p&gt;
           
           To see this article as it was originally written please visit: &lt;a href="http://thingsaaronmade.com/blog/cheating-yor-way-to-lisp-with-ruby.html"&gt;http://thingsaaronmade.com/blog/cheating-yor-way-to-lisp-with-ruby.html&lt;/a&gt;
         &lt;/blockquote&gt;
         
         &lt;p&gt;The main purpose of this post is to illustrate how simple it can be to bootstrap a small programming language using a high level language. The core of the language we’ll create is well under 100 lines, and is so extensible that it would be a relatively simple task to turn it into a full-blown Scheme implementation.&lt;/p&gt; &lt;blockquote&gt; The code examples in this post are stripped down versions of code found in my miniature Lisp implementation, &lt;a href=&#39;http://github.com/aarongough/flea&#39;&gt;Flea&lt;/a&gt;. &lt;/blockquote&gt; &lt;p&gt;Let’s dive right in and have a look at the core code for our mini-lisp! First let’s have a look at &lt;code&gt;MiniLisp::Environment&lt;/code&gt;. This class is responsible for defining and finding variables, each environment can optionally have a parent which gets included in the variable lookup chain, this allows us to implement lexical scoping.&lt;/p&gt; &lt;div class=&#39;highlight&#39;&gt;&lt;pre&gt;&lt;code class=&#39;ruby&#39;&gt;&lt;span class=&#39;lineno&#39;&gt; 1&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;module&lt;/span&gt; &lt;span class=&#39;nn&#39;&gt;MiniLisp&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt; 2&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;class&lt;/span&gt; &lt;span class=&#39;nc&#39;&gt;Environment&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt; 3&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt; 4&lt;/span&gt; &lt;span class=&#39;kp&#39;&gt;attr_accessor&lt;/span&gt; &lt;span class=&#39;ss&#39;&gt;:parent&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt; 5&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt; 6&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;def&lt;/span&gt; &lt;span class=&#39;nf&#39;&gt;initialize&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;parent&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;kp&#39;&gt;nil&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt; 7&lt;/span&gt; &lt;span class=&#39;vi&#39;&gt;@parent&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;parent&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt; 8&lt;/span&gt; &lt;span class=&#39;vi&#39;&gt;@table&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;p&#39;&gt;{}&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt; 9&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;end&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;10&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;11&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;def&lt;/span&gt; &lt;span class=&#39;nf&#39;&gt;find&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nb&#39;&gt;name&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;12&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;return&lt;/span&gt; &lt;span class=&#39;vi&#39;&gt;@table&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;[&lt;/span&gt;&lt;span class=&#39;nb&#39;&gt;name&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;]&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;if&lt;/span&gt; &lt;span class=&#39;vi&#39;&gt;@table&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;has_key?&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nb&#39;&gt;name&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;13&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;return&lt;/span&gt; &lt;span class=&#39;kp&#39;&gt;nil&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;if&lt;/span&gt; &lt;span class=&#39;vi&#39;&gt;@parent&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;nil?&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;14&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;return&lt;/span&gt; &lt;span class=&#39;vi&#39;&gt;@parent&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;find&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nb&#39;&gt;name&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;15&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;end&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;16&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;17&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;def&lt;/span&gt; &lt;span class=&#39;nf&#39;&gt;define&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nb&#39;&gt;name&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;value&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;18&lt;/span&gt; &lt;span class=&#39;vi&#39;&gt;@table&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;[&lt;/span&gt;&lt;span class=&#39;nb&#39;&gt;name&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;]&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;value&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;19&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;end&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;20&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;21&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;end&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;22&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;end&lt;/span&gt; &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Next is &lt;code&gt;MiniLisp::Interpreter&lt;/code&gt;, this class has two main methods: &lt;code&gt;run&lt;/code&gt; and &lt;code&gt;evaluate&lt;/code&gt;. The &lt;code&gt;run&lt;/code&gt; method simply steps through an array of expressions and passes them individually to the &lt;code&gt;evaluate&lt;/code&gt; method. The &lt;code&gt;evaluate&lt;/code&gt; method then does several checks:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;If it has been passed a &lt;code&gt;Symbol&lt;/code&gt; then it calls &lt;code&gt;find&lt;/code&gt; on the current environment using the symbol as the key and returns the value it finds.&lt;/li&gt; &lt;li&gt;If it is anything other than an &lt;code&gt;Array&lt;/code&gt; at this point then we are looking at a literal (be it a &lt;code&gt;String&lt;/code&gt;, &lt;code&gt;Integer&lt;/code&gt;, or &lt;code&gt;Float&lt;/code&gt;), and we need to return the literal untouched.&lt;/li&gt; &lt;li&gt;If it is an array then we are...
         </description> 
         <pubDate>Sun, 13 Mar 2011 00:00:00 PST</pubDate> 
         <guid>http://thingsaaronmade.com/blog/cheating-yor-way-to-lisp-with-ruby.html</guid> 
      </item> 
      
      <item> 
         <title>A quick intro to writing a parser with Treetop</title> 
         <link>http://thingsaaronmade.com/blog/a-quick-intro-to-writing-a-parser-using-treetop.html</link> 
         <description>
         &lt;blockquote&gt;
           &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; because these articles usually contain inline code examples 
           it is highly likely that they will not display properly in your feed reader.&lt;/p&gt;
           
           To see this article as it was originally written please visit: &lt;a href="http://thingsaaronmade.com/blog/a-quick-intro-to-writing-a-parser-using-treetop.html"&gt;http://thingsaaronmade.com/blog/a-quick-intro-to-writing-a-parser-using-treetop.html&lt;/a&gt;
         &lt;/blockquote&gt;
         
         &lt;p&gt;Treetop is a Ruby library that allows you to create &lt;a href=&quot;http://en.wikipedia.org/wiki/Parsing&quot;&gt;parsers&lt;/a&gt; easily by describing them using a &lt;a href=&quot;http://en.wikipedia.org/wiki/Parsing_expression_grammar&quot;&gt;Parsing Expression Grammar (PEG)&lt;/a&gt;. Writing a parser using Treetop is a fairly pain-free process, but getting started can be non-trivial, especially if you’re not familiar with PEGs, so this is going to be a fairly short ‘getting started’ guide. To keep things simple our example parser is going to process a subset of S-Expression syntax like so:&lt;/p&gt; &lt;div class=&#39;highlight&#39;&gt;&lt;pre&gt;&lt;code class=&#39;ruby&#39;&gt;&lt;span class=&#39;lineno&#39;&gt;1&lt;/span&gt; &lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;define&lt;/span&gt; &lt;span class=&#39;nb&#39;&gt;test&lt;/span&gt; &lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nb&#39;&gt;lambda&lt;/span&gt; &lt;span class=&#39;p&#39;&gt;()&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;2&lt;/span&gt; &lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;k&#39;&gt;begin&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;3&lt;/span&gt; &lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nb&#39;&gt;display&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;something&amp;quot;&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;4&lt;/span&gt; &lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nb&#39;&gt;display&lt;/span&gt; &lt;span class=&#39;mi&#39;&gt;1&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;5&lt;/span&gt; &lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nb&#39;&gt;display&lt;/span&gt; &lt;span class=&#39;mi&#39;&gt;3&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;mi&#39;&gt;08&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;))))&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;6&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;7&lt;/span&gt; &lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nb&#39;&gt;test&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;It will be a fairly simplistic example, but it should be enough to get you started!&lt;/p&gt; &lt;h2 id=&quot;installing_treetop&quot;&gt;Installing Treetop&lt;/h2&gt; &lt;p&gt;Provided that you already have Ruby and RubyGems installed, installing Treetop is a very simple process. Simply enter this at your command line:&lt;/p&gt; &lt;div class=&#39;highlight&#39;&gt;&lt;pre&gt;&lt;code class=&#39;text&#39;&gt;&lt;span class=&#39;lineno&#39;&gt;1&lt;/span&gt; gem install treetop &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If you do not have Ruby and RubyGems installed then you should &lt;a href=&quot;http://www.ruby-lang.org/en/&quot;&gt;have a look at the Ruby website for installation instructions&lt;/a&gt;.&lt;/p&gt; &lt;h2 id=&quot;getting_started&quot;&gt;Getting Started&lt;/h2&gt; &lt;p&gt;There are going to be three main parts to our parser:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;The Ruby class &lt;code&gt;Parser&lt;/code&gt; which will contain the API for interacting with the parser&lt;/li&gt; &lt;li&gt;The Treetop grammar file in which we will create all the rules that define how our parser will behave&lt;/li&gt; &lt;li&gt;A series of simple classes that subclass &lt;code&gt;Treetop::Runtime::SyntaxNode&lt;/code&gt;, these will allow us to easily describe our parsed structure by having each type of entity map directly to a custom &lt;a href=&quot;http://en.wikipedia.org/wiki/Abstract_syntax_tree&quot;&gt;syntax node&lt;/a&gt; class&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;The first thing we need to do is create skeletons for the three files involved:&lt;/p&gt; &lt;div class=&#39;highlight&#39;&gt;&lt;pre&gt;&lt;code class=&#39;ruby&#39;&gt;&lt;span class=&#39;lineno&#39;&gt; 1&lt;/span&gt; &lt;span class=&#39;c1&#39;&gt;# In file parser.rb&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt; 2&lt;/span&gt; &lt;span class=&#39;nb&#39;&gt;require&lt;/span&gt; &lt;span class=&#39;s1&#39;&gt;&amp;#39;treetop&amp;#39;&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt; 3&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt; 4&lt;/span&gt; &lt;span class=&#39;c1&#39;&gt;# Find out what our base path is&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt; 5&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;base_path&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;no&#39;&gt;File&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;expand_path&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;no&#39;&gt;File&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;dirname&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;bp&#39;&gt;__FILE__&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;))&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt; 6&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt; 7&lt;/span&gt; &lt;span class=&#39;c1&#39;&gt;# Load our custom syntax node classes so the parser can use them&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt; 8&lt;/span&gt; &lt;span class=&#39;nb&#39;&gt;require&lt;/span&gt; &lt;span class=&#39;no&#39;&gt;File&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;join&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;base_path&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;s1&#39;&gt;&amp;#39;node_extensions.rb&amp;#39;&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt; 9&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;10&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;class&lt;/span&gt; &lt;span class=&#39;nc&#39;&gt;Parser&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;11&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;12&lt;/span&gt; &lt;span class=&#39;c1&#39;&gt;#...
         </description> 
         <pubDate>Mon, 13 Sep 2010 00:00:00 PDT</pubDate> 
         <guid>http://thingsaaronmade.com/blog/a-quick-intro-to-writing-a-parser-using-treetop.html</guid> 
      </item> 
      
      <item> 
         <title>Writing an S-Expression parser in Ruby</title> 
         <link>http://thingsaaronmade.com/blog/writing-an-s-expression-parser-in-ruby.html</link> 
         <description>
         &lt;blockquote&gt;
           &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; because these articles usually contain inline code examples 
           it is highly likely that they will not display properly in your feed reader.&lt;/p&gt;
           
           To see this article as it was originally written please visit: &lt;a href="http://thingsaaronmade.com/blog/writing-an-s-expression-parser-in-ruby.html"&gt;http://thingsaaronmade.com/blog/writing-an-s-expression-parser-in-ruby.html&lt;/a&gt;
         &lt;/blockquote&gt;
         
         &lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/S-expression&quot;&gt;S-Expressions&lt;/a&gt; are a very versatile syntax for defining data structures and program code that are used by most &lt;a href=&#39;http://en.wikipedia.org/wiki/Lisp_(programming_language)&#39;&gt;Lisp&lt;/a&gt;-derived programming languages.&lt;/p&gt; &lt;p&gt;When experimenting with new languages S-Expressions are fantastic because they are extremely flexible but only require minimal effort to &lt;a href=&quot;http://en.wikipedia.org/wiki/Parsing&quot;&gt;parse&lt;/a&gt;. In this article I am going to cover the basic principles of creating a robust S-Expression parser in Ruby.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: if you just want a complete and working S-Expression parser library for Ruby please check out &lt;a href=&#39;http://github.com/aarongough/sexpistol&#39;&gt;Sexpistol&lt;/a&gt;&lt;/p&gt; &lt;blockquote&gt; &lt;strong&gt;Note:&lt;/strong&gt; Since writing this article I have found a more performant and concise parsing method using StringScanner. I will be writing an updated post shortly. If you would like to to have a look at the completed code using the new method check it out at &lt;a href=&#39;http://github.com/aarongough/sexpistol/blob/master/lib/sexpistol/sexpistol_parser.rb&#39;&gt;GitHub&lt;/a&gt;. The code in this article is still relevant as an introduction. &lt;/blockquote&gt;&lt;p /&gt; &lt;h2 id=&quot;our_parser&quot;&gt;Our parser&lt;/h2&gt; &lt;p&gt;One of the first things we should have a look at is a simple example of some program code written as an S-Expression:&lt;/p&gt; &lt;div class=&#39;highlight&#39;&gt;&lt;pre&gt;&lt;code class=&#39;text&#39;&gt;&lt;span class=&#39;lineno&#39;&gt;1&lt;/span&gt; (define test (lambda () ( &lt;span class=&#39;lineno&#39;&gt;2&lt;/span&gt; begin &lt;span class=&#39;lineno&#39;&gt;3&lt;/span&gt; (print &amp;quot;test&amp;quot;) &lt;span class=&#39;lineno&#39;&gt;4&lt;/span&gt; (print 1) &lt;span class=&#39;lineno&#39;&gt;5&lt;/span&gt; ))) &lt;span class=&#39;lineno&#39;&gt;6&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;7&lt;/span&gt; (test) &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The first step in most parsers is to break the input text up into &lt;a href=&quot;http://en.wikipedia.org/wiki/Lexical_analysis#Token&quot;&gt;‘tokens’&lt;/a&gt;, and in order to do that we have to know what the possible tokens are in our target grammar. In our case we have it easy as there are only 5 distinct tokens that we care about initially:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Opening parentheses &lt;code&gt;(&lt;/code&gt;&lt;/li&gt; &lt;li&gt;Closing parentheses &lt;code&gt;)&lt;/code&gt;&lt;/li&gt; &lt;li&gt;Symbols &lt;code&gt;define begin print etc...&lt;/code&gt;&lt;/li&gt; &lt;li&gt;String literals &lt;code&gt;&amp;quot;test&amp;quot; &amp;quot;foo&amp;quot; etc...&lt;/code&gt;&lt;/li&gt; &lt;li&gt;Integer literals &lt;code&gt;2 5 99 etc...&lt;/code&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;The first thing we should notice is that one of these tokens is a ‘special case’ in that it can contain other sequences of characters that we would normally perceive as tokens in of themselves. This complicated token is the String literal.&lt;/p&gt; &lt;p&gt;In order to simplify the problem for ourselves the first thing we are going to do is find all of the string literals, copy them into an array, and then replace them with a special placeholder string:&lt;/p&gt; &lt;div class=&#39;highlight&#39;&gt;&lt;pre&gt;&lt;code class=&#39;ruby&#39;&gt;&lt;span class=&#39;lineno&#39;&gt; 1&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;def&lt;/span&gt; &lt;span class=&#39;nf&#39;&gt;extract_string_literals&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;string&lt;/span&gt; &lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt; 2&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;string_literal_pattern&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;sr&#39;&gt;/&amp;quot;([^&amp;quot;\\]|\\.)*&amp;quot;/&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt; 3&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;string_replacement_token&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;___+++STRING_LITERAL+++___&amp;quot;&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt; 4&lt;/span&gt; &lt;span class=&#39;c1&#39;&gt;# Find and extract all the string literals&lt;/span&gt;...
         </description> 
         <pubDate>Sun, 05 Sep 2010 00:00:00 PDT</pubDate> 
         <guid>http://thingsaaronmade.com/blog/writing-an-s-expression-parser-in-ruby.html</guid> 
      </item> 
      
      <item> 
         <title>Introducing Koi - A language that teaches the basics of language implementation</title> 
         <link>http://thingsaaronmade.com/blog/introducing-koi.html</link> 
         <description>
         &lt;blockquote&gt;
           &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; because these articles usually contain inline code examples 
           it is highly likely that they will not display properly in your feed reader.&lt;/p&gt;
           
           To see this article as it was originally written please visit: &lt;a href="http://thingsaaronmade.com/blog/introducing-koi.html"&gt;http://thingsaaronmade.com/blog/introducing-koi.html&lt;/a&gt;
         &lt;/blockquote&gt;
         
         &lt;p&gt;Several months ago I started on a quest to learn more about how programming languages work internally. Today I am releasing my first programming language: Koi.&lt;/p&gt; &lt;p&gt;Koi is designed, above all else, to be a language whose implementation demonstrates the basics of how to build a language in a straight-forward way.&lt;/p&gt; &lt;p&gt;Most programming language implementations are written in low-level languages like C in order to maximize performance, and this generally makes them very opaque and difficult to follow.&lt;/p&gt; &lt;p&gt;In order to avoid this problem Koi is written from the ground up in Ruby to make sure that the implementation language never gets in the way of the &lt;em&gt;intent&lt;/em&gt; of the code. Koi will likely never be suitable for use as a production language, but that was never one of its goals.&lt;/p&gt; &lt;p&gt;Koi is an imperative, dynamic, weakly-typed language with first-class functions. Koi’s syntax and features were influenced by Lua, JavaScript and Ruby. Additionally Koi makes a special point of working very hard to be unambigous in its syntax so that it is easy to write parsers for.&lt;/p&gt; &lt;h2 id=&quot;code_example&quot;&gt;Code example:&lt;/h2&gt; &lt;p&gt;An old-school ‘Blast Off!’ example in Koi:&lt;/p&gt; &lt;div class=&#39;highlight&#39;&gt;&lt;pre&gt;&lt;code class=&#39;ruby&#39;&gt;&lt;span class=&#39;lineno&#39;&gt; 1&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;countdown&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;function&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;count&lt;/span&gt; &lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt; 2&lt;/span&gt; &lt;span class=&#39;nb&#39;&gt;print&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;to_string&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;count&lt;/span&gt; &lt;span class=&#39;p&#39;&gt;))&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt; 3&lt;/span&gt; &lt;span class=&#39;nb&#39;&gt;print&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;, &amp;quot;&lt;/span&gt; &lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt; 4&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;if&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;count&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;==&lt;/span&gt; &lt;span class=&#39;mi&#39;&gt;0&lt;/span&gt; &lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt; 5&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;return&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;()&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt; 6&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;end&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt; 7&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;count&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;count&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;-&lt;/span&gt; &lt;span class=&#39;mi&#39;&gt;1&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt; 8&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;call&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;countdown&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;count&lt;/span&gt; &lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt; 9&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;end&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;10&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;11&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;call&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;countdown&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;mi&#39;&gt;10&lt;/span&gt; &lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;12&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;13&lt;/span&gt; &lt;span class=&#39;nb&#39;&gt;print&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;Blast Off!&amp;quot;&lt;/span&gt; &lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;14&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;15&lt;/span&gt; &lt;span class=&#39;c1&#39;&gt;#=&amp;gt; 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, Blast Off!&lt;/span&gt; &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;More code example are available at the &lt;a href=&quot;http://github.com/aarongough/koi/tree/master/examples/&quot;&gt;Koi GitHub repository&lt;/a&gt;&lt;/p&gt; &lt;h2 id=&quot;installation&quot;&gt;Installation:&lt;/h2&gt; &lt;p&gt;For ease of use Koi is packaged as a RubyGem and will automatically install its dependencies. OSX and most flavors of Linux come with Ruby and RubyGems pre-installed so you should just be able to type:&lt;/p&gt; &lt;div class=&#39;highlight&#39;&gt;&lt;pre&gt;&lt;code class=&#39;text&#39;&gt;&lt;span class=&#39;lineno&#39;&gt;1&lt;/span&gt; gem install koi-lang &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If you need to install Ruby please &lt;a href=&quot;http://www.ruby-lang.org/&quot;&gt;check the Ruby website for instructions&lt;/a&gt;&lt;/p&gt;...
         </description> 
         <pubDate>Sun, 29 Aug 2010 00:00:00 PDT</pubDate> 
         <guid>http://thingsaaronmade.com/blog/introducing-koi.html</guid> 
      </item> 
      
      <item> 
         <title>Hardware Upgrades for Developers</title> 
         <link>http://thingsaaronmade.com/blog/hardware-upgrades-for-developers.html</link> 
         <description>
         &lt;blockquote&gt;
           &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; because these articles usually contain inline code examples 
           it is highly likely that they will not display properly in your feed reader.&lt;/p&gt;
           
           To see this article as it was originally written please visit: &lt;a href="http://thingsaaronmade.com/blog/hardware-upgrades-for-developers.html"&gt;http://thingsaaronmade.com/blog/hardware-upgrades-for-developers.html&lt;/a&gt;
         &lt;/blockquote&gt;
         
         &lt;p&gt;A little while ago I noticed my MacBook was becoming a little laggy. Opening applications seemed to have gotten slower, and switching between applications was often the cause of several seconds of waiting. Furthermore whenever my backup program starting doing it’s thing the machine would start swapping and everything would become extremely sluggish. Given that this was all breaking up my workflow I decided that I needed to upgrade.&lt;/p&gt; &lt;p&gt;Initially I looked at buying a new 13” MacBook Pro, but for the extra expense the only place where it had a clear advantage over my current 13” Aluminium Unibody MacBook was in the battery life, which wouldn’t solve my performance issues.&lt;/p&gt; &lt;p&gt;That led me to think about solid-state hard drives. Many people have become strong proponents of them over the last few years as they have matured as a product. I also wondered how an SSD would fare against a simple RAM upgrade in terms of seeing better performance in day-to-day use, so I decided to document the results of each step of the upgrade so other people could use the information to make choices for themselves.&lt;/p&gt; &lt;h2 id=&quot;the_original_hardware&quot;&gt;The original hardware:&lt;/h2&gt; &lt;p&gt;Late 2008 13” Aluminium Unibody Macbook (Model: MacBook5,1)&lt;/p&gt; &lt;ul&gt; &lt;li&gt;2Ghz Core 2 Duo&lt;/li&gt; &lt;li&gt;2Gb DDR3 PC8500 RAM&lt;/li&gt; &lt;li&gt;1066Mhz front-side bus&lt;/li&gt; &lt;li&gt;120Gb 5400RPM HDD&lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&quot;the_upgrade_options&quot;&gt;The upgrade options:&lt;/h2&gt; &lt;p&gt;&lt;strong&gt;6GB of DDR3 PC8500 RAM in 2 DIMMS: 1x 2GB, 1x 4GB&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Note: while I did all the tests with the full 6GB of RAM, I ended up taking out the 2GB DIMM and just going for 4GB total. This is because 6GB of RAM in this machine is unsupported and was causing issues when the computer went to sleep.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;50GB OCZ Vertex 2 SSD&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;This is an &lt;em&gt;insanely&lt;/em&gt; fast drive even by SSD standards, but it was primarily chosen for it’s controller. The Sandforce controller in this drive implements on-drive garbage collection that helps minimize performance degradation due to OS X’s lack of TRIM support.&lt;/p&gt; &lt;h2 id=&quot;testing_methodology&quot;&gt;Testing methodology:&lt;/h2&gt; &lt;p&gt;I can’t pretend to be an expert on statistics, so I basically approached the problem of benchmarking the upgrades the same way I would when profiling a software system. I wrote a series of automated benchmarks (the complete code for which can be found here: &lt;a href=&quot;http://gist.github.com/603332&quot;&gt;http://gist.github.com/603332&lt;/a&gt;) and then I did a series of runs of the tests. After each run the machine was restarted. The test suite was run 4 times...
         </description> 
         <pubDate>Sun, 29 Aug 2010 00:00:00 PDT</pubDate> 
         <guid>http://thingsaaronmade.com/blog/hardware-upgrades-for-developers.html</guid> 
      </item> 
      
      <item> 
         <title>A simple intro to writing a lexer with Ragel.</title> 
         <link>http://thingsaaronmade.com/blog/a-simple-intro-to-writing-a-lexer-with-ragel.html</link> 
         <description>
         &lt;blockquote&gt;
           &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; because these articles usually contain inline code examples 
           it is highly likely that they will not display properly in your feed reader.&lt;/p&gt;
           
           To see this article as it was originally written please visit: &lt;a href="http://thingsaaronmade.com/blog/a-simple-intro-to-writing-a-lexer-with-ragel.html"&gt;http://thingsaaronmade.com/blog/a-simple-intro-to-writing-a-lexer-with-ragel.html&lt;/a&gt;
         &lt;/blockquote&gt;
         
         &lt;p&gt;It seems that there is a fair variety of tools designed to make writing &lt;a href=&quot;http://en.wikipedia.org/wiki/Lexical_analysis&quot;&gt;Lexers, Scanners and Tokenizers&lt;/a&gt; easier, but &lt;a href=&quot;http://www.complang.org/ragel/&quot;&gt;Ragel&lt;/a&gt; has a reputation for being simple and consistently producing the fastest final code. This is a short and simple intro to Ragel for a common use-case: writing a Lexer for a programming language.&lt;/p&gt; &lt;p&gt;Start by making sure you have Ragel installed. This process varies for each OS so I&#39;m not going to cover it in detail. On OS X it&#39;s as easy as installing &lt;a href=&quot;http://www.macports.org/&quot;&gt;MacPorts&lt;/a&gt; and then opening a terminal and typing &#39;sudo port install ragel&#39;. You should now be able to use Ragel via the command-line.&lt;/p&gt; &lt;p&gt;Next you need to decide on your &#39;host language&#39;. The host language is preferably the same language that the rest of your project is written in, though many people opt to use C for their lexer because of the dramatic increase in speed that it provides. Ragel supports a number of host languages including: C, C++, Objective-C, D, Java and Ruby. For the purpose of this intro we will be using Ruby as it won&#39;t obscure the Ragel-specific code as much as other languages would.&lt;/p&gt; &lt;p&gt;First let&#39;s create a blank file called &#39;lexer.rl&#39; and then define an empty state machine inside it. Ragel state machines are defined inside blocks demarcated with &#39;%%{ }%%&#39; like so:&lt;/p&gt; &lt;script src=&quot;http://gist.github.com/474637.js&quot;&gt;&lt;/script&gt; &lt;p&gt;In this Ragel code block we are defining a blank state machine called &#39;test_lexer&#39;, then telling Ragel that the state machine should be compiled in this file using the &#39;write data&#39; directive. The ability to define where the state machine should be compiled is more useful once we start defining machines that span multiple files. Regions outside of &#39;%%{ }%%&#39; blocks and lines that do not start with &#39;%%&#39; are assumed to be written in the host language.&lt;/p&gt; &lt;p&gt;In Ragel the syntax for defining a lexer/scanner differs from that required for creating a normal state-machine and looks like this:&lt;/p&gt; &lt;script src=&quot;http://gist.github.com/474638.js&quot;&gt;&lt;/script&gt; &lt;p&gt;If the &#39;scanner_name&#39; is &#39;main&#39; then it is automatically run when our state machine is executed. An &#39;action&#39; is a section of host-language code that is executed whenever the token represented by &#39;token_description&#39; is found. It could be something as simple as printing out the token, or it could be code to affect the state of something external like a parser.&lt;/p&gt; &lt;p&gt;Token descriptions can either be a string literal (like &#39;keyword&#39;)...
         </description> 
         <pubDate>Tue, 13 Jul 2010 00:00:00 PDT</pubDate> 
         <guid>http://thingsaaronmade.com/blog/a-simple-intro-to-writing-a-lexer-with-ragel.html</guid> 
      </item> 
      
      <item> 
         <title>Bootstrapping a prototype-based object-model in 44 lines of code.</title> 
         <link>http://thingsaaronmade.com/blog/bootstrapping-a-prototype-based-object-oriented-language-in-44-lines-of-code.html</link> 
         <description>
         &lt;blockquote&gt;
           &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; because these articles usually contain inline code examples 
           it is highly likely that they will not display properly in your feed reader.&lt;/p&gt;
           
           To see this article as it was originally written please visit: &lt;a href="http://thingsaaronmade.com/blog/bootstrapping-a-prototype-based-object-oriented-language-in-44-lines-of-code.html"&gt;http://thingsaaronmade.com/blog/bootstrapping-a-prototype-based-object-oriented-language-in-44-lines-of-code.html&lt;/a&gt;
         &lt;/blockquote&gt;
         
         &lt;p&gt;Until a few weeks ago I had always thought that writing a language required some crazy voodoo, but it turns out that once you start digging into the fundamentals they are actually fairly easy to understand and, under certain circumstances, fairly easy to implement as well.&lt;/p&gt; &lt;p&gt;In this short example we are going to implement a prototype-based object-model in Ruby. To make it a valid exercise we will not be using any of Ruby&#39;s object-oriented features. The final mini-language we create will not be pretty, but it will work. Making it pretty will require syntactical sugar for things like sending a message to an object, which is not something we will tackle just yet.&lt;/p&gt; &lt;p&gt;The first thing we need is a way to store the structure of our objects. For this purpose we are going to use a Hash like so:&lt;/p&gt; &lt;script src=&quot;http://gist.github.com/472900.js&quot;&gt;&lt;/script&gt; &lt;p&gt;The &#39;slots&#39; in this hash will store the methods/data that are associated with the object. The &#39;parent&#39; will be a pointer to the object&#39;s parent if it has one, and the &#39;size&#39; will simply keep track of how many key/value pairs are stored in &#39;slots&#39;.&lt;/p&gt; &lt;p&gt;Next we need to define functions for sending a message to an object, and for creating a new object that inherits the behaviour of a previous one:&lt;/p&gt; &lt;script src=&quot;http://gist.github.com/472906.js&quot;&gt;&lt;/script&gt; &lt;p&gt;The &#39;send&#39; function depends on the fact that each object is required to define or inherit a &#39;lookup&#39; method. The &#39;lookup&#39; method defines how an object reacts when it is sent a message. If the send function cannot find a &#39;lookup&#39; method defined on the current object then it follows the chain of inheritance upwards (via &#39;parent&#39;) until it finds one, or until the inheritance chain is exhausted.&lt;/p&gt; &lt;p&gt;The &#39;derive_from&#39; function simply creates a new object with an existing object as it&#39;s &#39;parent&#39;. This provides a way to create a new object that inherits behaviours from an existing object, this layout is technically known as &#39;single inheritance&#39;.&lt;/p&gt; &lt;p&gt;Next up we need to manually create the initial &#39;lookup&#39; method for our basic object:&lt;/p&gt; &lt;script src=&quot;http://gist.github.com/472918.js&quot;&gt;&lt;/script&gt; &lt;p&gt;The &#39;lookup&#39; method is very similar to the &#39;send&#39; function in that it traces the chain of inheritance looking for a slot with a key which corresponds with the &#39;message&#39;. If it finds a match then is simply returns the value of the slot so that &#39;send&#39; can execute it as a method. If it cannot find a corresponding...
         </description> 
         <pubDate>Mon, 12 Jul 2010 00:00:00 PDT</pubDate> 
         <guid>http://thingsaaronmade.com/blog/bootstrapping-a-prototype-based-object-oriented-language-in-44-lines-of-code.html</guid> 
      </item> 
      
      <item> 
         <title>Improving application throughput 9x with asynchronous responses in Rails 3</title> 
         <link>http://thingsaaronmade.com/blog/improving-application-throughput-900-percent-with-asynchronous-responses-in-rails-3.html</link> 
         <description>
         &lt;blockquote&gt;
           &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; because these articles usually contain inline code examples 
           it is highly likely that they will not display properly in your feed reader.&lt;/p&gt;
           
           To see this article as it was originally written please visit: &lt;a href="http://thingsaaronmade.com/blog/improving-application-throughput-900-percent-with-asynchronous-responses-in-rails-3.html"&gt;http://thingsaaronmade.com/blog/improving-application-throughput-900-percent-with-asynchronous-responses-in-rails-3.html&lt;/a&gt;
         &lt;/blockquote&gt;
         
         &lt;p&gt;&lt;blockquote&gt;&lt;strong&gt;Update:&lt;/strong&gt; A quick overview of the changes needed to setup Ajax-Gist to use asynchronous responses is available here: &lt;a href=&quot;http://github.com/aarongough/ajax-gist/commit/d740bea4182b9787349be945a345218bfb8873e4&quot;&gt;commit summary at GitHub&lt;/a&gt;&lt;/blockquote&gt;&lt;/p&gt; &lt;p&gt;Several weeks ago when writing &lt;a href=&quot;http://ajax-gist.com/&quot;&gt;Ajax-Gist.com&lt;/a&gt; one aspect of the project I neglected was performance. Because every un-cached request requires that we do a HTTP call to gist.github.com, application throughput was very low, on the order of 5 requests per second.&lt;/p&gt; &lt;p&gt;For the most part this was &#39;good enough&#39; and logs showed that very few people were being left waiting on the queue because of my fairly aggressive HTTP caching. But when it came down to it I wanted to be able to offer a more reliable and more performant service, ideally without shelling out the extra clams for access to more application instances on Heroku.&lt;/p&gt; &lt;p&gt;While thinking about the problem I remembered that Thin (the web-server that Heroku uses) is capable of serving asynchronous requests using EventMachine. I knew that asynchronous Rack applications were fairly easy to write, but I didn&#39;t want to abandon Rails because, while this is a fairly simple application, keeping the simplicity of Rails &lt;em&gt;and&lt;/em&gt; getting the advantage of higher application throughput in this and other more complex applications would be a big win.&lt;/p&gt; &lt;p&gt;Luckily this is one of those occasions where other, much smarter, people already had the same idea, albeit fairly recently. My research turned up a lot of work by &lt;a href=&quot;http://igvita.com/&quot;&gt;Ilya Grigorik&lt;/a&gt; and &lt;a href=&quot;http://www.mikeperham.com/&quot;&gt;Mike Perham&lt;/a&gt; that pushed toward this goal. &lt;a href=&quot;http://github.com/mperham/rack-fiber_pool&quot;&gt;Rack/Fiber-Pool&lt;/a&gt; by Mike is a piece of Rack middleware that runs each request in it&#39;s own Fiber, allowing the possibility of easy cooperative scheduling in Rack applications. While &lt;a href=&quot;http://github.com/igrigorik/em-synchrony&quot;&gt;EM-Synchrony&lt;/a&gt; provides a set of Fiber-aware EventMachine clients for common things like HTTP requests, Memcached, MySQL and Mongo.&lt;/p&gt; &lt;p&gt;Mike was kind enough to do all of the leg-work in creating &lt;a href=&quot;http://www.mikeperham.com/2010/04/03/introducing-phat-an-asynchronous-rails-app/&quot;&gt;a guide for creating asynchronous Rails 2.X applications&lt;/a&gt; and only 2 days ago Ilya provided &lt;a href=&quot;http://gist.github.com/432563&quot;&gt;an example for achieving the same results in Rails 3&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;In the end implementation turned out to be relatively simple, and the results speak for themselves:&lt;/p&gt; &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;text&quot;&gt;&lt;span class=&quot;lineno&quot;&gt; 1&lt;/span&gt; # Synchronous: &lt;span class=&quot;lineno&quot;&gt; 2&lt;/span&gt; &lt;span class=&quot;lineno&quot;&gt; 3&lt;/span&gt; Benchmarking 192.168.1.3 (be patient).....done &lt;span class=&quot;lineno&quot;&gt; 4&lt;/span&gt; Document Path: /gist/1010.js &lt;span class=&quot;lineno&quot;&gt; 5&lt;/span&gt; Concurrency Level: 30 &lt;span class=&quot;lineno&quot;&gt; 6&lt;/span&gt; Time taken for tests: 18.312 seconds &lt;span class=&quot;lineno&quot;&gt; 7&lt;/span&gt; Complete requests: 100 &lt;span class=&quot;lineno&quot;&gt; 8&lt;/span&gt; Requests per second: 5.46 [#/sec] (mean)...
         </description> 
         <pubDate>Sat, 12 Jun 2010 00:00:00 PDT</pubDate> 
         <guid>http://thingsaaronmade.com/blog/improving-application-throughput-900-percent-with-asynchronous-responses-in-rails-3.html</guid> 
      </item> 
      
      <item> 
         <title>Ruby, shallow copy surprise!</title> 
         <link>http://thingsaaronmade.com/blog/ruby-shallow-copy-surprise.html</link> 
         <description>
         &lt;blockquote&gt;
           &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; because these articles usually contain inline code examples 
           it is highly likely that they will not display properly in your feed reader.&lt;/p&gt;
           
           To see this article as it was originally written please visit: &lt;a href="http://thingsaaronmade.com/blog/ruby-shallow-copy-surprise.html"&gt;http://thingsaaronmade.com/blog/ruby-shallow-copy-surprise.html&lt;/a&gt;
         &lt;/blockquote&gt;
         
         &lt;p&gt;Many people, like me, that have done any C, C++ programming are used to the idea that programming languages either copy variables by value, or by reference, or either if explicitly set.&lt;/p&gt; &lt;p&gt;I was under the impression Ruby was a &#39;pass by value&#39; language, but no longer. After spending most of a day debugging a problem and then finding out that one of my base-level assumptions about Ruby was fundamentally flawed I was quite shocked, and felt more than a bit stupid. But upon talking to some fellow Rubyists the other day at &lt;a href=&quot;http://unspace.ca/innovation/pubnite&quot;&gt;Rails Pub Nite&lt;/a&gt; I found out I was not alone in my assumptions. This may seem silly to some that have broader experience with a range of high level languages, but to others (like me!) it can be quite surprising.&lt;/p&gt; &lt;p&gt;Consider this:&lt;/p&gt; &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;lineno&quot;&gt; 1&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;test/unit&amp;#39;&lt;/span&gt; &lt;span class=&quot;lineno&quot;&gt; 2&lt;/span&gt; &lt;span class=&quot;lineno&quot;&gt; 3&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SanityTest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Test&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Unit&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;TestCase&lt;/span&gt; &lt;span class=&quot;lineno&quot;&gt; 4&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_my_sanity&lt;/span&gt; &lt;span class=&quot;lineno&quot;&gt; 5&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;complex_array&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:blah&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;hello&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:foo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;blah&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;lineno&quot;&gt; 6&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;copied_array&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;complex_array&lt;/span&gt; &lt;span class=&quot;lineno&quot;&gt; 7&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;copied_array&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:blah&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;lineno&quot;&gt; 8&lt;/span&gt; &lt;span class=&quot;lineno&quot;&gt; 9&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;assert_not_equal&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;copied_array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;complex_array&lt;/span&gt; &lt;span class=&quot;lineno&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt; &lt;span class=&quot;lineno&quot;&gt;11&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt; &lt;span class=&quot;lineno&quot;&gt;12&lt;/span&gt; &lt;span class=&quot;lineno&quot;&gt;13&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# 1) Failure:&lt;/span&gt; &lt;span class=&quot;lineno&quot;&gt;14&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# test_my_sanity(SanityTest):&lt;/span&gt; &lt;span class=&quot;lineno&quot;&gt;15&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# &amp;lt;[{:blah=&amp;gt;nil}, {:foo=&amp;gt;&amp;quot;blah&amp;quot;}]&amp;gt; expected to be != to&lt;/span&gt; &lt;span class=&quot;lineno&quot;&gt;16&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# &amp;lt;[{:blah=&amp;gt;nil}, {:foo=&amp;gt;&amp;quot;blah&amp;quot;}]&amp;gt;&lt;/span&gt; &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;What? If ruby is copying by value why is that change back-propagating to our original array? How about &lt;strong&gt;Object.clone&lt;/strong&gt;? That should fix whatever the problem is. But no. After some research it turns out that there is a big difference between the way Ruby handles &#39;immediate&#39; values (Fixnum, Symbol) and the way it handles more complex objects (Float, String, Array, Hash, YourClass) during copying. The key thing that eventually jumped out at me when reading over the ruby &lt;strong&gt;Object&lt;/strong&gt; docs was the phrase &#39;shallow copy&#39;. What is a &#39;shallow copy&#39;? A shallow copy means that only the fundamental datatypes actually get copied into new objects, everything else gets copied as a reference to the original object!&lt;/p&gt; &lt;p&gt;So how can we fix this? It&#39;s not very Rubyish, but at least it&#39;s simple:&lt;/p&gt; &lt;div...
         </description> 
         <pubDate>Wed, 19 May 2010 00:00:00 PDT</pubDate> 
         <guid>http://thingsaaronmade.com/blog/ruby-shallow-copy-surprise.html</guid> 
      </item> 
      
      <item> 
         <title>Automatic content moderation with 'validates_text_content'</title> 
         <link>http://thingsaaronmade.com/blog/validates_text_content.html</link> 
         <description>
         &lt;blockquote&gt;
           &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; because these articles usually contain inline code examples 
           it is highly likely that they will not display properly in your feed reader.&lt;/p&gt;
           
           To see this article as it was originally written please visit: &lt;a href="http://thingsaaronmade.com/blog/validates_text_content.html"&gt;http://thingsaaronmade.com/blog/validates_text_content.html&lt;/a&gt;
         &lt;/blockquote&gt;
         
         &lt;p&gt;Over the last 6 months I have been working on a number of community websites, all of which aim to make it as easy as possible for people to contribute. No account creation, no captchas, no hassle. This has brought a particular problem to my attention: one of the greatest differences between a valuable online community and a horrible one is the level of time and thought that goes into the comments/content produced by the community members. As an example of this consider the comments written on &lt;a href=&quot;http://news.ycombinator.com/newcomments&quot;&gt;Hacker News&lt;/a&gt; versus the ones on &lt;a href=&quot;http://www.youtube.com/&quot;&gt;YouTube&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;A big issue for many online communities is the fact that distinguishing between valuable content and trash content in an automatic fashion is very hard. Most communities solve this problem by enlisting the help of human moderators in addition to a member-accessible content flagging system.&lt;/p&gt; &lt;p&gt;But what if human moderation is not an option? You have a small community that you want to grow quickly but you can&#39;t afford to devote untold hours moderating content or lots of money paying someone else to moderate the content for you. Luckily some simple statistical analysis can probably come to the rescue!&lt;/p&gt; &lt;p&gt;How many words does it take to say something of worth? Surely content that is only 20 characters long cannot be contributing much? How about content that has no capital letters? Or no punctuation? There are many patterns inherent in any written language that we can leverage to determine whether or not textual content meets a certain level of quality. Text that has been well though out will be laid out into sentences and paragraphs, will be well punctuated and consist mainly of words that are listed in a dictionary somewhere, rather than short abbreviations.&lt;/p&gt; &lt;p&gt;With this in mind we can dig up some simple relevant facts about how the English language is structured:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Sentences start with a capital letter and end with one of a variety of punctuation marks.&lt;/li&gt; &lt;li&gt;The letter &#39;E&#39; is the most commonly used letter in English words, occurring roughly 12% of the time.&amp;nbsp;&lt;a href=&quot;http://www.cs.bris.ac.uk/Teaching/Resources/COMS30124/Labs/freq.html&quot;&gt;[source]&lt;/a&gt;&lt;/li&gt; &lt;li&gt;The average length of an English word is roughly 5.1 characters. &lt;a href=&quot;http://blogamundo.net/lab/wordlengths/&quot;&gt;[source]&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;We can also pull in a relevant point from simple common sense etiquette:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Writing exclusively in BLOCK CAPS is a sign of either rudeness or laziness.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Without inventing strong A.I. or resorting to complex &lt;a href=&quot;http://en.wikipedia.org/wiki/Bayesian_spam_filtering&quot;&gt;Bayesian Filtering&lt;/a&gt;&amp;nbsp;we can still...
         </description> 
         <pubDate>Tue, 13 Apr 2010 00:00:00 PDT</pubDate> 
         <guid>http://thingsaaronmade.com/blog/validates_text_content.html</guid> 
      </item> 
      
      <item> 
         <title>Ternary Quandry</title> 
         <link>http://thingsaaronmade.com/blog/ternary-quandry.html</link> 
         <description>
         &lt;blockquote&gt;
           &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; because these articles usually contain inline code examples 
           it is highly likely that they will not display properly in your feed reader.&lt;/p&gt;
           
           To see this article as it was originally written please visit: &lt;a href="http://thingsaaronmade.com/blog/ternary-quandry.html"&gt;http://thingsaaronmade.com/blog/ternary-quandry.html&lt;/a&gt;
         &lt;/blockquote&gt;
         
         &lt;p&gt;When writing even fairly simple code in JavaScript you will encounter many situations where you need to test for the existence of a variable, and either use it or a secondary variable if it does not exist (or more correctly, does not evaluate to ‘true’). Consider this:&lt;/p&gt; &lt;div class=&#39;highlight&#39;&gt;&lt;pre&gt;&lt;code class=&#39;javascript&#39;&gt;&lt;span class=&#39;lineno&#39;&gt;1&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;if&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt; &lt;span class=&#39;nx&#39;&gt;object&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;nx&#39;&gt;property&lt;/span&gt; &lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;2&lt;/span&gt; &lt;span class=&#39;p&#39;&gt;{&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;3&lt;/span&gt; &lt;span class=&#39;kd&#39;&gt;var&lt;/span&gt; &lt;span class=&#39;nx&#39;&gt;result&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;nx&#39;&gt;object&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;nx&#39;&gt;property&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;;&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;4&lt;/span&gt; &lt;span class=&#39;p&#39;&gt;}&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;5&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;else&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;6&lt;/span&gt; &lt;span class=&#39;p&#39;&gt;{&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;7&lt;/span&gt; &lt;span class=&#39;kd&#39;&gt;var&lt;/span&gt; &lt;span class=&#39;nx&#39;&gt;result&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;nx&#39;&gt;object&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;nx&#39;&gt;otherProperty&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;;&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;8&lt;/span&gt; &lt;span class=&#39;p&#39;&gt;}&lt;/span&gt; &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This, while being easy to understand, clearly takes up a lot more room than it needs to. With this in mind many developers will turn to the &lt;a href=&#39;http://en.wikipedia.org/wiki/Ternary_operation&#39;&gt;Ternary operator&lt;/a&gt; to gain the same result in a more compact form:&lt;/p&gt; &lt;div class=&#39;highlight&#39;&gt;&lt;pre&gt;&lt;code class=&#39;javascript&#39;&gt;&lt;span class=&#39;lineno&#39;&gt;1&lt;/span&gt; &lt;span class=&#39;kd&#39;&gt;var&lt;/span&gt; &lt;span class=&#39;nx&#39;&gt;result&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nx&#39;&gt;object&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;nx&#39;&gt;property&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;?&lt;/span&gt; &lt;span class=&#39;nx&#39;&gt;object&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;nx&#39;&gt;property&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;:&lt;/span&gt; &lt;span class=&#39;nx&#39;&gt;object&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;nx&#39;&gt;otherProperty&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;;&lt;/span&gt; &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Personally I find the syntax of the Ternary operator confusing… Can you easily recall which variable is assigned when the condition is met? How about someone that has just started programming? What if it is used in the middle of another expression? I am a big believer in making the function of your code as obvious as possible and, for me at least, the Ternary operator does not contribute toward that ideal.&lt;/p&gt; &lt;p&gt;Enter the Or operator:&lt;/p&gt; &lt;div class=&#39;highlight&#39;&gt;&lt;pre&gt;&lt;code class=&#39;javascript&#39;&gt;&lt;span class=&#39;lineno&#39;&gt;1&lt;/span&gt; &lt;span class=&#39;kd&#39;&gt;var&lt;/span&gt; &lt;span class=&#39;nx&#39;&gt;result&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;nx&#39;&gt;object&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;nx&#39;&gt;property&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;||&lt;/span&gt; &lt;span class=&#39;nx&#39;&gt;object&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;nx&#39;&gt;otherProperty&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;;&lt;/span&gt; &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;In this example we are using a lesser-known sprinkling of JavaScript’s syntactical sugar. If the &lt;code&gt;object.property&lt;/code&gt; variable evaluates to true it is assigned, otherwise the Or operator jumps in and hands the second variable (&lt;code&gt;object.otherProperty&lt;/code&gt;) to the receiving variable. To illustrate:&lt;/p&gt; &lt;div class=&#39;highlight&#39;&gt;&lt;pre&gt;&lt;code class=&#39;javascript&#39;&gt;&lt;span class=&#39;lineno&#39;&gt;1&lt;/span&gt; &lt;span class=&#39;nb&#39;&gt;window&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;nx&#39;&gt;firstProperty&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;Hello!&amp;quot;&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;;&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;2&lt;/span&gt; &lt;span class=&#39;nb&#39;&gt;window&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;nx&#39;&gt;secondProperty&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;I&amp;#39;m number 2!&amp;quot;&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;;&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;3&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;4&lt;/span&gt; &lt;span class=&#39;kd&#39;&gt;var&lt;/span&gt; &lt;span class=&#39;nx&#39;&gt;result&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;nb&#39;&gt;window&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;nx&#39;&gt;firstProperty&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;||&lt;/span&gt; &lt;span class=&#39;nb&#39;&gt;window&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;nx&#39;&gt;secondProperty&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;;&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;5&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;6&lt;/span&gt; &lt;span class=&#39;nx&#39;&gt;alert&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt; &lt;span class=&#39;nx&#39;&gt;result&lt;/span&gt; &lt;span class=&#39;p&#39;&gt;);&lt;/span&gt; &lt;span class=&#39;c1&#39;&gt;// Hello!&lt;/span&gt; &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#39;highlight&#39;&gt;&lt;pre&gt;&lt;code class=&#39;javascript&#39;&gt;&lt;span class=&#39;lineno&#39;&gt;1&lt;/span&gt; &lt;span class=&#39;c1&#39;&gt;// window.firstProperty === undefined;&lt;/span&gt; &lt;span class=&#39;lineno&#39;&gt;2&lt;/span&gt; &lt;span class=&#39;nb&#39;&gt;window&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;nx&#39;&gt;secondProperty&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;I&amp;#39;m number 2!&amp;quot;&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;;&lt;/span&gt; &lt;span...
         </description> 
         <pubDate>Tue, 13 Apr 2010 00:00:00 PDT</pubDate> 
         <guid>http://thingsaaronmade.com/blog/ternary-quandry.html</guid> 
      </item> 
      
      
    </channel> 
</rss>