<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Random Hacks: Tag Ruby</title>
    <link>http://www.randomhacks.net/articles/tag/Ruby?tag=Ruby</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>Technology and Other Fun Stuff</description>
    <item>
      <title>Ruby-style metaprogramming in JavaScript (plus a port of RSpec)</title>
      <description>&lt;p&gt;Programming in Ruby makes me happy.  It&amp;#8217;s a lovable language, with a
pleasantly quirky syntax and lots of expressive power.&lt;/p&gt;

&lt;p&gt;Programming in JavaScript, on the other hand, frustrates me to no end.
JavaScript &lt;i&gt;could&lt;/i&gt; be a reasonable language, but it has all sorts of
ugly corner cases, and it forces me to roll everything from scratch.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ve been trying to make JavaScript a bit more like Ruby.  In particular, I
want to support Ruby-style metaprogramming in JavaScript.  This would make it possible to port over many advanced Ruby libraries.&lt;/p&gt;

&lt;p&gt;You can
check out the &lt;a href="http://www.randomhacks.net/svn/planetary/tags/0.1.0/spec_checker.html"&gt;interactive specification&lt;/a&gt;, or look at some examples
below.  If the &lt;a href="http://www.randomhacks.net/svn/planetary/tags/0.1.0/spec_checker.html"&gt;specification&lt;/a&gt; gives you any errors, please post them in the comment
thread, and let me know what browser you&amp;#8217;re running!&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.randomhacks.net/articles/2007/07/01/ruby-metaprogramming-javascript-rspec-bdd"&gt;Read More&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Sun, 01 Jul 2007 19:00:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:421e0747-a145-4fc3-b0f1-8a5323eaea01</guid>
      <author>Eric Kidd</author>
      <link>http://www.randomhacks.net/articles/2007/07/01/ruby-metaprogramming-javascript-rspec-bdd</link>
      <category>Ruby</category>
      <category>JavaScript</category>
      <category>Macros</category>
      <category>Planetary</category>
      <trackback:ping>http://www.randomhacks.net/articles/trackback/472</trackback:ping>
    </item>
    <item>
      <title>Some useful closures, in Ruby</title>
      <description>&lt;p&gt;Reginald Braithwaite has just posted &lt;a href="http://weblog.raganwald.com/2007/01/closures-and-higher-order-functions.html"&gt;a short introduction to closures in Ruby&lt;/a&gt;. Closures allow you to pass functions around your program, and build new functions from old ones.&lt;/p&gt;

&lt;p&gt;Programming languages that support closures include Perl, Ruby, Python (sorta), Lisp, Haskell, Dylan, Javascript and many others.&lt;/p&gt;

&lt;p&gt;The &lt;a href="http://en.wikipedia.org/wiki/Dylan_programming_language"&gt;Dylan programming language&lt;/a&gt; included four very useful functions built using closures: &lt;strong&gt;complement&lt;/strong&gt;, &lt;strong&gt;conjoin&lt;/strong&gt;, &lt;strong&gt;disjoin&lt;/strong&gt; and &lt;strong&gt;compose&lt;/strong&gt;.  The names are a bit obscure, but they can each be written in a few lines of Ruby.&lt;/p&gt;

&lt;p&gt;Let&amp;#8217;s start with &lt;strong&gt;complement&lt;/strong&gt;:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="comment"&gt;# Builds a function that returns true&lt;/span&gt;
&lt;span class="comment"&gt;# when 'f' returns false, and vice versa.&lt;/span&gt;
&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;complement&lt;/span&gt; &lt;span class="ident"&gt;f&lt;/span&gt;
  &lt;span class="ident"&gt;lambda&lt;/span&gt; &lt;span class="punct"&gt;{|*&lt;/span&gt;&lt;span class="ident"&gt;args&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="keyword"&gt;not&lt;/span&gt; &lt;span class="ident"&gt;f&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;call&lt;/span&gt;&lt;span class="punct"&gt;(*&lt;/span&gt;&lt;span class="ident"&gt;args&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;We can use this to build the &amp;#8220;opposite&amp;#8221; of a function:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;is_even&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;lambda&lt;/span&gt; &lt;span class="punct"&gt;{|&lt;/span&gt;&lt;span class="ident"&gt;n&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="ident"&gt;n&lt;/span&gt; &lt;span class="punct"&gt;%&lt;/span&gt; &lt;span class="number"&gt;2&lt;/span&gt; &lt;span class="punct"&gt;==&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;
&lt;span class="ident"&gt;is_odd&lt;/span&gt;  &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;complement&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;is_even&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;

&lt;span class="ident"&gt;is_odd&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;call&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="comment"&gt;# true&lt;/span&gt;
&lt;span class="ident"&gt;is_odd&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;call&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;2&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="comment"&gt;# false&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;compose&lt;/strong&gt; is another useful function:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="comment"&gt;# Builds a function which calls 'f' with&lt;/span&gt;
&lt;span class="comment"&gt;# the return value of 'g'.&lt;/span&gt;
&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;compose&lt;/span&gt; &lt;span class="ident"&gt;f&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;g&lt;/span&gt;
  &lt;span class="ident"&gt;lambda&lt;/span&gt; &lt;span class="punct"&gt;{|*&lt;/span&gt;&lt;span class="ident"&gt;args&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="ident"&gt;f&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;call&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;g&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;call&lt;/span&gt;&lt;span class="punct"&gt;(*&lt;/span&gt;&lt;span class="ident"&gt;args&lt;/span&gt;&lt;span class="punct"&gt;))&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;We can use this to pass the output of one function to the input of another:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;mult2&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;lambda&lt;/span&gt; &lt;span class="punct"&gt;{|&lt;/span&gt;&lt;span class="ident"&gt;n&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="ident"&gt;n&lt;/span&gt;&lt;span class="punct"&gt;*&lt;/span&gt;&lt;span class="number"&gt;2&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;
&lt;span class="ident"&gt;add1&lt;/span&gt;  &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;lambda&lt;/span&gt; &lt;span class="punct"&gt;{|&lt;/span&gt;&lt;span class="ident"&gt;n&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="ident"&gt;n&lt;/span&gt;&lt;span class="punct"&gt;+&lt;/span&gt;&lt;span class="number"&gt;1&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;
&lt;span class="ident"&gt;mult2_add1&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;compose&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;add1&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;mult2&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;

&lt;span class="ident"&gt;mult2_add1&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;call&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;3&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="comment"&gt;# 7&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The &lt;strong&gt;conjoin&lt;/strong&gt; function is a bit more complicated, but still very useful:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="comment"&gt;# Builds a function which returns true&lt;/span&gt;
&lt;span class="comment"&gt;# whenever _every_ function in 'predicates'&lt;/span&gt;
&lt;span class="comment"&gt;# returns true.&lt;/span&gt;
&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;conjoin&lt;/span&gt; &lt;span class="punct"&gt;*&lt;/span&gt;&lt;span class="ident"&gt;predicates&lt;/span&gt;
  &lt;span class="ident"&gt;base&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;lambda&lt;/span&gt; &lt;span class="punct"&gt;{|*&lt;/span&gt;&lt;span class="ident"&gt;args&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="constant"&gt;true&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;
  &lt;span class="ident"&gt;predicates&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;inject&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;base&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;built&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;pred&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
    &lt;span class="ident"&gt;lambda&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|*&lt;/span&gt;&lt;span class="ident"&gt;args&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
      &lt;span class="ident"&gt;built&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;call&lt;/span&gt;&lt;span class="punct"&gt;(*&lt;/span&gt;&lt;span class="ident"&gt;args&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="ident"&gt;pred&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;call&lt;/span&gt;&lt;span class="punct"&gt;(*&lt;/span&gt;&lt;span class="ident"&gt;args&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;We can use it to construct the logical &amp;#8220;and&amp;#8221; of a list of functions:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;is_number&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;lambda&lt;/span&gt; &lt;span class="punct"&gt;{|&lt;/span&gt;&lt;span class="ident"&gt;n&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="ident"&gt;n&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;kind_of?&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="constant"&gt;Numeric&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;
&lt;span class="ident"&gt;is_even_number&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;conjoin&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;is_number&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;is_even&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;

&lt;span class="ident"&gt;is_even_number&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;call&lt;/span&gt;&lt;span class="punct"&gt;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;a&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;)&lt;/span&gt; &lt;span class="comment"&gt;# false&lt;/span&gt;
&lt;span class="ident"&gt;is_even_number&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;call&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;   &lt;span class="comment"&gt;# false&lt;/span&gt;
&lt;span class="ident"&gt;is_even_number&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;call&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;2&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;   &lt;span class="comment"&gt;# true&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The opposite of &lt;strong&gt;conjoin&lt;/strong&gt; is &lt;strong&gt;disjoin&lt;/strong&gt;:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="comment"&gt;# Builds a function which returns true&lt;/span&gt;
&lt;span class="comment"&gt;# whenever _any_ function in 'predicates'&lt;/span&gt;
&lt;span class="comment"&gt;# returns true.&lt;/span&gt;
&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;disjoin&lt;/span&gt; &lt;span class="punct"&gt;*&lt;/span&gt;&lt;span class="ident"&gt;predicates&lt;/span&gt;
  &lt;span class="ident"&gt;base&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;lambda&lt;/span&gt; &lt;span class="punct"&gt;{|*&lt;/span&gt;&lt;span class="ident"&gt;args&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="constant"&gt;false&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;
  &lt;span class="ident"&gt;predicates&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;inject&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;base&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;built&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;pred&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
    &lt;span class="ident"&gt;lambda&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|*&lt;/span&gt;&lt;span class="ident"&gt;args&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
      &lt;span class="ident"&gt;built&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;call&lt;/span&gt;&lt;span class="punct"&gt;(*&lt;/span&gt;&lt;span class="ident"&gt;args&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;||&lt;/span&gt; &lt;span class="ident"&gt;pred&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;call&lt;/span&gt;&lt;span class="punct"&gt;(*&lt;/span&gt;&lt;span class="ident"&gt;args&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This allows us to construct the logical &amp;#8220;or&amp;#8221; of a list of functions:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;is_string&lt;/span&gt;  &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;lambda&lt;/span&gt; &lt;span class="punct"&gt;{|&lt;/span&gt;&lt;span class="ident"&gt;n&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="ident"&gt;n&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;kind_of?&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="constant"&gt;String&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;
&lt;span class="ident"&gt;is_string_or_number&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt;
  &lt;span class="ident"&gt;disjoin&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;is_string&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;is_number&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;

&lt;span class="ident"&gt;is_string_or_number&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;call&lt;/span&gt;&lt;span class="punct"&gt;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;a&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;)&lt;/span&gt; &lt;span class="comment"&gt;# true&lt;/span&gt;
&lt;span class="ident"&gt;is_string_or_number&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;call&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;   &lt;span class="comment"&gt;# true&lt;/span&gt;
&lt;span class="ident"&gt;is_string_or_number&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;call&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:a&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;  &lt;span class="comment"&gt;# false&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;These were four of the first closure-related functions I ever used, and they&amp;#8217;re still favorites today.&lt;/p&gt;

&lt;p&gt;Feel free to post versions in other languages below!&lt;/p&gt;</description>
      <pubDate>Thu, 01 Feb 2007 18:36:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:662731c8-031a-46e3-97bc-02668e09b272</guid>
      <author>Eric Kidd</author>
      <link>http://www.randomhacks.net/articles/2007/02/01/some-useful-closures-in-ruby</link>
      <category>Ruby</category>
      <category>Hacks</category>
      <trackback:ping>http://www.randomhacks.net/articles/trackback/245</trackback:ping>
    </item>
    <item>
      <title>13 Ways of Looking at a Ruby Symbol</title>
      <description>&lt;p&gt;New Ruby programmers often ask, &amp;#8220;What, exactly, &lt;em&gt;is&lt;/em&gt; a symbol? And how does
it differ from a string?&amp;#8221;  No one answer works for everybody, so&amp;#8211;with
&lt;a href="http://www.poets.org/viewmedia.php/prmMID/15746"&gt;apologies to Wallace Stevens&lt;/a&gt;&amp;#8211;here are 13 ways of looking at a
Ruby symbol.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.randomhacks.net/articles/2007/01/20/13-ways-of-looking-at-a-ruby-symbol"&gt;Read More&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Sat, 20 Jan 2007 03:20:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:46f3fe2b-e387-46d2-a682-8047b0fbf523</guid>
      <author>Eric Kidd</author>
      <link>http://www.randomhacks.net/articles/2007/01/20/13-ways-of-looking-at-a-ruby-symbol</link>
      <category>Ruby</category>
      <trackback:ping>http://www.randomhacks.net/articles/trackback/194</trackback:ping>
    </item>
    <item>
      <title>Why Ruby is an acceptable LISP</title>
      <description>&lt;p&gt;Years ago, I looked at Ruby and decided to ignore it. Ruby wasn&amp;#8217;t as
popular as Python, and it wasn&amp;#8217;t as powerful as LISP. So why should I
bother?&lt;/p&gt;

&lt;p&gt;Of course, we could turn those criteria around.  What if Ruby were more
popular than &lt;em&gt;LISP&lt;/em&gt;, and more powerful than &lt;em&gt;Python&lt;/em&gt;?  Would that be enough
to make Ruby interesting?&lt;/p&gt;

&lt;p&gt;Before answering this question, we should decide what makes LISP so
powerful.  Paul Graham has &lt;a href="http://www.paulgraham.com/icad.html" title="Revenge of the Nerds"&gt;written eloquently&lt;/a&gt; about LISP&amp;#8217;s virtues.  But, for the sake of argument, I&amp;#8217;d like to boil them down to two things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;LISP is a dense functional language.  &lt;/li&gt;
&lt;li&gt;LISP has programmatic macros.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As it turns out, Ruby compares well as a functional language, and it fakes
macros better than I&amp;#8217;d thought.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.randomhacks.net/articles/2005/12/03/why-ruby-is-an-acceptable-lisp"&gt;Read More&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Sat, 03 Dec 2005 11:30:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:080ade06-c978-4e36-8847-44c22d1bc9b9</guid>
      <author>Eric Kidd</author>
      <link>http://www.randomhacks.net/articles/2005/12/03/why-ruby-is-an-acceptable-lisp</link>
      <category>Ruby</category>
      <category>LISP</category>
      <category>Macros</category>
      <category>Recommended</category>
      <trackback:ping>http://www.randomhacks.net/articles/trackback/77</trackback:ping>
    </item>
    <item>
      <title>Moving a blog to Typo</title>
      <description>&lt;p&gt;This weekend, I moved Random Hacks to &lt;a href="http://typo.leetsoft.com/trac/"&gt;Typo&lt;/a&gt;, a nifty Rails-based blogging system. Here&amp;#8217;s what I did:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set up my Mac for Rails development&lt;/li&gt;
&lt;li&gt;Pointed Typo at MySQL&lt;/li&gt;
&lt;li&gt;Created a custom theme&lt;/li&gt;
&lt;li&gt;Wrote an article importer&lt;/li&gt;
&lt;li&gt;Routed my old URLs to new locations&lt;/li&gt;
&lt;li&gt;&lt;a href="http://randomhacks.net/articles/2005/11/13/typo-sidebars-recent-comments-and-tagged-articles"&gt;Wrote some custom sidebars&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Configured Debian&amp;#8217;s mod_fcgid&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now for the gruesome details.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.randomhacks.net/articles/2005/11/15/moving-a-blog-to-typo"&gt;Read More&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Tue, 15 Nov 2005 22:13:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:e3f3c54b-6034-48f2-8949-d5e37a76558d</guid>
      <author>Eric Kidd</author>
      <link>http://www.randomhacks.net/articles/2005/11/15/moving-a-blog-to-typo</link>
      <category>Rails</category>
      <category>Typo</category>
      <category>Ruby</category>
      <trackback:ping>http://www.randomhacks.net/articles/trackback/76</trackback:ping>
    </item>
    <item>
      <title>Random Hacks is back online</title>
      <description>    &lt;p&gt;I just recovered the contents of this site after a two-year hiatus.
    I'm going to try to dig up some other old stuff, too.&lt;/p&gt;

    &lt;p&gt;I should really rebuild this whole site using Ruby on Rails and some
    Ajax goodness.  But that's going to have to wait until I ship some
    software at work and take care of other personal projects.&lt;/p&gt;</description>
      <pubDate>Tue, 11 Oct 2005 00:00:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:cf79983a-dc3f-43d8-9522-b840329faef7</guid>
      <author>Eric</author>
      <link>http://www.randomhacks.net/articles/2005/10/11/back-online</link>
      <category>Ruby</category>
      <category>Rails</category>
      <trackback:ping>http://www.randomhacks.net/articles/trackback/71</trackback:ping>
    </item>
    <item>
      <title>McCarthy's Ambiguous Operator</title>
      <description>    &lt;p&gt;Back in 1961, John McCarthy (the inventor of LISP) &lt;a href='http://citeseer.ist.psu.edu/mccarthy63basis.html'&gt;described&lt;/a&gt;
    an interesting mathematical operator called &lt;code&gt;amb&lt;/code&gt;.  Essentially,
    &lt;code&gt;amb&lt;/code&gt; &lt;i&gt;hates&lt;/i&gt; to be called with no arguments, and can look
    into the future to keep that from happening.  Here's how it might look
    in Ruby.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.randomhacks.net/articles/2005/10/11/amb-operator"&gt;Read More&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Tue, 11 Oct 2005 00:00:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:8d29ae6d-81d0-4f48-a6cb-80187e1821a7</guid>
      <author>Eric</author>
      <link>http://www.randomhacks.net/articles/2005/10/11/amb-operator</link>
      <category>Ruby</category>
      <category>Continuations</category>
      <category>Hacks</category>
      <category>Recommended</category>
      <trackback:ping>http://www.randomhacks.net/articles/trackback/70</trackback:ping>
    </item>
  </channel>
</rss>
