<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">

 <title>a.blog.about.code</title>
 
 <link href="http://ablogaboutcode.com/" />
 <updated>2013-04-01T14:38:00-07:00</updated>
 <id>http://ablogaboutcode.com/</id>
 <description>{ topic: "code", type: "blog", author: "pan thomakos" }</description>
 <author>
   <name>Pan Thomakos</name>
 </author>
 <image>
   <url>http://ablogaboutcode.com/assets/icon.jpeg</url>
   <title>a.blog.about.code</title>
   <link>http://ablogaboutcode.com/</link>
 </image>

 
 <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/ablogaboutcode" /><feedburner:info uri="ablogaboutcode" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry>
   <title><![CDATA[Overwriting Console Output Using Curses in Ruby]]></title>
   <link href="http://feedproxy.google.com/~r/ablogaboutcode/~3/R0fV3bAEEDg/overwriting-console-output-using-curses-in-ruby" />
   <updated>2013-04-01T00:00:00-07:00</updated>
   <id>http://ablogaboutcode.com//2013/04/01/overwriting-console-output-using-curses-in-ruby</id>
   <content type="html">
     
     &lt;p&gt;&lt;a href="http://translate.google.com/?hl=en&amp;amp;tab=TT&amp;amp;authuser=0#el/en/%CE%9A%CE%B1%CE%BB%CF%8C%20%CE%BC%CE%AE%CE%BD%CE%B1"&gt;Καλό μήνα&lt;/a&gt;! A while back I wrote about how to
&lt;a href="/2012/04/16/overwriting-console-output-in-ruby"&gt;overwrite console output in Ruby&lt;/a&gt;. Originally the project I used this
technique for only required overwriting a single line of output. That project
has now grown and I need to be able to maintain a mini-dashboard on the console.&lt;/p&gt;

&lt;p&gt;Fortunately, Ruby rocks and has a &lt;a href="http://www.ruby-doc.org/stdlib-2.0/libdoc/curses/rdoc/Curses.html"&gt;standard library wrapper for Curses&lt;/a&gt;.
I would encourage you to read through the documentation. I've written a simple
script to show-off the most basic use-case. In this example I initialize ten
workers. Each worker is responsible for keeping track of the work she has
completed, &lt;code&gt;@percent&lt;/code&gt;, and then reporting that progress on her own line,
&lt;code&gt;@index&lt;/code&gt;, of the console.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="c1"&gt;#!/usr/bin/env ruby&lt;/span&gt;

&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;curses&amp;#39;&lt;/span&gt;

&lt;span class="no"&gt;Curses&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;noecho&lt;/span&gt;
&lt;span class="no"&gt;Curses&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;init_screen&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Worker&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;
    &lt;span class="vi"&gt;@percent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;run&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;work&lt;/span&gt;
      &lt;span class="n"&gt;report&lt;/span&gt;
      &lt;span class="nb"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;rand&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;to_s&lt;/span&gt;
    &lt;span class="s2"&gt;&amp;quot;Worker #&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;%2d&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="vi"&gt;@index&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; is &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;%3d&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="vi"&gt;@percent&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;% complete&amp;quot;&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="kp"&gt;private&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;work&lt;/span&gt;
    &lt;span class="vi"&gt;@percent&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;report&lt;/span&gt;
    &lt;span class="no"&gt;Curses&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setpos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="no"&gt;Curses&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;addstr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;to_s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="no"&gt;Curses&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;refresh&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;workers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="no"&gt;Worker&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nb"&gt;at_exit&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;workers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;worker&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;worker&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;workers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;worker&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="no"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;worker&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="ss"&gt;:join&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="no"&gt;Curses&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;close_screen&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Because Curses clears the screen once it is complete, the &lt;code&gt;at_exit&lt;/code&gt; block
ensures that the last known state of the workers is echoed to the screen one
last time.&lt;/p&gt;

&lt;p&gt;Another command I found useful was the &lt;code&gt;Curses.clear&lt;/code&gt; command. This function
clears the entire screen before rewriting output. This is particularly helpful
when you want to overwrite a long line of text with a shorter one.&lt;/p&gt;

&lt;p&gt;I hope this was helpful! Have fun making some cool console applications. If you
build something worth sharing, please leave a comment that links to your code.&lt;/p&gt;

     
   &lt;img src="http://feeds.feedburner.com/~r/ablogaboutcode/~4/R0fV3bAEEDg" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://ablogaboutcode.com//2013/04/01/overwriting-console-output-using-curses-in-ruby</feedburner:origLink></entry>
 
 <entry>
   <title><![CDATA[Context Driven Refactoring]]></title>
   <link href="http://feedproxy.google.com/~r/ablogaboutcode/~3/_jF889Kcq_4/context-driven-refactoring" />
   <updated>2012-12-16T00:00:00-08:00</updated>
   <id>http://ablogaboutcode.com//2012/12/16/context-driven-refactoring</id>
   <content type="html">
     
     &lt;p&gt;I got excited about this refactoring website called &lt;a href="http://www.refactr.it"&gt;refactr.it&lt;/a&gt;. Users
post refactoring questions and vote on the best answers. The website is kind of
a simplified version of the &lt;a href="http://programmers.stackexchange.com"&gt;Programmers Stack Exchange&lt;/a&gt;. But as I explored
the ruby section, which is definitely still in it's infancy, I was a little
disappointed.&lt;/p&gt;

&lt;p&gt;Here is an example of a question and solution that was titled
"&lt;a href="http://www.refactr.it/problems/50bab8def2f2231000000001"&gt;Simplifying Nested If Statements&lt;/a&gt;".&lt;/p&gt;

&lt;h2&gt;Question Code&lt;/h2&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="vi"&gt;@problems&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@tags&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;blank?&lt;/span&gt;
        &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="vi"&gt;@language&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nil?&lt;/span&gt;
            &lt;span class="no"&gt;Problem&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;language&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="vi"&gt;@language&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;desc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@sort&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@page&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;
            &lt;span class="no"&gt;Problem&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;desc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@sort&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@page&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="vi"&gt;@language&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nil?&lt;/span&gt;
            &lt;span class="no"&gt;Problem&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;in&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="vi"&gt;@tags&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;language&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="vi"&gt;@language&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;desc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@sort&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@page&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;
            &lt;span class="no"&gt;Problem&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;in&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="vi"&gt;@tags&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;desc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@sort&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@page&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h2&gt;Solution Code&lt;/h2&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="vi"&gt;@problems&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Problem&lt;/span&gt;
&lt;span class="vi"&gt;@problems&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@problems&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;in&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="vi"&gt;@tags&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="vi"&gt;@tags&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;blank?&lt;/span&gt;
&lt;span class="vi"&gt;@problems&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@problems&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;language&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="vi"&gt;@language&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="vi"&gt;@language&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nil?&lt;/span&gt;
&lt;span class="vi"&gt;@problems&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@problems&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;desc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@sort&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@page&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The solution is definitely a start. In fact it "simplifies the nested if
statement" perfectly. And I would be a much happier programmer if I happened
upon the solution code than I would be if I came across the question code. My
disappointment is that the refactoring lacks context. It's just an example of a
refactoring formula:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="c1"&gt;# Nested&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;
    &lt;span class="n"&gt;Z&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Y&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="n"&gt;Z&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;
    &lt;span class="n"&gt;Z&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Y&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="n"&gt;Z&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# Not Nested&lt;/span&gt;

&lt;span class="n"&gt;chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Z&lt;/span&gt;
&lt;span class="n"&gt;chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;chain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt;
&lt;span class="n"&gt;chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;chain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Y&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The solution is "correct", and it's a valuable technique, but it misses the
mark. Refactoring often falls short &lt;strong&gt;because&lt;/strong&gt; people blindly apply a selection
of these transformations and then call it a day. &lt;strong&gt;Refactoring isn't just about
rewriting code.&lt;/strong&gt; Let's take a look at a couple of questions that might help us
devise a better strategy for approaching this problem.&lt;/p&gt;

&lt;h2&gt;Question One: Why should I refactor this code?&lt;/h2&gt;

&lt;p&gt;Refactoring is fun, but if the code is a mess, and you don't need to touch it,
&lt;a href="http://confreaks.com/videos/1115-gogaruco2012-go-ahead-make-a-mess"&gt;leave it alone&lt;/a&gt;. As Sandi Metz explains, if you can't see the mess, it
doesn't exist. &lt;strong&gt;Refactoring should always happen for a reason.&lt;/strong&gt; In this case
there are multiple potential reasons we might need to refactor. But leaving that
reasoning out of the discussion can lead to a misguided solution.&lt;/p&gt;

&lt;p&gt;Do I need to add a new search parameter? Then I'm probably in need of a solution
that reduces complexity.&lt;/p&gt;

&lt;p&gt;Am I replicating this code somewhere else? Then I'm probably in need of a
solution that DRYs up my existing implementation.&lt;/p&gt;

&lt;h2&gt;Step One: Establish a context for the refactoring.&lt;/h2&gt;

&lt;p&gt;Let's start with, "I need to add a new search parameter." This helps us
establish that the code is too complex, and that we need to address this issue
because we need to change the code.&lt;/p&gt;

&lt;h2&gt;Question Two: How am I going to test this code?&lt;/h2&gt;

&lt;p&gt;Imagine, first without using a database, how you would go about testing the
question code, or even the solution code for that matter. You would definitely
have to provide stubs for &lt;code&gt;#in&lt;/code&gt;, &lt;code&gt;#where&lt;/code&gt;, &lt;code&gt;#sort&lt;/code&gt; and &lt;code&gt;#page&lt;/code&gt;. You would have
to test conditionals for &lt;code&gt;@language&lt;/code&gt;, &lt;code&gt;@tags&lt;/code&gt;, and your new search parameter.
And all those tests have to combined with the rest of the controller tests for
the search action.&lt;/p&gt;

&lt;p&gt;Even if you allowed yourself use of the database, you would still have to
construct objects for each of the test scenarios and verify that the
conditionals were working properly.&lt;/p&gt;

&lt;p&gt;That's a lot of stuff (otherwise know as responsibilities). The "always write
tests" mantra isn't just meant to increase code confidence, it helps illuminate
design flaws and unwanted complexity.&lt;/p&gt;

&lt;h2&gt;Step Two: Read/Write Tests.&lt;/h2&gt;

&lt;p&gt;Assuming the tests don't already exist, write them. Even though they are brutal
to write after the fact, you need to have test coverage before you start moving
code around.&lt;/p&gt;

&lt;h2&gt;Question Three: What did the tests teach us?&lt;/h2&gt;

&lt;p&gt;Probably that we have a "Fat Controller". You've probably heard of "Fat Models,
Skinny Controllers", but this heuristic does not really mean Fat
&lt;code&gt;ActiveRecord::Base&lt;/code&gt; classes and Skinny &lt;code&gt;ApplicationController&lt;/code&gt; classes. It
means that objects responsible for connecting business logic and views, should
do only that. It's the "Single Responsibility Principle" in Rails terms.&lt;/p&gt;

&lt;p&gt;The reason we should strive for single responsibility objects is that they are
easier to extend and test. In this case we've seen how difficult it is to test
the code (in both the question and the solution) which indicates that the
proposed solution should probably not be our first refactoring step.&lt;/p&gt;

&lt;h2&gt;Step Three: Refactor Your Code&lt;/h2&gt;

&lt;p&gt;Because the tests indicated an unnecessary complexity, we know that we should
probably introduce a new object this is responsible for handling some of the
logic, without involving the controller.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="vi"&gt;@problems&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;ProblemSearch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@language&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vi"&gt;@tags&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vi"&gt;@sort&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vi"&gt;@page&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;So what goes into &lt;code&gt;ProblemSearch#find&lt;/code&gt;? Probably the original solution, but
at this point it really doesn't matter because it's completely isolated. The
original non-nested code is definitely simpler and easier to extend than the
nested code, but that's the transformation part of refactoring, not the reason
we are refactoring in the first place.&lt;/p&gt;

&lt;p&gt;You should always simplify your programming constructs so that they are more
intention revealing, but the meat of this refactoring is really in the domain
modelling and the tests. The original code had too many responsibilities, it
was hard to test, and it was hard to extend.&lt;/p&gt;

&lt;p&gt;When we needed to add a new search parameter and tried writing tests, we
realized how complex that was going to be and identified the need for a
refactoring. Allowing that context to guide us, resulted in an intention
revealing, testable and extensible solution.&lt;/p&gt;

     
   &lt;img src="http://feeds.feedburner.com/~r/ablogaboutcode/~4/_jF889Kcq_4" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://ablogaboutcode.com//2012/12/16/context-driven-refactoring</feedburner:origLink></entry>
 
 <entry>
   <title><![CDATA[Actually Always Refactoring]]></title>
   <link href="http://feedproxy.google.com/~r/ablogaboutcode/~3/hq2qV8jj_00/actually-always-refactoring" />
   <updated>2012-09-26T00:00:00-07:00</updated>
   <id>http://ablogaboutcode.com//2012/09/26/actually-always-refactoring</id>
   <content type="html">
     
     &lt;p&gt;I apologize, it's been a while since my last blog post. After being sick, doing
a lot of climbing, and some traveling, I attended &lt;a href="http://gogaruco.com/"&gt;GoGaRuCo 2012&lt;/a&gt;. It
was my first Ruby conference and it really opened my eyes to the active and
friendly community of Ruby. It gave me the boost I needed to sit down and write
another blog post.&lt;/p&gt;

&lt;p&gt;While on my hiatus, some comments trickled in on old blog posts. I do want to go
back and write updated versions of a few of my older articles. But today I want
to talk about Refactoring. I watched
&lt;a href="http://www.confreaks.com/videos/1071-cascadiaruby2012-therapeutic-refactoring"&gt;Therapeutic Refactoring by Katrina Owen&lt;/a&gt; the other day and it got me
thinking. While I was at GoGaRuCo I made a point of talking to people, and I
noticed the sly smile on their faces when I told them that, "I love
refactoring." They loved it too. So why don't we do more of it? If it's
therapeutic, if it's exciting and makes our code better, why aren't we always
refactoring?&lt;/p&gt;

&lt;p&gt;The reason, I think, is that along with that feeling of making our code awesome,
and coding purely to write code - no feature requests, there is a very real
feeling of &lt;a href="http://i.imgur.com/wGUTG.gif"&gt;impending doom&lt;/a&gt;. What if I pull on a thread that
unravels the system? What if I find out that refactoring the mailer actually
means I need to refactor the entire user object?&lt;/p&gt;

&lt;p&gt;We've all experienced that elated feeling after watching a great presentation
about refactoring. We head back to our keyboards, determined to make our code
better.  But in reality the systems we encounter are never as simple as the
examples we've just seen. The same tricks don't apply. Our objects aren't easy
to isolate, they aren't easy to test and are often so complex that it hurts to
even think about them.&lt;/p&gt;

&lt;p&gt;So what are we to do? Here are my thoughts.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Change your mindset. The goal is not to make the system &lt;strong&gt;perfect&lt;/strong&gt; and
&lt;strong&gt;easy&lt;/strong&gt; to understand. The goal is to make the system &lt;strong&gt;better&lt;/strong&gt; and
&lt;strong&gt;easier&lt;/strong&gt; to understand.&lt;/li&gt;
&lt;li&gt;It's okay to stop. Start small - even if it's not the final solution. Pick
one function, a few lines or even one line of code, and work on that first.
Think about creating a pull request with the changes you've just made. Would
your peers be able to reason about your changes?&lt;/li&gt;
&lt;li&gt;Don't be afraid to replace two messes with one mess (of equal and approximate
size). It's an evolving process and each piece of code does not need to be
final or pretty, it just needs to make your program better in one way. Take
another stab at refactoring duplication or complexity once the first step is
done. Too many times have I been sucked down the rat hole of trying to fix
all the messy parts at once.&lt;/li&gt;
&lt;li&gt;Find someone to share the experience with. Pair refactoring is a great way to
tackle the larger messes.&lt;/li&gt;
&lt;li&gt;Refactor all the time. When a new feature request comes along, see if you can
refactor first, in a separate commit. Then implement the feature. The goal
is to make the feature commit simpler.&lt;/li&gt;
&lt;li&gt;Demand refactoring. If you don't have the support to refactor then get that
support or find a company/client that values it. Refactoring makes code
better. Better code makes better products and better jobs.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;I hope that helps. And keep your spirits up. Refactoring isn't easy to do the
first time. Soon enough though, you'll begin to view it as "your feature
request." And it will be a regular part of your awesome day.&lt;/p&gt;

     
   &lt;img src="http://feeds.feedburner.com/~r/ablogaboutcode/~4/hq2qV8jj_00" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://ablogaboutcode.com//2012/09/26/actually-always-refactoring</feedburner:origLink></entry>
 
 <entry>
   <title><![CDATA[Fixtures and Factories]]></title>
   <link href="http://feedproxy.google.com/~r/ablogaboutcode/~3/lFuwFomq80M/fixtures-and-factories" />
   <updated>2012-06-21T00:00:00-07:00</updated>
   <id>http://ablogaboutcode.com//2012/06/21/fixtures-and-factories</id>
   <content type="html">
     
     &lt;p&gt;I recently converted a test suite that only used factories to a hybrid that uses
a combination of factories and fixtures. While I really like the simplicity and
cleanliness of factories, fixtures are simply unbeatable in some cases. I had
never really used both together in the same project, so I wanted to outline the
pros and cons of each, as well as how they work together.&lt;/p&gt;

&lt;h3&gt;Loading and Creating Data (Performance)&lt;/h3&gt;

&lt;p&gt;If you're loading all of your fixtures at the beginning of every test you're
missing out on one of their major benefits - loading a lot of data only once.
Instead, switch to loading all of your fixtures at the beginning of the entire
test suite, and then using transactions around each test for cleanup. That way
the base fixture data hangs around and each test takes care of cleaning up its
own changes. Since generating data can be more expensive than saving it to the
database, this simple change can result in dramatic performance gains.&lt;/p&gt;

&lt;p&gt;When using factories you have the benefit of creating only the data you want.
You may face some degraded performance caused by create operations, since you'll
have to process all those pesky callbacks, but you will benefit from having more
isolated tests and data.&lt;/p&gt;

&lt;h3&gt;Sharing and Customizing Data (Maintainability)&lt;/h3&gt;

&lt;p&gt;Fixtures often make customizations to data more complex. It's certainly a lot
harder to change fixtures because other tests depend on that very same data.
Certainly a slew of update statements is going to offset some of that
performance gain of having data pre-loaded as well.&lt;/p&gt;

&lt;p&gt;I often find that fixture based tests end up doing a lot of pre-assertions to
ensure that data is in the correct state. If that's the case in your tests it's
probably worth asking yourself if you could be using factories instead.&lt;/p&gt;

&lt;p&gt;One way to combat the fixture modification data is to combine fixtures and
factories. For instance, if you need to parse a large XML file and then create
a model from that data, do the parsing ahead of time, store it as a fixture, and
then use that model as a base for your factories.&lt;/p&gt;

&lt;p&gt;Factories should generally be an MVO, or minimally-viable-object. Data sharing
becomes a non-issue because each object adds only what it needs without worrying
about conflicting with other objects or tests.&lt;/p&gt;

&lt;h3&gt;Proximity of Data and Assertions (Ease of Use)&lt;/h3&gt;

&lt;p&gt;In the fixture approach it's often harder to find the data related to a test
because it's usually contained in another file. Sometimes this is unavoidable,
even with factories, but it's more often the case that fixture data lives in
some other file. If you are making an assertion about data, it's best to have
that data near the assertion.&lt;/p&gt;

&lt;p&gt;In the factory approach the relevant data declarations and modifications are
all contained in the same test file which makes the test cases easier to read
and follow.&lt;/p&gt;

&lt;h3&gt;Rule of Thumb&lt;/h3&gt;

&lt;p&gt;No approach is ever 100% better. In fact you'll probably see the greatest
performance gains and have the most fun by using both factories and fixtures.
It feels great to use the right tool for the job. If you use transactions to
clean your tests then the two approaches work very well together. Fixtures will
load data before the entire suite, and then each test will automatically
rollback any changes to fixture data, and remove any factories it created.&lt;/p&gt;

&lt;p&gt;As a rule of thumb, if data is expensive to create, it's probably better to use
fixtures. If data requires many small customizations, it's probably better to
use factories.&lt;/p&gt;

     
   &lt;img src="http://feeds.feedburner.com/~r/ablogaboutcode/~4/lFuwFomq80M" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://ablogaboutcode.com//2012/06/21/fixtures-and-factories</feedburner:origLink></entry>
 
 <entry>
   <title><![CDATA[Benchmark Your Bundle]]></title>
   <link href="http://feedproxy.google.com/~r/ablogaboutcode/~3/pdg-flrnVac/benchmark-your-bundle" />
   <updated>2012-05-03T00:00:00-07:00</updated>
   <id>http://ablogaboutcode.com//2012/05/03/benchmark-your-bundle</id>
   <content type="html">
     
     &lt;p&gt;Your Rails app takes anywhere from 20 seconds to a minute to boot.
&lt;a href="/2012/01/12/a-simple-rails-boot-time-improvement/"&gt;Maybe you've even tried to optimize your gem loading&lt;/a&gt;. But which
gems are actually causing you all that trouble? How can you pinpoint the gems to
delay, replace or optimize?&lt;/p&gt;

&lt;p&gt;Here's a simple script I wrote to benchmark the loading of each of the gems in
your Gemfile. A gist can be found &lt;a href="https://gist.github.com/2588879"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="c1"&gt;#!/usr/bin/env ruby&lt;/span&gt;

&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;benchmark&amp;#39;&lt;/span&gt;

&lt;span class="no"&gt;REGEXPS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;
  &lt;span class="sr"&gt;/^no such file to load -- (.+)$/i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="sr"&gt;/^Missing \w+ (?:file\s*)?([^\s]+.rb)$/i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="sr"&gt;/^Missing API definition file in (.+)$/i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="sr"&gt;/^cannot load such file -- (.+)$/i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="o"&gt;]&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;pull&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dep&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;required_file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;

  &lt;span class="k"&gt;begin&lt;/span&gt;
    &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dep&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;autorequire&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;dep&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;required_file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;
      &lt;span class="no"&gt;Kernel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;require&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="no"&gt;LoadError&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;dep&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;autorequire&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nil?&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;dep&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;include?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;-&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;begin&lt;/span&gt;
        &lt;span class="n"&gt;namespaced_file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dep&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gsub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;-&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;/&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="no"&gt;Kernel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;require&lt;/span&gt; &lt;span class="n"&gt;namespaced_file&lt;/span&gt;
      &lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="no"&gt;LoadError&lt;/span&gt;
        &lt;span class="no"&gt;REGEXPS&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=~&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;dep&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;autorequire&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="vg"&gt;$1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gsub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;-&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;/&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;namespaced_file&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="no"&gt;REGEXPS&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=~&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;dep&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;autorequire&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="vg"&gt;$1&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;required_file&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;rails/all&amp;#39;&lt;/span&gt;

&lt;span class="c1"&gt;# If you would prefer gems to incur the cost of autoloading&lt;/span&gt;
&lt;span class="c1"&gt;# Rails frameworks, then comment out this next line.&lt;/span&gt;
&lt;span class="ss"&gt;ActiveSupport&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="ss"&gt;:Autoload&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;eager_autoload!&lt;/span&gt;

&lt;span class="vg"&gt;$VERBOSE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;

&lt;span class="no"&gt;Benchmark&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bm&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="no"&gt;Bundler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setup&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dependencies&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;dependency&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;report&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dependency&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;ljust&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;pull&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dependency&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;All of the code in &lt;code&gt;#pull&lt;/code&gt; has been plucked right out of the
&lt;a href="https://github.com/carlhuda/bundler/blob/d351e68fa0a5df6de7aff587effce0801297848a/lib/bundler/runtime.rb#L51"&gt;Bundler require function&lt;/a&gt;. It's responsible for loading
a gem depending on its Gemfile configuration. It considers custom require paths,
and generally converts dashes into slashes if it can't load the file.&lt;/p&gt;

&lt;p&gt;The script then loads rails (&lt;code&gt;require 'rails/all'&lt;/code&gt;) - something you won't be
able to avoid either way. It also turns warnings off (&lt;code&gt;$VERBOSE = nil&lt;/code&gt;) so that
the benchmarking output looks a little nicer.&lt;/p&gt;

&lt;p&gt;Once that setup is complete, it loops through each of the gem dependencies and
requires them. Your output will probably look something like this:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="n"&gt;rails&lt;/span&gt;                  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000215&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;aws&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;s3&lt;/span&gt;                 &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;160000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;030000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;190000&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;182991&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;declarative_authoriza&lt;/span&gt;  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;850000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;120000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;970000&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;970152&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;fog&lt;/span&gt;                    &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;530000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;060000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;590000&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;589278&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;mysql2&lt;/span&gt;                 &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;010000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;010000&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;012&lt;/span&gt;&lt;span class="mi"&gt;908&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;nokogiri&lt;/span&gt;               &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;0002&lt;/span&gt;&lt;span class="mi"&gt;85&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;oauth2&lt;/span&gt;                 &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;140000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;010000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;150000&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;156330&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;rack&lt;/span&gt;                   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000232&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;rails_autolink&lt;/span&gt;         &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000&lt;/span&gt;&lt;span class="mi"&gt;854&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;rpm_contrib&lt;/span&gt;            &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;450000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;030000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;480000&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;482697&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;timezone&lt;/span&gt;               &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;010000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;010000&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;0076&lt;/span&gt;&lt;span class="mi"&gt;98&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;jquery&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rails&lt;/span&gt;           &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;010000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;010000&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;00&lt;/span&gt;&lt;span class="mi"&gt;8963&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;hike&lt;/span&gt;                   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;001602&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;sass&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rails&lt;/span&gt;             &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;370000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;020000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;390000&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;400510&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;coffee&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rails&lt;/span&gt;           &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;120000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;020000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;140000&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;136651&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;uglifier&lt;/span&gt;               &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;002760&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;capybara&lt;/span&gt;               &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;010000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;010000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;020000&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;0067&lt;/span&gt;&lt;span class="mi"&gt;83&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;capybara&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;webkit&lt;/span&gt;        &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;050000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;050000&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;053145&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;database_cleaner&lt;/span&gt;       &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;007077&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;gherkin&lt;/span&gt;                &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;070000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;010000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;080000&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;06&lt;/span&gt;&lt;span class="mi"&gt;8361&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;jasmine&lt;/span&gt;                &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;020000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;020000&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;025752&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;jasmine&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;headless&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;webk&lt;/span&gt;  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;0105&lt;/span&gt;&lt;span class="mi"&gt;95&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;launchy&lt;/span&gt;                &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;060000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;010000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;070000&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;060&lt;/span&gt;&lt;span class="mi"&gt;992&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;rspec&lt;/span&gt;                  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;350000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;030000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;380000&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;385097&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;rspec&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rails&lt;/span&gt;            &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000&lt;/span&gt;&lt;span class="mi"&gt;903&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;sham&lt;/span&gt;                   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;030000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;030000&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;025&lt;/span&gt;&lt;span class="mi"&gt;905&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;spork&lt;/span&gt;                  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;003553&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;timecop&lt;/span&gt;                &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;040000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;040000&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;041003&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;guard&lt;/span&gt;                  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;003354&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;rb&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;fsevent&lt;/span&gt;             &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;010000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;010000&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;004126&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;guard&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;spork&lt;/span&gt;            &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;00&lt;/span&gt;&lt;span class="mi"&gt;8679&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;test&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;unit&lt;/span&gt;              &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;130000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;010000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;140000&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;132788&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;webmock&lt;/span&gt;                &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;150000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;020000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;170000&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;167813&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;vcr&lt;/span&gt;                    &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;060000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;060000&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;06&lt;/span&gt;&lt;span class="mi"&gt;8362&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;I've condensed the output, but the total load time was 5 seconds. You can verify
that by benchmarking &lt;code&gt;Bundler.require&lt;/code&gt; in your own application. You'll also
notice that the declarative authorization gem took up approximately 1 second
(20% of the total time) to load.  Maybe it's a good candidate for an upgrade,
replacement or optimization.&lt;/p&gt;

     
   &lt;img src="http://feeds.feedburner.com/~r/ablogaboutcode/~4/pdg-flrnVac" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://ablogaboutcode.com//2012/05/03/benchmark-your-bundle</feedburner:origLink></entry>
 
 <entry>
   <title><![CDATA[Overwriting Console Output in Ruby]]></title>
   <link href="http://feedproxy.google.com/~r/ablogaboutcode/~3/xpI94rEEz2s/overwriting-console-output-in-ruby" />
   <updated>2012-04-16T00:00:00-07:00</updated>
   <id>http://ablogaboutcode.com//2012/04/16/overwriting-console-output-in-ruby</id>
   <content type="html">
     
     &lt;p&gt;I've always liked the way some long running console utilities display their
status without having to print a new line. For example the little spinner that
alternates displaying &lt;code&gt;|&lt;/code&gt;, &lt;code&gt;/&lt;/code&gt;, and &lt;code&gt;\&lt;/code&gt;. Or various internet utilities that
display the percentage of the file that has been downloaded.&lt;/p&gt;

&lt;p&gt;I recently wrote a utility to kick off parallel RSpec tasks on remote instances
and wanted to report the results back to the console after pinging the utility
every few seconds. I accomplished this with a cool little trick - the &lt;code&gt;\r&lt;/code&gt;.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;percent&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="nb"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="se"&gt;\r&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;percent&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;% complete&amp;quot;&lt;/span&gt;
  &lt;span class="nb"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;This little scripts begins by printing &lt;code&gt;10% complete&lt;/code&gt; and works up to
&lt;code&gt;100% complete&lt;/code&gt; in 10 percent increments. It's a cool way to notify the user
of your Ruby utility that the script is still progressing and that it hasn't
simply stopped dead in its tracks.&lt;/p&gt;

&lt;p&gt;One thing to keep in mind is that you are overwriting the previous line, so
if your previous line is of a longer length than the next one, you might need to
pad it with whitespace to cover up the last message.&lt;/p&gt;

     
   &lt;img src="http://feeds.feedburner.com/~r/ablogaboutcode/~4/xpI94rEEz2s" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://ablogaboutcode.com//2012/04/16/overwriting-console-output-in-ruby</feedburner:origLink></entry>
 
 <entry>
   <title><![CDATA[Respect the Active Record]]></title>
   <link href="http://feedproxy.google.com/~r/ablogaboutcode/~3/pm1uja2LvKs/respect-the-active-record" />
   <updated>2012-03-22T00:00:00-07:00</updated>
   <id>http://ablogaboutcode.com//2012/03/22/respect-the-active-record</id>
   <content type="html">
     
     &lt;p&gt;Here's some bad Rails code I often come across:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="no"&gt;Author&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp"&gt;public&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;score &amp;gt; ?&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;&lt;a href="/2012/02/27/understanding-the-law-of-demeter/"&gt;The problem isn't that we're chaining&lt;/a&gt;. Because we're only handling
&lt;code&gt;ActiveRecord::Relation&lt;/code&gt; objects, we aren't increasing the complexity or
responsibility of our code by the mere act of chaining. Chaining is a useful
programming pattern. However, we are increasing the complexity of our code by
making assumptions about the internal workings of &lt;code&gt;Author&lt;/code&gt; - we're breaking
encapsulation. Even if you feel that &lt;code&gt;ActiveRecord&lt;/code&gt; makes this easy to do, it
doesn't mean you should do it.&lt;/p&gt;

&lt;p&gt;We shouldn't know that authors have internal &lt;code&gt;score&lt;/code&gt; and &lt;code&gt;public&lt;/code&gt; attributes.
Keep in mind that this is different from being able to call &lt;code&gt;Author#score&lt;/code&gt; and
&lt;code&gt;Author#public&lt;/code&gt;, because in the former case, we actually "know" a lot more about
&lt;code&gt;Author&lt;/code&gt; and we make some unhealthy assumptions.&lt;/p&gt;

&lt;p&gt;In particular we make the assumption that these two statements are logically
equivalent:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="no"&gt;Author&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;select&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="no"&gt;Author&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;score&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;In short, this code is asking &lt;code&gt;Author&lt;/code&gt; to perform an operation based on an
assumed internal state. We are asking - not telling. That's not good.&lt;/p&gt;

&lt;p&gt;Telling &lt;code&gt;Author&lt;/code&gt; to give us this data looks very different:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="no"&gt;Author&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;with_public_account&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;with_score_above&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Having this kind of interface for our objects benefits us in a couple of
really awesome ways.&lt;/p&gt;

&lt;h3&gt;Readability&lt;/h3&gt;

&lt;p&gt;Using intentionally crafted public interfaces for your objects makes them easier
to read and more descriptive. This is usually a by-product of the simple fact
that you are naming your methods instead of using what is already there. Keep in
mind that ORMs were created as a general infrastructure for many different kinds
of applications. There is no need to expose that infrastructure to your own
application. It makes more sense to write &lt;code&gt;Author.with_public_account&lt;/code&gt; than it
does to write &lt;code&gt;Author.where(public: true)&lt;/code&gt;. The intent is clearly communicated.&lt;/p&gt;

&lt;h3&gt;Searchability&lt;/h3&gt;

&lt;p&gt;Searching for &lt;code&gt;where.*score&lt;/code&gt; in a code base can be tedious and might not result
in catching all the possible use cases. Code structured like this can easily be
missed:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="n"&gt;conditions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;score&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="no"&gt;Author&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conditions&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;By contrast, searching for &lt;code&gt;with_score_above&lt;/code&gt; is much more likely to yield
usable and accurate results. Obviously having a full test suite helps alleviate
this kind of a refactoring, but that doesn't mean you should make it difficult
for others to track down your handiwork.&lt;/p&gt;

&lt;h3&gt;Changeability&lt;/h3&gt;

&lt;p&gt;Have a more explicit interface makes it easier to change our ORM from
&lt;code&gt;ActiveRecord&lt;/code&gt; if we ever choose to. It makes it easier to make small attribute
level changes, like renaming score. That's because we now only need to modify
the &lt;code&gt;Author&lt;/code&gt; object, not every piece of code that filters authors on score. You
could imagine a future implementation that looks something like this:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;AuthorRelation&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;authors&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@authors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;authors&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;with_public_account&lt;/span&gt;
    &lt;span class="vi"&gt;@authors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@authors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;select&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;public?&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;paid?&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nb"&gt;self&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;with_score_above&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@authors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@authors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;select&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cached_score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nb"&gt;self&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;If you're thinking - why would I ever want to change something like that? Then
you've missed the point. This isn't a pre-optimization, this is a philosophy for
creating persistence objects that behave like simple Ruby objects, without
exception. It's a slippery slope to assume that some objects just aren't going
to change and that kind of thinking causes headaches for the rest of your code
and for other developers working with code you've written.&lt;/p&gt;

&lt;p&gt;What if we didn't change the entire object; what if we simply denormalized and
indexed a flag that combined &lt;code&gt;score&lt;/code&gt; and &lt;code&gt;public&lt;/code&gt;? Our carefully crafted public
interface would allow us to make use of this new column, whereas being tied to
the &lt;code&gt;where&lt;/code&gt; way of doing things would mean having to modify a lot more code.&lt;/p&gt;

&lt;h3&gt;Testability&lt;/h3&gt;

&lt;p&gt;It's easier to begin building an application without being tied to the
&lt;code&gt;ActiveRecord&lt;/code&gt; way of doing things. This frees us up to write isolated tests and
hide &lt;code&gt;ActiveRecord&lt;/code&gt; as a true implementation detail, rather than making it a
central part of our application. No object or collection of objects should
dominate your code. Some objects might be more or less connected, but that
doesn't mean they should be required to test one another. Isolation is a great
thing.&lt;/p&gt;

&lt;h3&gt;Summary&lt;/h3&gt;

&lt;p&gt;Respect the &lt;code&gt;ActiveRecord&lt;/code&gt;. Let it do what it does best, as a piece of
infrastructure and as a 3rd party library. Its way of doing things and its
method signatures should not infect the rest of your application. It does what
it does best when it's limited to and hidden inside of your &lt;code&gt;ActiveRecord::Base&lt;/code&gt;
objects.&lt;/p&gt;

     
   &lt;img src="http://feeds.feedburner.com/~r/ablogaboutcode/~4/pm1uja2LvKs" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://ablogaboutcode.com//2012/03/22/respect-the-active-record</feedburner:origLink></entry>
 
 <entry>
   <title><![CDATA[Reducing Metadata Queries in Resque]]></title>
   <link href="http://feedproxy.google.com/~r/ablogaboutcode/~3/GqqeuqTCkWw/reducing-metadata-queries-in-resque" />
   <updated>2012-03-08T00:00:00-08:00</updated>
   <id>http://ablogaboutcode.com//2012/03/08/reducing-metadata-queries-in-resque</id>
   <content type="html">
     
     &lt;p&gt;If you're using Resque with your Rails application you may have noticed a large
number of &lt;code&gt;SHOW TABLES&lt;/code&gt;, &lt;code&gt;SHOW CREATE TABLE&lt;/code&gt; and &lt;code&gt;SHOW FIELDS FROM&lt;/code&gt; queries in
your log while a job is processing. The most frustrating thing about this is
that they probably don't appear in your web requests.&lt;/p&gt;

&lt;p&gt;The solution for this is quite simple. Because Resque forks its processes before
each job is executed it only maintains - in memory - the cached metadata that
was loaded before the fork. To resolve this issue we need to load all this
metadata before the Resque job forks. Fortunately Resque provides a
&lt;code&gt;before_first_fork&lt;/code&gt; hook which allows us to execute code before the first job,
hence allowing us to pre-load a lot of metadata into memory.&lt;/p&gt;

&lt;p&gt;Add the following to an initializer file, like &lt;code&gt;config/initializers/resque.rb&lt;/code&gt;.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="c1"&gt;# Pre-load all the ActiveRecord column metadata.&lt;/span&gt;
&lt;span class="no"&gt;Resque&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;before_first_fork&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="ss"&gt;ActiveRecord&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="ss"&gt;:Base&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:subclasses&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;klass&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;klass&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;abstract_class?&lt;/span&gt;
      &lt;span class="n"&gt;klass&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;primary_key&lt;/span&gt;
      &lt;span class="n"&gt;klass&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;columns&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;This code loads all the &lt;code&gt;ActiveRecord&lt;/code&gt; subclasses and then, if they have a table
associated with them, loads their column and primary key information. The column
information is associated with the &lt;code&gt;SHOW FIELDS FROM&lt;/code&gt; queries and the primary
key information is associated with the &lt;code&gt;SHOW TABLES&lt;/code&gt; query.&lt;/p&gt;

&lt;p&gt;A note of caution. If you happen to use a gem that also hooks into the Resque
pre-fork process you may run into issues. Currently Resque only supports a
single block/code snippet per hook. Hopefully this issue will be resolved in
&lt;a href="https://github.com/defunkt/resque/pull/537"&gt;this pull request&lt;/a&gt; that I created yesterday.&lt;/p&gt;

&lt;p&gt;But if you are itching to get this working right away you can use my branch that
contains the updates by adding the following to your Gemfile:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;resque&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;git&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;git://github.com/panthomakos/resque&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;branch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;hooks&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;This code allows Resque to keep track of, and register, multiple fork hooks, so
gems like &lt;a href="https://github.com/newrelic/rpm_contrib"&gt;rpm contrib&lt;/a&gt;, which also hook into the Resque boot process, can
co-exist with your hooks.&lt;/p&gt;

&lt;p&gt;Enjoy the faster Resque processing!&lt;/p&gt;

     
   &lt;img src="http://feeds.feedburner.com/~r/ablogaboutcode/~4/GqqeuqTCkWw" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://ablogaboutcode.com//2012/03/08/reducing-metadata-queries-in-resque</feedburner:origLink></entry>
 
 <entry>
   <title><![CDATA[Understanding The Law of Demeter]]></title>
   <link href="http://feedproxy.google.com/~r/ablogaboutcode/~3/jLnqOCR8zU4/understanding-the-law-of-demeter" />
   <updated>2012-02-27T00:00:00-08:00</updated>
   <id>http://ablogaboutcode.com//2012/02/27/understanding-the-law-of-demeter</id>
   <content type="html">
     
     &lt;p&gt;The Law of Demeter is often stated as, "only talk to your immediate friends."
In Object Oriented languages that use a dot as the field identifier this is
often simplified to, "only use one dot." While this is an interesting heuristic
of sorts, it's a very poor rule to follow because it's almost never that simple.
This is often hard to describe to new programmers, who tend to seek a set of
rules to help them advance their skills. The reality is that there exists no
simple rule you can follow, it's really more of a sense. The best way I've been
able to come up with to summarize the Law of Demeter is, "don't operate on
objects that you might not understand."&lt;/p&gt;

&lt;p&gt;To illustrate this, let's consider things from the perspective of the calling
object, &lt;code&gt;self&lt;/code&gt; in Ruby. Say we have an expression &lt;code&gt;self.x.y&lt;/code&gt;. Then we should be
less likely to tell the receiver, &lt;code&gt;x&lt;/code&gt;, to do &lt;code&gt;y&lt;/code&gt;, as it becomes harder to
understand &lt;code&gt;x&lt;/code&gt; or as it becomes more likely for &lt;code&gt;x&lt;/code&gt; to change.&lt;/p&gt;

&lt;p&gt;In the simplest case the receiver is the caller. This case is equivalent to the
original and stricter Law of Demeter. So in the expression &lt;code&gt;self.x&lt;/code&gt;, &lt;code&gt;self&lt;/code&gt; is
the caller and the receiver. And since we have a high level of confidence in our
own methods, we can call &lt;code&gt;x&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In the more general case, given &lt;code&gt;self.x.y.z&lt;/code&gt;, if our level of confidence in &lt;code&gt;x&lt;/code&gt;
is low, we should not be telling &lt;code&gt;x&lt;/code&gt; to do &lt;code&gt;y&lt;/code&gt;. And this carries forward - if,
from the perspective of &lt;code&gt;self&lt;/code&gt;, we do not have high confidence in &lt;code&gt;y&lt;/code&gt;, then we
should not be telling it to do &lt;code&gt;z&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;A Ruby Example&lt;/h1&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;,&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Using the original definition this code violates the law since the call to
&lt;code&gt;Array#join&lt;/code&gt; is a case of talking to a non-immediate friend. &lt;code&gt;[1,2,3,4]&lt;/code&gt; is
the immediate friend of &lt;code&gt;self&lt;/code&gt; in this case. The call to &lt;code&gt;Array#map&lt;/code&gt; is fine,
but the result of that operation is not an immediate friend, so we can't tell
it to do anything.&lt;/p&gt;

&lt;p&gt;Fixing this code leads us down a rat-hole and is highly non-productive. It most
likely results in greatly increasing the complexity of an otherwise pretty
simple piece of code. In fact this simple example demonstrates that under a
strict version of the Law of Demeter we can't chain methods at all.&lt;/p&gt;

&lt;p&gt;To solve this chaining problem, most people tend to introduce this caveat:
'your friend's friend is also your friend if she is of the same type as your
your friend'. In our previous example &lt;code&gt;Array#map&lt;/code&gt; returns an array and we
started with an array, so we can act on the result of that operation. But we
can't act on the string that &lt;code&gt;Array#join&lt;/code&gt; returns because we didn't start with a
string.&lt;/p&gt;

&lt;p&gt;This caveat is not enough though. In some cases it's too restrictive and in
others it simply is not restrictive enough.&lt;/p&gt;

&lt;h1&gt;An Example of Complex Code&lt;/h1&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="no"&gt;User&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;active&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="no"&gt;Group&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;owner_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;grep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Rails&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;This is only slightly a violation of the Law of Demeter, but it is definitely a
violation of the fuzzier version I introduced earlier. The issue here is really
the complexity of the code. There is a good chance that the code related to
either &lt;code&gt;User&lt;/code&gt; or &lt;code&gt;Group&lt;/code&gt; will change and it's not feasible to expect that we
will know when that happens. Additionally, this code assumes that we have
confidence in each operation in the chain, and that's not something I feel
comfortable with. Not because any one call in the chain is complex, but because
by the time we get to the call that deals with grepping for 'Rails', we have
already lost track of what we were doing. Take a look at a simplified version of
this code that addresses these issues.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;active&lt;/span&gt;

&lt;span class="no"&gt;Group&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;owned_by_any_of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;with_name_matching&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Rails&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;That's the beauty of the Law of Demeter. It advocates writing code like this
over the first example. It's not really about how many dots you are using, it's
about the responsibility of the objects in your code. How many objects is the
caller responsible for understanding and keeping track of? How much logic is the
caller encompassing? And is the logical path of the chain easy to follow?&lt;/p&gt;

&lt;h1&gt;An Example of Unknown Output&lt;/h1&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;try&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;If you find yourself writing code like this, then you're in violation of the
Law of Demeter. Both versions. And this code should be simplified.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;group_name&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Let's take a look at a slight variation to the first example.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;In this code there's a good chance that you're in the clear. In fact this code
is quite easy to understand, and if we actually do have confidence that &lt;code&gt;group&lt;/code&gt;
exists and that we'll understand the output, it's perfectly fine to use this
expression.&lt;/p&gt;

&lt;h1&gt;Summary&lt;/h1&gt;

&lt;p&gt;The Law of Demeter is not a law, and it's not as simple as counting the number
of dots in your statements. It's really about developing a sense for
constructing your code so that each object is confident in what it is telling
other objects to do, and what it is responsible for understanding. Hopefully
this post clarified the Law of Demeter for you.&lt;/p&gt;

     
   &lt;img src="http://feeds.feedburner.com/~r/ablogaboutcode/~4/jLnqOCR8zU4" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://ablogaboutcode.com//2012/02/27/understanding-the-law-of-demeter</feedburner:origLink></entry>
 
 <entry>
   <title><![CDATA[From WordPress to GitHub Pages]]></title>
   <link href="http://feedproxy.google.com/~r/ablogaboutcode/~3/Ky7BHS9F-gc/from-wordpress-to-github-pages" />
   <updated>2012-02-21T00:00:00-08:00</updated>
   <id>http://ablogaboutcode.com//2012/02/21/from-wordpress-to-github-pages</id>
   <content type="html">
     
     &lt;p&gt;A little while ago I migrated ablogaboutcode.com from a &lt;a href="http://www.wordpress.com"&gt;wordpress.com&lt;/a&gt;
hosted site to a &lt;a href="https://github.com/mojombo/jekyll"&gt;jekyll&lt;/a&gt;-generated and &lt;a href="http://pages.github.com/"&gt;github-pages&lt;/a&gt;-hosted
site. This is a move I've been wanting to make for quite some time now. My
reasons were primarily due to control over content and style combined with
wanting to own the code behind it all.&lt;/p&gt;

&lt;p&gt;Wodpress served me well when I was first getting started - and trying to decide
if I wanted to commit to blogging and producing content on a regular basis. It
was also a great way to familiarize myself with a full-featured blogging
platform and what that could potentially provide. But wordpress.com imposes some
constraints around commenting and formatting that I wasn't going to be happy
with in the longer term.&lt;/p&gt;

&lt;p&gt;I could have used my own wordpress installation, but I think that as a blogging
platform it's overly complex and slow. And I like coding. Moving to jekyll means
that I can write my blog posts in vim, using markdown, and then easily check the
results on a local server - no internet required. I'm actually writing this
particular blog post on a bus with non-functioning internet.&lt;/p&gt;

&lt;p&gt;The migration process was relatively painless. Disqus provides a great import
tool for migrating comments from wordpress. Transferring my domain registration
from wordpress.com to GoDaddy was also a simple process.&lt;/p&gt;

&lt;p&gt;The hardest part of the move was converting my posts into markdown. There are
lots of tools to do this but in the end I still had to go through and clean up
each post individually. This consisted primarily of converting code and
highlight blocks to pygments and making sure that the formatting of my content
was to my liking - 80 character line lengths and pretty. Vim macros really made
this part of the process fast.&lt;/p&gt;

&lt;p&gt;I started with the &lt;a href="http://tom.preston-werner.com/"&gt;Tom Preston&lt;/a&gt; css template and added some of my own
customizations for Disqus and a more fluid layout. I've also added a floating
share bar which I plan on expanding in the future.&lt;/p&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;

     
   &lt;img src="http://feeds.feedburner.com/~r/ablogaboutcode/~4/Ky7BHS9F-gc" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://ablogaboutcode.com//2012/02/21/from-wordpress-to-github-pages</feedburner:origLink></entry>
 
 <entry>
   <title><![CDATA[The Ruby Global Interpreter Lock]]></title>
   <link href="http://feedproxy.google.com/~r/ablogaboutcode/~3/AX_5vxRGgU4/the-ruby-global-interpreter-lock" />
   <updated>2012-02-06T00:00:00-08:00</updated>
   <id>http://ablogaboutcode.com//2012/02/06/the-ruby-global-interpreter-lock</id>
   <content type="html">
     
     &lt;p&gt;All of the code in this post was executed on Ruby 1.9.3 in February 2012.
Ruby MRI refers to the C implementation of Ruby.&lt;/p&gt;

&lt;p&gt;The Ruby MRI Global Interpreter Lock (GIL) is often misunderstood. Programmers
hear "global" and "lock" and assume that threaded code won’t execute with any
concurrency. While I'm hopeful that it will eventually be removed (jRuby and
Rubinius Hydra) the GIL is not all that bad, and the state of Ruby MRI
threading can only improve.&lt;/p&gt;

&lt;p&gt;The reason I say it's not that bad is that the GIL only applies to Ruby
operations. That means it really only applies to the work that Ruby is doing.
Which makes sense, because it exists to protect the integrity of the Ruby
Virtual Machine.&lt;/p&gt;

&lt;p&gt;But besides Ruby operations, what kind of other work is there? In a typical web
application – a lot. When you're querying the database, disk or memcached Ruby
isn't doing work, which means you aren't invoking the GIL. Let's take a look at
a simple example.&lt;/p&gt;

&lt;h2&gt;I/O Operations&lt;/h2&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;benchmark&amp;#39;&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;mysql2&amp;#39;&lt;/span&gt;

&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;Mysql2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="ss"&gt;:Client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;
&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;Mysql2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="ss"&gt;:Client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;

&lt;span class="no"&gt;Benchmark&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bm&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;report&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;w/o&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;SELECT SLEEP(1)&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;SELECT SLEEP(1)&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;report&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;with&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;SELECT SLEEP(1)&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;SELECT SLEEP(1)&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;
    &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

       &lt;span class="n"&gt;user&lt;/span&gt;     &lt;span class="nb"&gt;system&lt;/span&gt;      &lt;span class="n"&gt;total&lt;/span&gt;        &lt;span class="n"&gt;real&lt;/span&gt;
&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt;  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;  &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;002&lt;/span&gt;&lt;span class="mi"&gt;874&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;with&lt;/span&gt;  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;  &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;00165&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;In this example Ruby passed the SQL query into a C program that waited on the
database to respond. During that time Ruby released the GIL because it was not
performing any work. Querying the database is an I/O operation and the GIL does
not factor in to I/O operations. That means that the Ruby interpreter had the
freedom to process more than one thread at a time. To understand the difference,
let’s take a look at this next example.&lt;/p&gt;

&lt;h2&gt;Ruby Operations&lt;/h2&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;benchmark&amp;#39;&lt;/span&gt;

&lt;span class="no"&gt;Benchmark&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bm&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;report&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;w/o&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="mi"&gt;10_000_000&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;times&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;report&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;with&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mi"&gt;5_000_000&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;times&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mi"&gt;5_000_000&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;times&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;
    &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

       &lt;span class="n"&gt;user&lt;/span&gt;     &lt;span class="nb"&gt;system&lt;/span&gt;      &lt;span class="n"&gt;total&lt;/span&gt;        &lt;span class="n"&gt;real&lt;/span&gt;
&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt;  &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;300000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt;   &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;300000&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;  &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;312023&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;with&lt;/span&gt;  &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;330000&lt;/span&gt;   &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;000000&lt;/span&gt;   &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;330000&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;  &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;338784&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;In this example Ruby had to perform computations and modify data, so threading
provided no benefit since the GIL was active. In fact attempting to parallelize
these computations incurred the overhead of creating two threads.&lt;/p&gt;

&lt;h2&gt;Summary&lt;/h2&gt;

&lt;p&gt;The Ruby GIL only applies to non I/O operations. While removal of the GIL would
allow my last example to take full advantage of native threads, Ruby threading
is not in a state of non-existence. Ruby threading does work, it's just hasn't
evolved to the same level as other languages yet.&lt;/p&gt;

&lt;p&gt;Hopefully this clarified the GIL and threading. At this point in time
event-driven ruby, threads and fibers provide a great deal of concurrency in
Ruby despite the GIL. I believe in the future this will only improve –
particularly for threads. The GitHub Gist of this code also includes another
example using Ruby’s sleep function.&lt;/p&gt;

     
   &lt;img src="http://feeds.feedburner.com/~r/ablogaboutcode/~4/AX_5vxRGgU4" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://ablogaboutcode.com//2012/02/06/the-ruby-global-interpreter-lock</feedburner:origLink></entry>
 
 <entry>
   <title><![CDATA[A Simple Rails Boot Time Improvement]]></title>
   <link href="http://feedproxy.google.com/~r/ablogaboutcode/~3/_QcRMtHVTfc/a-simple-rails-boot-time-improvement" />
   <updated>2012-01-12T00:00:00-08:00</updated>
   <id>http://ablogaboutcode.com//2012/01/12/a-simple-rails-boot-time-improvement</id>
   <content type="html">
     
     &lt;p&gt;This simple improvement can have varying effects on the application depending on
how many Gems you require. Before you actually jump into this I would definitely
recommend having a full unit-test suite. Anytime you're refactoring code or
changing how dependencies are loaded you want to be sure you aren't messing
things up.&lt;/p&gt;

&lt;p&gt;The examples from this post were performed on a Rails 3.1.3 application running
on Ruby 1.9.3 on a Mac OSX PowerBook. The Gemfile contained about 65 gems in
development mode.&lt;/p&gt;

&lt;p&gt;The first step to any performance improvement endeavor is to benchmark. It's
also important that you perform this step more than once - this gives you a more
consistent reading as the first run can often be inflated above the average
run-time.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="o"&gt;(&lt;/span&gt;master&lt;span class="o"&gt;)&lt;/span&gt; % &lt;span class="nb"&gt;time &lt;/span&gt;bundle &lt;span class="nb"&gt;exec &lt;/span&gt;rake environment
bundle &lt;span class="nb"&gt;exec &lt;/span&gt;rake environment  29.09s user 2.44s system 61% cpu 51.570 total

&lt;span class="o"&gt;(&lt;/span&gt;master&lt;span class="o"&gt;)&lt;/span&gt; % &lt;span class="nb"&gt;time &lt;/span&gt;bundle &lt;span class="nb"&gt;exec &lt;/span&gt;rake environment
bundle &lt;span class="nb"&gt;exec &lt;/span&gt;rake environment  28.02s user 1.77s system 98% cpu 30.184 total

&lt;span class="o"&gt;(&lt;/span&gt;master&lt;span class="o"&gt;)&lt;/span&gt; % &lt;span class="nb"&gt;time &lt;/span&gt;bundle &lt;span class="nb"&gt;exec &lt;/span&gt;rake environment
bundle &lt;span class="nb"&gt;exec &lt;/span&gt;rake environment  28.24s user 1.84s system 98% cpu 30.632 total
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Now let's take a look at your application.rb and measure how much time we're
spending loading gems.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="c1"&gt;# application.rb&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;benchmark&amp;#39;&lt;/span&gt;

&lt;span class="no"&gt;Benchmark&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bm&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;report&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;defined?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Bundler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="no"&gt;Bundler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;groups&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:assets&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="sx"&gt;%w(development test)&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;When we run this benchmark we get an interesting result:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="o"&gt;(&lt;/span&gt;master&lt;span class="o"&gt;)&lt;/span&gt; % &lt;span class="nb"&gt;time &lt;/span&gt;bundle &lt;span class="nb"&gt;exec &lt;/span&gt;rake environment
       user     system      total        real
  10.910000   0.900000  11.810000 &lt;span class="o"&gt;(&lt;/span&gt; 11.969414&lt;span class="o"&gt;)&lt;/span&gt;
bundle &lt;span class="nb"&gt;exec &lt;/span&gt;rake environment  27.99s user 1.76s system 98% cpu 30.199 total

&lt;span class="o"&gt;(&lt;/span&gt;master&lt;span class="o"&gt;)&lt;/span&gt; % &lt;span class="nb"&gt;time &lt;/span&gt;bundle &lt;span class="nb"&gt;exec &lt;/span&gt;rake environment
       user     system      total        real
  10.770000   0.900000  11.670000 &lt;span class="o"&gt;(&lt;/span&gt; 11.721163&lt;span class="o"&gt;)&lt;/span&gt;
bundle &lt;span class="nb"&gt;exec &lt;/span&gt;rake environment  27.71s user 1.78s system 99% cpu 29.721 total
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;We're spending about 1/3 of our time in this &lt;code&gt;Bundler.require&lt;/code&gt; statement. The
reason for this is that Bundler is loading and executing every gem in your
Gemfile, and with 65 gems that's a hefty portion of time spent executing code.
We can confirm this by benchmarking the two parts of &lt;code&gt;Bundler.require&lt;/code&gt; -
&lt;code&gt;Bundler::Runtime#setup&lt;/code&gt; and &lt;code&gt;Bundler::Runtime#require&lt;/code&gt;. I'm going to leave out
the details, but require is the offender here, and that makes sense. Bundler
isn't really doing anything fancy, but it is responsible for executing all those
gems you've collected in your Gemfile.&lt;/p&gt;

&lt;p&gt;Here's a simple way to improve that.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
Begin with a minor gem. By that I mean a gem that is only used in one or two
files or that has minimal impact on your application. That’s usually a good
starting point because the effects are minor. Also, don’t pick a gem that rails
automatically includes anyways – that won’t work.
  &lt;/li&gt;
  &lt;li&gt;
Check if the gem has Railties. One way to do this is to navigate to its
source code directory and search for uses of ‘Railtie’.

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="sb"&gt;`&lt;/span&gt;bundle list flickr_fu&lt;span class="sb"&gt;`&lt;/span&gt;
find . | xargs grep Railtie
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

  &lt;/li&gt;
  &lt;li&gt;
If you see an output then that gem uses Railties and you need to move on to
another gem for this optimization.
  &lt;/li&gt;
  &lt;li&gt;
If you don’t see an output then the gem does not use Railties. That means it
doesn’t hook into the Rails initialization process, which in turn means that it
does not need to be required during the application boot. So, let’s take care of
that – tell bundler to not require that gem.

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="c1"&gt;# Gemfile&lt;/span&gt;
&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;flickr_fu&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;require&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

  &lt;/li&gt;
  &lt;li&gt;
Find uses of that gem, and manually require the gem in those files.

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="c1"&gt;# lib/flickr_decorator.rb&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;flickr_fu&amp;#39;&lt;/span&gt;

&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;FlickrDecorator&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;.&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

  &lt;/li&gt;
  &lt;li&gt;Run your tests.&lt;/li&gt;
  &lt;li&gt;Run your benchmarks.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;You probably won't notice a difference form a few measly gems, but once you're
done with the entire process you'll be looking at a significant time
improvement. In this particular application I was able to shave 10s off each
application boot. There's an added benefit that you now know exactly which files
are using which gems. This makes it easier to test these files in isolation and
measure the impact/use of a gem. Enjoy!&lt;/p&gt;

     
   &lt;img src="http://feeds.feedburner.com/~r/ablogaboutcode/~4/_QcRMtHVTfc" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://ablogaboutcode.com//2012/01/12/a-simple-rails-boot-time-improvement</feedburner:origLink></entry>
 
 <entry>
   <title><![CDATA[The & Operator in Ruby]]></title>
   <link href="http://feedproxy.google.com/~r/ablogaboutcode/~3/QTBWZSsLVYs/the-ampersand-operator-in-ruby" />
   <updated>2012-01-04T00:00:00-08:00</updated>
   <id>http://ablogaboutcode.com//2012/01/04/the-ampersand-operator-in-ruby</id>
   <content type="html">
     
     &lt;p&gt;I'm going to assume that you are already familiar with the double ampersand
operator in Ruby - the logical AND. This post is going to focus on all uses of
the single ampersand operator. &amp;amp; can be quite confusing because it has a
different meaning depending on the context in which it's used. In fact, both
unary (&lt;code&gt;&amp;amp;object&lt;/code&gt;) and binary (&lt;code&gt;object &amp;amp; object&lt;/code&gt;) operations have meaning in
Ruby. To understand these let's look at the uses of &amp;amp; in core Ruby.&lt;/p&gt;

&lt;h3&gt;The Binary Ampersand&lt;/h3&gt;

&lt;p&gt;In Ruby 1.9.3 there are three uses for the binary ampersand operator.&lt;/p&gt;

&lt;h4&gt;Bitwise AND&lt;/h4&gt;

&lt;p&gt;Bitwise AND is the binary bit-by-bit equivalent of boolean AND. So binary
&lt;code&gt;101 &amp;amp; 100 = 100&lt;/code&gt; and binary &lt;code&gt;101 &amp;amp; 001 = 001&lt;/code&gt;. &amp;amp; is defined as a bitwise AND
operator for &lt;code&gt;Bignum&lt;/code&gt;, &lt;code&gt;Fixnum&lt;/code&gt; and &lt;code&gt;Process::Status&lt;/code&gt; and simply converts the
integer into a binary representation and performs a bitwise AND on that
representation. &lt;code&gt;Process::Status&lt;/code&gt; converts the process status number to a
&lt;code&gt;Fixnum&lt;/code&gt; and uses that to perform the operation.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="irb"&gt;&lt;span class="gp"&gt;irb(main):001:0&amp;gt; &lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="mi"&gt;13&lt;/span&gt;
&lt;span class="go"&gt;=&amp;gt; 12&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The result of this operation can be clearly seen by converting the numbers to
their binary representations.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="irb"&gt;&lt;span class="gp"&gt;irb(main):001:0&amp;gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &amp;amp; &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; = &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="go"&gt;=&amp;gt; &amp;quot;1110 &amp;amp; 1101 = 1100&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h4&gt;Set Intersection&lt;/h4&gt;

&lt;p&gt;Possibly the simplest use of the binary &amp;amp; operator is in the &lt;code&gt;Array&lt;/code&gt; class. &amp;amp;
is the set-intersection operator, which means the result is a collection of the
common elements in both arrays.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="irb"&gt;&lt;span class="gp"&gt;irb(main):001:0&amp;gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="go"&gt;=&amp;gt; [1, 2]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h4&gt;Boolean AND&lt;/h4&gt;

&lt;p&gt;On the &lt;code&gt;FalseClass&lt;/code&gt;, &lt;code&gt;NilClass&lt;/code&gt; and &lt;code&gt;TrueClass&lt;/code&gt; binary &amp;amp; is the equivalent of
the boolean AND. Keep in mind this does not work like the &amp;amp;&amp;amp; operator, since it
is only defined on these three classes.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="n"&gt;irb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="mo"&gt;001&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
&lt;span class="n"&gt;irb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="mo"&gt;002&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
&lt;span class="n"&gt;irb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="mo"&gt;003&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="no"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
&lt;span class="n"&gt;irb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="mo"&gt;004&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;NoMethodError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;undefined&lt;/span&gt; &lt;span class="nb"&gt;method&lt;/span&gt; &lt;span class="sb"&gt;`&amp;amp;&amp;#39; for #&amp;lt;Object:0x007f9e7ac96420&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h4&gt;Custom Definitions&lt;/h4&gt;

&lt;p&gt;When the binary ampersand operator is invoked (&lt;code&gt;First &amp;amp; Second&lt;/code&gt;) Ruby executes
the definition from the first object (&lt;code&gt;First#&amp;amp;&lt;/code&gt;). You can write your own binary
ampersand method easily. When I do, I try to keep the first two core Ruby uses
in mind - bitwise AND and set intersection. I don't like using logical AND
because it is already covered by the &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; operator and is only defined on
&lt;code&gt;true&lt;/code&gt;, &lt;code&gt;false&lt;/code&gt; and &lt;code&gt;nil&lt;/code&gt;, which are special classes. Here is a custom example
that works like set intersection.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="no"&gt;DNA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Struct&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:chain&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;triples&lt;/span&gt;
    &lt;span class="n"&gt;chain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;//&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each_slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_a&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dna&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;triples&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;dna&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;triples&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;triple&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;triple&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;




&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="irb"&gt;&lt;span class="gp"&gt;irb(main):001:0&amp;gt; &lt;/span&gt;&lt;span class="no"&gt;DNA&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;AGGTTACCA&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="no"&gt;DNA&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;TTAAGGCCC&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="go"&gt;=&amp;gt; [&amp;quot;AGG&amp;quot;, &amp;quot;TTA&amp;quot;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h3&gt;The Unary &amp;amp;&lt;/h3&gt;

&lt;p&gt;The Unary &amp;amp; is a little more complex. It is almost the equivalent of calling
&lt;code&gt;#to_proc&lt;/code&gt; on the object, but not quite. To understand it let's go over some
background first. In Ruby you have two kinds of code blocks, Blocks and Procs.
The two are very closely related but have some important differences. You can
define and reference Procs and assign them to variables. Blocks are always
related to a method call and can't be defined outside of that context. The way
you tell them apart is that Procs are always preceded by &lt;code&gt;Proc.new&lt;/code&gt;, &lt;code&gt;proc&lt;/code&gt;,
&lt;code&gt;lambda&lt;/code&gt; or &lt;code&gt;-&amp;gt;()&lt;/code&gt; when they are defined.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="c1"&gt;# A block that is passed to the each function on the [1,2,3] Array.&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# A proc assigned to a variable.&lt;/span&gt;
&lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Proc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;All methods have one and only one implicit Block argument, whether you use it or
not. You can access it by calling &lt;code&gt;yield&lt;/code&gt; in the method body.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;two&lt;/span&gt;
  &lt;span class="k"&gt;yield&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;




&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="irb"&gt;&lt;span class="gp"&gt;irb(main):001:0&amp;gt; &lt;/span&gt;&lt;span class="n"&gt;two&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="go"&gt;=&amp;gt; 4&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Blocks are pretty useless outside of function calls though, for instance you
can't just define one.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="irb"&gt;&lt;span class="gp"&gt;irb(main):001:0&amp;gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="go"&gt;=&amp;gt; SyntaxError: syntax error, unexpected &amp;#39;|&amp;#39;, expecting &amp;#39;}&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;But you can define and reference Procs.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="irb"&gt;&lt;span class="gp"&gt;irb(main):001:0&amp;gt; &lt;/span&gt;&lt;span class="no"&gt;Proc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="go"&gt;=&amp;gt; #&amp;lt;Proc:0x007f9e7ab766a8@(pry):30&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Procs fall into two categories. Procs that are &lt;code&gt;lambda?&lt;/code&gt;, lambda procs, and
Procs that aren't, simple procs. Lambdas are defined using &lt;code&gt;lambda&lt;/code&gt; or &lt;code&gt;-&amp;gt;()&lt;/code&gt;
and whereas simple procs are defined using &lt;code&gt;Proc.new&lt;/code&gt; or &lt;code&gt;proc&lt;/code&gt;.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="irb"&gt;&lt;span class="gp"&gt;irb(main):001:0&amp;gt; &lt;/span&gt;&lt;span class="nb"&gt;lambda&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="go"&gt;=&amp;gt; #&amp;lt;Proc:0x007f9e8a8c3f40@(pry):34 (lambda)&amp;gt;&lt;/span&gt;
&lt;span class="gp"&gt;irb(main):002:0&amp;gt; &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="go"&gt;=&amp;gt; #&amp;lt;Proc:0x007f9e7a896ed8@(pry):35 (lambda)&amp;gt;&lt;/span&gt;
&lt;span class="gp"&gt;irb(main):003:0&amp;gt; &lt;/span&gt;&lt;span class="no"&gt;Proc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="go"&gt;=&amp;gt; #&amp;lt;Proc:0x007f9e7a8f95d8@(pry):36&amp;gt;&lt;/span&gt;
&lt;span class="gp"&gt;irb(main):004:0&amp;gt; &lt;/span&gt;&lt;span class="nb"&gt;proc&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="go"&gt;=&amp;gt; #&amp;lt;Proc:0x007f9e7a950e28@(pry):37&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;I'm not going to delve into the details of lambdas and simple procs, but there
are two basic differences and it's important to know that they exist. The first
is that lambdas are strict argument checkers, like methods, they can throw an
&lt;code&gt;ArgumentError&lt;/code&gt; exception. Simple procs will just ignore incorrect, extra or
fewer argument combinations. The second is that lambdas act like methods
regarding their return status - they can return values just like methods. When
you try to return a value from a simple proc you end up with a &lt;code&gt;LocalJumpError&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now back to our unary ampersand operator. Since both Blocks and Procs are
useful, it's convenient to be able to switch between them - enter &amp;amp;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;amp;object&lt;/code&gt; is evaluated in the following way:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;if object is a block, it converts the block into a simple proc.&lt;/li&gt;
&lt;li&gt;if object is a Proc, it converts the object into a block while preserving the
&lt;code&gt;lambda?&lt;/code&gt; status of the object.&lt;/li&gt;
&lt;li&gt;if object is not a Proc, it first calls #to_proc on the object and then
converts it into a block.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Let's examine each of these steps individually.&lt;/p&gt;

&lt;h4&gt;If object is a block, it converts the block to a simple proc.&lt;/h4&gt;

&lt;p&gt;The simplest example of this is when we want to have access to the block we pass
to a method, instead of just calling yield. To do this we need to convert the
block into a proc.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="s2"&gt;&amp;quot;The block that was passed has parameters: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parameters&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;




&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="irb"&gt;&lt;span class="gp"&gt;irb(main):001:0&amp;gt; &lt;/span&gt;&lt;span class="n"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="go"&gt;=&amp;gt; &amp;quot;The block that was passed has parameters: [[:opt, :a], [:opt, :b]]&amp;quot;&lt;/span&gt;
&lt;span class="gp"&gt;irb(main):002:0&amp;gt; &lt;/span&gt;&lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="gp"&gt;irb(main):003:0&amp;gt; &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="go"&gt;=&amp;gt; &amp;quot;The block that was passed has parameters: [[:rest, :args]]&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h4&gt;If object is a Proc, it converts the object into a block while preserving&lt;/h4&gt;

&lt;p&gt;the &lt;code&gt;lambda?&lt;/code&gt; status of the object.&lt;/p&gt;

&lt;p&gt;This is an extremely useful case of the &amp;amp; operator. For instance, we know that
&lt;code&gt;Array#map&lt;/code&gt; takes a block, but say we have a proc that we want to re-use in
multiple map calls.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="irb"&gt;&lt;span class="gp"&gt;irb(main):001:0&amp;gt; &lt;/span&gt;&lt;span class="n"&gt;multiply&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;lambda&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="gp"&gt;irb(main):002:0&amp;gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="go"&gt;=&amp;gt; [2, 4, 6]&lt;/span&gt;
&lt;span class="gp"&gt;irb(main):003:0&amp;gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="go"&gt;=&amp;gt; [8, 10, 12]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Keep in mind that the operator also preserves the &lt;code&gt;lambda?&lt;/code&gt; status of the
original block. That's kind of neat because it means we are able to pass lambdas
(not simple procs) as blocks. That means we can impose strict argument checking
in our blocks and we can have them return values using the &lt;code&gt;return&lt;/code&gt; keyword. The
only exception to this preservation is methods, which are always lambdas
regardless of how they are defined.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="s2"&gt;&amp;quot;Calling lambda? on the block results in &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lambda?&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.&amp;quot;&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;




&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="irb"&gt;&lt;span class="gp"&gt;irb(main):001:0&amp;gt; &lt;/span&gt;&lt;span class="n"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;lambda&lt;/span&gt;&lt;span class="p"&gt;{})&lt;/span&gt;
&lt;span class="go"&gt;=&amp;gt; &amp;quot;Calling lambda? on the block results in true.&amp;quot;&lt;/span&gt;
&lt;span class="gp"&gt;irb(main):002:0&amp;gt; &lt;/span&gt;&lt;span class="n"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;proc&lt;/span&gt;&lt;span class="p"&gt;{})&lt;/span&gt;
&lt;span class="go"&gt;=&amp;gt; &amp;quot;Calling lambda? on the block results in false.&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;




&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Container&lt;/span&gt;
  &lt;span class="n"&gt;define_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:m&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;proc&lt;/span&gt;&lt;span class="p"&gt;{})&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;




&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="irb"&gt;&lt;span class="gp"&gt;irb(main):001:0&amp;gt; &lt;/span&gt;&lt;span class="n"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="no"&gt;Container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:m&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_proc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="go"&gt;=&amp;gt; &amp;quot;Calling lambda? on the block results in true.&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h4&gt;If object is not a Proc, it first calls &lt;code&gt;#to_proc&lt;/code&gt; on the object and then converts it into a block.&lt;/h4&gt;

&lt;p&gt;This is where the magic really happens because it makes passing objects to
functions in the place of blocks very simple. The most common case of this is
probably calling into &lt;code&gt;Array#map&lt;/code&gt; with a symbol.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="irb"&gt;&lt;span class="gp"&gt;irb(main):001:0&amp;gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;2&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;3&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="ss"&gt;:to_i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="go"&gt;=&amp;gt; [1, 2, 3]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;This works because calling &lt;code&gt;Symbol#to_proc&lt;/code&gt; returns a proc that responds to the
symbol's method. So the &lt;code&gt;:to_i&lt;/code&gt; symbol is first converted to a proc, and then to
a block. This is kind of cool because we can create our own &lt;code&gt;to_proc&lt;/code&gt; methods.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Display&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_proc&lt;/span&gt;
    &lt;span class="nb"&gt;lambda&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FancyDisplay&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_proc&lt;/span&gt;
    &lt;span class="nb"&gt;lambda&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;** &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; **&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;




&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="irb"&gt;&lt;span class="gp"&gt;irb(main):001:0&amp;gt; &lt;/span&gt;&lt;span class="n"&gt;greetings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Hi&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Hello&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Welcome&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;

&lt;span class="gp"&gt;irb(main):002:0&amp;gt; &lt;/span&gt;&lt;span class="n"&gt;greetings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="no"&gt;Display&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="go"&gt;Hi&lt;/span&gt;
&lt;span class="go"&gt;Hello&lt;/span&gt;
&lt;span class="go"&gt;Welcome&lt;/span&gt;
&lt;span class="go"&gt;=&amp;gt; [nil, nil, nil]&lt;/span&gt;

&lt;span class="gp"&gt;irb(main):003:0&amp;gt; &lt;/span&gt;&lt;span class="n"&gt;greetings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="no"&gt;FancyDisplay&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="go"&gt;** Hi **&lt;/span&gt;
&lt;span class="go"&gt;** Hello **&lt;/span&gt;
&lt;span class="go"&gt;** Welcome **&lt;/span&gt;
&lt;span class="go"&gt;=&amp;gt; [nil, nil, nil]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Hopefully this post has clarified the binary and unary ampersand operator in
Ruby.  It's a fun operator. In the binary form it can provide us with a
shorthand way of doing bitwise AND and set intersection like operations. In the
unary form it provides us with some powerful functionality for converting blocks
and procs.&lt;/p&gt;

     
   &lt;img src="http://feeds.feedburner.com/~r/ablogaboutcode/~4/QTBWZSsLVYs" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://ablogaboutcode.com//2012/01/04/the-ampersand-operator-in-ruby</feedburner:origLink></entry>
 
 <entry>
   <title><![CDATA[Courteous Meta-Programming in Ruby]]></title>
   <link href="http://feedproxy.google.com/~r/ablogaboutcode/~3/wtGsG3KN-Ic/courteous-meta-programming-in-ruby" />
   <updated>2011-12-29T00:00:00-08:00</updated>
   <id>http://ablogaboutcode.com//2011/12/29/courteous-meta-programming-in-ruby</id>
   <content type="html">
     
     &lt;p&gt;Meta-programming is often kind of mean. It has a tendency to be hard to
understand and it can be quite destructive - causing methods to be modified or
overwritten in non-obvious ways. I decided to write a post about a more
courteous form of meta-programming. I picked up the technique from
&lt;a href="http://avdi.org/devblog/2011/12/07/defining-method_missing-and-respond_to-at-the-same-time/"&gt;a blog post about method_missing and respond_to?&lt;/a&gt;. I realized that
although I am comfortable with meta-programming, other developers might not feel
the same way. So, here's a simple pattern that can make your meta-programming
more readable and less destructive.&lt;/p&gt;

&lt;p&gt;I want to create a module named &lt;code&gt;Greetings&lt;/code&gt; so that when I extend my classes
with it I can declaratively add greetings to them.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FrenchAndEnglish&lt;/span&gt;
  &lt;span class="kp"&gt;extend&lt;/span&gt; &lt;span class="no"&gt;Greetings&lt;/span&gt;
  &lt;span class="n"&gt;greeting&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Bonjour!&amp;quot;&lt;/span&gt;
  &lt;span class="n"&gt;greeting&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Hello!&amp;quot;&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;




&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="irb"&gt;&lt;span class="gp"&gt;irb(main):001:0&amp;gt; &lt;/span&gt;&lt;span class="no"&gt;FrenchAndEnglish&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;greet&lt;/span&gt;
&lt;span class="go"&gt;Bonjour!&lt;/span&gt;
&lt;span class="go"&gt;Hello!&lt;/span&gt;
&lt;span class="go"&gt;=&amp;gt; nil&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;There are a couple of ways to accomplish this with Ruby. But before we jump into
code, let's add these constraints to the system. After all, we are trying to
write courteous code.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Readability&lt;/strong&gt; - the code should be easy to read and understand with minimal
knowledge of meta-programming.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Super Support&lt;/strong&gt; - the &lt;code&gt;greet&lt;/code&gt; method should support the use of &lt;code&gt;super&lt;/code&gt; to
delegate to parent definitions.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Non Destructive&lt;/strong&gt; - the extending class should be able to define it's own
&lt;code&gt;greet&lt;/code&gt; method.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;For instance, consider the following use of the &lt;code&gt;Greetings&lt;/code&gt; module. It supports
the use of &lt;code&gt;super&lt;/code&gt; to delegate to previous implementations of &lt;code&gt;greet&lt;/code&gt; and it
allows the base class to define it's own &lt;code&gt;greet&lt;/code&gt; method.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TriLingualWithEnglish&lt;/span&gt;
  &lt;span class="kp"&gt;extend&lt;/span&gt; &lt;span class="no"&gt;Greetings&lt;/span&gt;
  &lt;span class="n"&gt;greeting&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Hello!&amp;#39;&lt;/span&gt;
  &lt;span class="n"&gt;greeting&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Howdy!&amp;#39;&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message01&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message02&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@message01&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;message01&lt;/span&gt;
    &lt;span class="vi"&gt;@message02&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;message02&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;greet&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt; &lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="vi"&gt;@message01&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; and &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="vi"&gt;@message02&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;!&amp;quot;&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;




&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="irb"&gt;&lt;span class="gp"&gt;irb(main):001:0&amp;gt; &lt;/span&gt;&lt;span class="no"&gt;TriLingualWithEnglish&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Bonjour&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Kalimera&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;greet&lt;/span&gt;
&lt;span class="go"&gt;Hello!&lt;/span&gt;
&lt;span class="go"&gt;Howdy!&lt;/span&gt;
&lt;span class="go"&gt;Bonjour and Kalimera!&lt;/span&gt;
&lt;span class="go"&gt;=&amp;gt; nil&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Let's look at the most common meta-programming approaches to solving this
problem.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;eval&lt;/strong&gt; - using &lt;code&gt;instance_eval&lt;/code&gt; or &lt;code&gt;class_eval&lt;/code&gt; might be acceptable, but
these options are generally destructive. They overwrite methods on the base
class and this breaks our non-destructive requirement. If we were able to solve
this problem by using alias method chains then we would definitely be entering
the territory of un-readable code. Also method chains would not allow us to use
&lt;code&gt;super&lt;/code&gt; to call previous definitions of &lt;code&gt;greet&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tracking Class Variable&lt;/strong&gt; - a variable defined on the class level that is
responsible for keeping a list of greetings. This has lots of problems, for one
it does not support &lt;code&gt;super&lt;/code&gt;, but it also greatly restricts our flexibility.  We
can no longer define an alternate &lt;code&gt;greet&lt;/code&gt; method on the base class.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Since these two approaches don't fit our courteous meta-programming
requirements, here's the cool alternative that does.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Greetings&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;greeting&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;phrase&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Module&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;define_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:greet&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="k"&gt;super&lt;/span&gt; &lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;
        &lt;span class="nb"&gt;puts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;phrase&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;By using the anonymous module &lt;code&gt;m&lt;/code&gt;, and including it we are actually creating a
storage object in the class hierarcy for the method, instead of writing it on
the original class. This approach is non-destructive and allows us to maintain
a clean method chain that supports the use of &lt;code&gt;super&lt;/code&gt;. The &lt;code&gt;super rescue nil&lt;/code&gt;
line in our &lt;code&gt;TriLingualWithEnglish&lt;/code&gt; class now calls into the anonymous module
and allows both greeting implementations to co-exist. The code is also very
readable since the programmer does not need to understand &lt;code&gt;class_eval&lt;/code&gt; and
&lt;code&gt;instance_eval&lt;/code&gt;. I would advocate this approach whenever possible since it
preserves the class hierarchy and avoids some of the less readable
meta-programming techniques.&lt;/p&gt;

     
   &lt;img src="http://feeds.feedburner.com/~r/ablogaboutcode/~4/wtGsG3KN-Ic" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://ablogaboutcode.com//2011/12/29/courteous-meta-programming-in-ruby</feedburner:origLink></entry>
 
 <entry>
   <title><![CDATA[Object Oriented Ruby and Rails in the Complex World of Gems]]></title>
   <link href="http://feedproxy.google.com/~r/ablogaboutcode/~3/6E1tfhAhLUI/object-oriented-ruby-and-rails-in-the-complex-world-of-gems" />
   <updated>2011-11-30T00:00:00-08:00</updated>
   <id>http://ablogaboutcode.com//2011/11/30/object-oriented-ruby-and-rails-in-the-complex-world-of-gems</id>
   <content type="html">
     
     &lt;p&gt;Good Object-Oriented Programmers think of Objects and Responsibilities in terms
of a one-to-one relationship. One object, one responsibility. This concept
implies that applications should have a dichotomy between objects that are
responsible for business logic and objects that are responsible for integrating
with Gems. Another way to think of this is that your business logic should not
also be responsible for understanding a 3rd Party API. The knowledge of how to
interact with a gem shouldn't be duplicated in two different areas of your
application. Ideally, if you upgrade or replace a gem you should only have to
change one piece of code to make your application fully compatible with the new
gem version. That way your code is less brittle and easier to maintain.&lt;/p&gt;

&lt;h3&gt;A Simple Example&lt;/h3&gt;

&lt;p&gt;Say you have a pagination gem that works by monkey-patching the Array object.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="c1"&gt;#paginate(per_page, page)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;To wrap this functionality you could create the following object.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Paginator&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;paginate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;per_page&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;paginate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;per_page&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;When you upgrade that particular gem you only have one piece of code that you
need to change. And when an exception is raised, it is raised from within the
&lt;code&gt;Paginator&lt;/code&gt; which is a clean and obvious way of notifying you that the API has
probably changed. If the author of that gem chooses to use named parameters in
a hash in the next gem version, you can simply modify your &lt;code&gt;Paginator&lt;/code&gt; object.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Paginator&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;paginate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;per_page&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;paginate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;per_page&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;per_page&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;page&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h3&gt;The Two Solutions&lt;/h3&gt;

&lt;p&gt;At some point my objects need to interact with external libraries directly, but
I like to minimize where that happens.&lt;/p&gt;

&lt;p&gt;The first way to achieve this is to use the
&lt;a href="http://en.wikipedia.org/wiki/Facade_pattern"&gt;Facade Pattern&lt;/a&gt; and have your
classes interact with the facade object rather than the gem. The facade object
is responsible for abstracting the gem API and is customized to fit the needs of
your application.&lt;/p&gt;

&lt;p&gt;The second way to achieve this is to use what I like to call the Isolation
Pattern. In the Isolation Pattern the objects that interact with the external
library meet two requirements. First, they are relegated to the single
responsibility of interacting with the gem. Second, they are kept in their own
module or directory so as to prevent any kind of mingling with your other
objects.&lt;/p&gt;

&lt;p&gt;The two approaches achieve a similar end result - only one area of your code is
responsible for interaction with gem X. And that's the important take-away.
Let's take a look at three examples.&lt;/p&gt;

&lt;h3&gt;RSpec&lt;/h3&gt;

&lt;p&gt;RSpec clearly falls into the Isolation Pattern solution. It is setup to operate
in the &lt;code&gt;spec/&lt;/code&gt; directory with files named &lt;code&gt;*_spec.rb&lt;/code&gt;. It should not creep into
any other application files. It's also a very well known API. Other developers
will find it easier to interact with RSpec directly than with a facade that you
have created.&lt;/p&gt;

&lt;h3&gt;Facebook and Twitter&lt;/h3&gt;

&lt;p&gt;Facebook and Twitter authentication gems fall into the Facade Pattern solution.
They are highly specialized and don't have a common or popular interface. Most
developers won't need to interact with these gems on a daily basis, so a facade
makes sense because it simplifies an often complex API.&lt;/p&gt;

&lt;h3&gt;ActiveRecord&lt;/h3&gt;

&lt;p&gt;ActiveRecord - now this one may seem complex because Rails developers tend to
put everything under the sun into their ActiveRecord classes, but it really
falls into the Isolation Pattern solution. I like to think of ActiveRecord
objects as Objects that have the Responsibility of persisting your domain data.
That's it. They sit in the &lt;code&gt;app/models&lt;/code&gt; directory. They aren't responsible for
authenticating my Users or suggesting other Users for them to follow. It's
actually quite simple, here are my two ActiveRecord rules.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
Don't call ActiveRecord finders directly.

Finders, like `where`, are specific to ActiveRecord. They should not be called
outside of the ActiveRecord classes.


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PostsController&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;
    &lt;span class="vi"&gt;@posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Post&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:created_at&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gte&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Date&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;today&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;month&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


Should actually be


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PostsController&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;
    &lt;span class="vi"&gt;@posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Post&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;in_the_last_month&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


The reason for this is that if ActiveRecord changes its query interface as it
did between Rails 2 and Rails 3 then we shouldn't have to change our controllers
and application logic.
&lt;/li&gt;
&lt;li&gt;
Don't put domain logic in your ActiveRecord classes.


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="ss"&gt;ActiveRecord&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="ss"&gt;:Base&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;authenticate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;.&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


Should actually be


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserAuthenticator&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;authenticate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;by_username&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;.&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


The reason for this is that user authentication is application logic. It should
not be dependent upon our persistence layer.
&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;In a small application this may seem cumbersome.  Why create so many extra
objects to handle such simple functionality? As your application grows and more
developers need to understand it and test it, using good
Object-Oriented-Programming patterns makes sense. It makes your life easier and
it makes coding more fun. There are few things worse than
large-multi-responsible-classes.  Massive classes take too long to understand
and force longer and more complex function names. By following One Object, One
Responsibility you can separate implementation logic from business logic and
make your system less brittle, easier to test and easier to scale.&lt;/p&gt;

     
   &lt;img src="http://feeds.feedburner.com/~r/ablogaboutcode/~4/6E1tfhAhLUI" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://ablogaboutcode.com//2011/11/30/object-oriented-ruby-and-rails-in-the-complex-world-of-gems</feedburner:origLink></entry>
 
 <entry>
   <title><![CDATA[Ruby 1.9.3-p0 Released]]></title>
   <link href="http://feedproxy.google.com/~r/ablogaboutcode/~3/-3W4DtBbJrc/ruby-1-9-3-p0-released" />
   <updated>2011-10-31T00:00:00-07:00</updated>
   <id>http://ablogaboutcode.com//2011/10/31/ruby-1-9-3-p0-released</id>
   <content type="html">
     
     &lt;p&gt;Among the smattering of new methods and bug fixes the most important improvement
in Ruby 1.9.3 release, for Rails users, is going to be in application boot time.
I've seen at least 50% performance boosts in load time simply by upgrading from
Ruby 1.9.2. The installation was painless although I had some issues compiling
the &lt;a href="https://rubygems.org/gems/ffi"&gt;ffi&lt;/a&gt; gem extensions. I can't wait to migrate
production code over to this new version and development is going to be so much
more of a pleasure.&lt;/p&gt;

&lt;p&gt;To upgrade with RVM:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;rvm get head
rvm reload
rvm install 1.9.3
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;You can read the
&lt;a href="http://svn.ruby-lang.org/repos/ruby/tags/v1_9_3_0/NEWS"&gt;news post&lt;/a&gt; or
&lt;a href="http://svn.ruby-lang.org/repos/ruby/tags/v1_9_3_0/ChangeLog"&gt;changelog&lt;/a&gt; for
additional details.&lt;/p&gt;

&lt;p&gt;In particular I found the following of interest.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Random.rand&lt;/code&gt; now accepts a range as an argument &lt;code&gt;Random.rand(10..20)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;IO.write&lt;/code&gt; and &lt;code&gt;IO.binwrite&lt;/code&gt; for writing to files in normal and binary mode.&lt;/li&gt;
&lt;li&gt;New Encodings including &lt;code&gt;UTF-16&lt;/code&gt; and &lt;code&gt;UTF-32&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;ARGF new methods like &lt;code&gt;ARGF.write&lt;/code&gt; and &lt;code&gt;ARGF.puts&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Enjoy!&lt;/p&gt;

     
   &lt;img src="http://feeds.feedburner.com/~r/ablogaboutcode/~4/-3W4DtBbJrc" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://ablogaboutcode.com//2011/10/31/ruby-1-9-3-p0-released</feedburner:origLink></entry>
 
 <entry>
   <title><![CDATA[Using Rails Observers to write Faster Tests and Simpler Models]]></title>
   <link href="http://feedproxy.google.com/~r/ablogaboutcode/~3/Zh7LW8xTmNg/using-rails-observers-to-write-faster-tests-and-simpler-models" />
   <updated>2011-10-24T00:00:00-07:00</updated>
   <id>http://ablogaboutcode.com//2011/10/24/using-rails-observers-to-write-faster-tests-and-simpler-models</id>
   <content type="html">
     
     &lt;p&gt;&lt;a href="http://api.rubyonrails.org/classes/ActiveRecord/Observer.html"&gt;Rails observers&lt;/a&gt;
provide a great way to organize your code. If you follow the
skinny-controller-fat-model practice in Rails then you may have already crossed
the line from comfortably-plump models into massively-obese models. In fact it's
a common misconception that your "models" need to map directly to database
tables and it's quite easy to get carried away adding methods, associations,
scopes, validations and callbacks to them. Do not fear - one of the benefits of
writing Agile Object-Oriented Ruby is that you can easily simplify this mess
with a little refactoring. I'm only going to touch on refactoring callbacks
today, but a lot of what I cover here can be implemented for other methods as
well.&lt;/p&gt;

&lt;h3&gt;What's Wrong with This Callback?&lt;/h3&gt;

&lt;p&gt;Let's consider the following seemingly innocent code. Assume for the time being
that in production our emails are actually delivered in the background.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;
  &lt;span class="n"&gt;after_create&lt;/span&gt; &lt;span class="ss"&gt;:send_welcome_email&lt;/span&gt;

  &lt;span class="kp"&gt;protected&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;send_welcome_email&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;purchased_membership?&lt;/span&gt;
      &lt;span class="no"&gt;GreetingMailer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;welcome_and_thanks_email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;deliver&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="no"&gt;GreetingMailer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;welcome_email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;deliver&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Does this callback really belong on the &lt;code&gt;User&lt;/code&gt; class? In some ways it does, it's
definitely entirely dependent on the user's state and does a pretty good job of
delegating to the &lt;code&gt;GreetingMailer&lt;/code&gt; instead of trying to handle the mail
implementation itself. But it does kind of break the "each object should only
deal with one or a few things" OOP pattern. On a more academic level this code
doesn't really have much to do with the user domain model. It's only really
responsible for sending a welcome email when something is created.&lt;/p&gt;

&lt;h3&gt;Let's Refactor It&lt;/h3&gt;

&lt;p&gt;Let's rid the &lt;code&gt;User&lt;/code&gt; model of this coupling by refactoring the code into an
observer. Our &lt;code&gt;WelcomeEmailObserver&lt;/code&gt; will have a single responsibility, namely
to "send the appropriate welcome email once something is created".&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="c1"&gt;# app/[models|observers]/welcome_email_observer.rb&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WelcomeEmailObserver&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="ss"&gt;ActiveRecord&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="ss"&gt;:Observer&lt;/span&gt;
  &lt;span class="n"&gt;observe&lt;/span&gt; &lt;span class="ss"&gt;:user&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;after_create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;purchased_membership?&lt;/span&gt;
      &lt;span class="no"&gt;GreetingMailer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;welcome_and_thanks_email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;deliver&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="no"&gt;GreetingMailer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;welcome_email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;deliver&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# app/models/user.rb&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# config/application.rb&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Application&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="ss"&gt;Rails&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="ss"&gt;:Application&lt;/span&gt;
  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;active_record&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;observers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;:welcome_email_observer&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Looks good. A couple of things to notice. First, the &lt;code&gt;User&lt;/code&gt; model is simpler.
It is no longer coupled to the &lt;code&gt;GreetingMailer&lt;/code&gt;. In fact, removing or modifying
the &lt;code&gt;GreetingMailer&lt;/code&gt; does not require us to touch the &lt;code&gt;User&lt;/code&gt; model. A
side-effect of this is also that the &lt;code&gt;WelcomeEmailObserver&lt;/code&gt; is reusable. It is
no longer strictly coupled to the &lt;code&gt;User&lt;/code&gt;. Secondly, we aren't messing with
&lt;a href="http://en.wikipedia.org/wiki/Law_of_Demeter"&gt;The Law of Demeter&lt;/a&gt;, the
&lt;code&gt;WelcomeEmailObserver&lt;/code&gt; is only referencing its own parameters and first level
attributes of those parameters.&lt;/p&gt;

&lt;h3&gt;Fixing Our Tests&lt;/h3&gt;

&lt;p&gt;Now that we've moved things around, let's take a look at our tests. First we'll
ensure that they pass and that we didn't break anything.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;welcome email&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;let&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:mail&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="n"&gt;stub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:deliver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;should send the simple welcome email if not purchased&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="no"&gt;WelcomeMailer&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;should_receive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:welcome_email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;and_return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mail&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;any_instance&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:purchased_membership?&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;and_return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sham!&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;should send the welcome and thanks email if purchased&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="no"&gt;WelcomeMailer&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;should_receive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:welcome_and_thanks_email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;and_return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mail&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;any_instance&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:purchased_membership?&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;and_return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sham!&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Once we've verified that the code works, we'll move the tests from our
&lt;code&gt;user_spec&lt;/code&gt; into our &lt;code&gt;welcome_email_observer_spec&lt;/code&gt;. After all we're no longer
really testing the &lt;code&gt;User&lt;/code&gt;.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="no"&gt;WelcomeEmailObserver&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;let&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:mail&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="n"&gt;stub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:deliver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;should send the simple welcome email if not purchased&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="no"&gt;WelcomeMailer&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;should_receive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:welcome_email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;and_return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mail&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="no"&gt;WelcomeEmailObserver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;after_create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:purchased_membership?&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;should send the welcome and thanks email if purchased&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="no"&gt;WelcomeMailer&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;should_receive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:welcome_and_thanks_email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;and_return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mail&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="no"&gt;WelcomeEmailObserver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;
      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;after_create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:purchased_membership?&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;That's a great first step, we've definitely simplified our test and are no
longer coupled to the &lt;code&gt;User&lt;/code&gt; class.&lt;/p&gt;

&lt;h3&gt;Reducing Test Dependencies&lt;/h3&gt;

&lt;p&gt;While it's not immediately obvious, our first implementation actually strongly
coupled all of our tests that create a &lt;code&gt;User&lt;/code&gt; to the &lt;code&gt;GreetingMailer&lt;/code&gt;. Any time
we created a user we inadvertently also delivered a welcome email. Aside from
creating a dependency between our tests and the success of &lt;code&gt;GreetingMailer&lt;/code&gt;
methods we've also incurred a great performance penalty, namely the code related
to constructing and rendering the email.&lt;/p&gt;

&lt;p&gt;While the rendering part may not apply to all of our tests it's easy to deduce
that almost any callback will impose a similar and undesirable overhead. This
simple performance penalty is really the main reason that so many Rails test
suites take so long to run.&lt;/p&gt;

&lt;p&gt;Let's take a look at a solution to this overhead and how we can simplify our
test.&lt;/p&gt;

&lt;h3&gt;Improving Test Performance&lt;/h3&gt;

&lt;p&gt;First, we'll install the
&lt;a href="https://rubygems.org/gems/no_peeping_toms"&gt;no_peeping_toms&lt;/a&gt; gem. This gem
allows us to turn off ActiveRecord observers on a case-by-case basis. I prefer
to implement it by adding the following to my spec helper file.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="no"&gt;RSpec&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;configure&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;before&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:suite&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="ss"&gt;ActiveRecord&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="ss"&gt;:Observer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;disable_observers&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;If you already have observers that are being tested, this change will most
likely causes a lot of your tests to fail until you enable the related observers
on individual tests. But alone this change can result in a very noticeable
performance boost.&lt;/p&gt;

&lt;p&gt;The one thing we might be missing from this refactoring is a good integration
test. While it can be argued that testing observer integration is really just
testing Rails, we can make an argument that an integration test is actually
simply testing that our observer is in fact at least observing the &lt;code&gt;User&lt;/code&gt; model.
In other words that our observer contains the line &lt;code&gt;observer :user&lt;/code&gt;.  So, if we
are compelled to do so, we can also add an integration test to ensure this.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;should send a welcome email on create&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="no"&gt;WelcomeEmailObserver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;any_instance&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;should_receive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:after_create&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;once&lt;/span&gt;
    &lt;span class="ss"&gt;ActiveRecord&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="ss"&gt;:Observer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;with_observers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:welcome_email_observer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sham!&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Hopefully this post has enlightened or convinced you of the use of observers and
given you some insight into testing them and improving the performance and
reliability of the remainder of your tests. I would like to continue writing
some more posts about refactoring and testing improvements, so if you have any
suggestions please email me or leave a comment.&lt;/p&gt;

     
   &lt;img src="http://feeds.feedburner.com/~r/ablogaboutcode/~4/Zh7LW8xTmNg" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://ablogaboutcode.com//2011/10/24/using-rails-observers-to-write-faster-tests-and-simpler-models</feedburner:origLink></entry>
 
 <entry>
   <title><![CDATA[Dynamic Rescue Clause in Ruby]]></title>
   <link href="http://feedproxy.google.com/~r/ablogaboutcode/~3/TnJLC9zkg54/dynamic-rescue-clause-in-ruby" />
   <updated>2011-09-21T00:00:00-07:00</updated>
   <id>http://ablogaboutcode.com//2011/09/21/dynamic-rescue-clause-in-ruby</id>
   <content type="html">
     
     &lt;p&gt;I recently finished &lt;a href="http://about.avdi.org/"&gt;Avdi Grimm&lt;/a&gt;'s
&lt;a href="http://exceptionalruby.com/"&gt;Exceptional Ruby&lt;/a&gt;. It's definitely a great
introduction to Ruby exceptions and how you can begin using and handling them in
your own projects and libraries.&lt;/p&gt;

&lt;p&gt;While working through an example in his book I realized that Ruby 1.9.2 actually
greatly improves the rescue clause functionality. For instance, in Ruby 1.8.7
you can not use a proc to handle exceptions.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="c1"&gt;#!/usr/bin/env ruby&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;match_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;regexp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;lambda&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;regexp&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;begin&lt;/span&gt;
  &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="no"&gt;StandardError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Error message about a socket.&amp;quot;&lt;/span&gt;
&lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="n"&gt;match_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/socket/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Error &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; matches /socket/; ignored.&amp;quot;&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Running this code in Ruby 1.8.7 produces a TypeError.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:9: class or module required for rescue clause (TypeError)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Running this code in Ruby 1.9.2 results in a properly handled exception.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Error StandardError matches /socket/; ignored.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To get this code to work in Ruby 1.8.7 you have to create a new module and
modify the === function on that module to handle the exception.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="c1"&gt;#!/usr/bin/env ruby&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;match_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;regexp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Module&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;instance_eval&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;define_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:===&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;regexp&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="n"&gt;m&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;begin&lt;/span&gt;
  &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="no"&gt;StandardError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Error message about a socket.&amp;quot;&lt;/span&gt;
&lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="n"&gt;match_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/socket/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Error &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; matches /socket/; ignored.&amp;quot;&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Fortunately Ruby 1.9.2 entirely removes the module/class requirement for rescue
clauses which results in a
&lt;a href="https://gist.github.com/1230515#file_dynamic.bench.rb"&gt;27 times faster&lt;/a&gt;
alternative when using a proc over the module metaprogramming approach. I
personally have not used this style of dynamic error handler in my code, I
prefer to subclass my exceptions, but if you are using another developer's
library this might be your only option to safely catch multiple exceptions.&lt;/p&gt;

&lt;p&gt;For the jRuby fans out there, this is a syntax which jRuby does not support.
Even if you are running jRuby with the JRUBY_OPTS="--1.9" you'll have to use the
1.8.7 code.&lt;/p&gt;

&lt;p&gt;You can view a gist of the examples in this post
&lt;a href="https://gist.github.com/1230515"&gt;here&lt;/a&gt;.&lt;/p&gt;

     
   &lt;img src="http://feeds.feedburner.com/~r/ablogaboutcode/~4/TnJLC9zkg54" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://ablogaboutcode.com//2011/09/21/dynamic-rescue-clause-in-ruby</feedburner:origLink></entry>
 
 <entry>
   <title><![CDATA[Sham 1.0.0 Released!]]></title>
   <link href="http://feedproxy.google.com/~r/ablogaboutcode/~3/00XOp6KYP74/sham-1-0-0-released" />
   <updated>2011-09-13T00:00:00-07:00</updated>
   <id>http://ablogaboutcode.com//2011/09/13/sham-1-0-0-released</id>
   <content type="html">
     
     &lt;p&gt;Today I released a new version of the
&lt;a href="https://rubygems.org/gems/sham"&gt;Sham gem (version 1.0.0)&lt;/a&gt;. This new version is
not backwards compatible, hence the major version release. I highly recommend
upgrading - this new version has some cool goodies included in it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sham::Config.activate! is faster - much faster.&lt;/li&gt;
&lt;li&gt;Shams can be included individually. You no longer need to activate all
shams, you can simply include a file with a Sham definition in it and that Sham
will be available to you. You can also define Shams inline in your specs and
tests.&lt;/li&gt;
&lt;li&gt;The Sham definition syntax has changed, you can read more about this in the
&lt;a href="https://github.com/panthomakos/sham/blob/master/README.markdown"&gt;documentation&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;There are a few more helper functions, namely the #empty function which allows
you to create a simple empty Sham.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Here's a quick sample using the new definition syntax:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="no"&gt;Sham&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;empty&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="no"&gt;Sham&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:small&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;attributes&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;:weight&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="no"&gt;Sham&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:large&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;attributes&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;:weight&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="no"&gt;Item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sham!&lt;/span&gt;
&lt;span class="no"&gt;Item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sham!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:small&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:quantity&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;Item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sham!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:large&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:build&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:quantity&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Enjoy!&lt;/p&gt;

     
   &lt;img src="http://feeds.feedburner.com/~r/ablogaboutcode/~4/00XOp6KYP74" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://ablogaboutcode.com//2011/09/13/sham-1-0-0-released</feedburner:origLink></entry>
 
 <entry>
   <title><![CDATA[after_create bug in Rails 3]]></title>
   <link href="http://feedproxy.google.com/~r/ablogaboutcode/~3/NdtYR-INeB0/after_create-bug-in-rails-3" />
   <updated>2011-08-17T00:00:00-07:00</updated>
   <id>http://ablogaboutcode.com//2011/08/17/after_create-bug-in-rails-3</id>
   <content type="html">
     
     &lt;p&gt;I ran into this callback ordering issue while working on a Rails project
recently and decided to investigate.  After writing some test rails apps I am
pretty confident this is a bug in Rails 3.0.x.  If you believe otherwise, please
leave a comment or explanation.&lt;/p&gt;

&lt;p&gt;Taking a step back from the actual code, in an ORM (Object Relational Model) I
would expect that callbacks from objects are consistent in their ordering.  That
is, if I have a callback that fires when an object has been saved to the
database, that callback will fire at the same time (after the object has been
saved to the database) regardless of any dependent objects or where the callback
has been declared.  Here's some code to demonstrate this:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;
  &lt;span class="n"&gt;after_create&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;after create user&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:posts&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Post&lt;/span&gt;
  &lt;span class="n"&gt;after_create&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;after create post&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;belongs_to&lt;/span&gt; &lt;span class="ss"&gt;:user&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;
&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;posts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;build&lt;/span&gt;
&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;after commit user&amp;#39;&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;after commit post&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Simple, right? Almost. The problem in Rails is that the after_create callback
doesn't exactly work that way. When it fires is actually dependent on the order
in which it was defined. What's more - this isn't actually the case with the
after destroy callback. Here's some code to demonstrate the issue:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;
  &lt;span class="n"&gt;after_create&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;User - first after create&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;after_destroy&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;User - first after destroy&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:posts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:dependent&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:destroy&lt;/span&gt;

  &lt;span class="n"&gt;after_create&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;User - second after create&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;after_destroy&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;User - second after destroy&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Post&lt;/span&gt;
  &lt;span class="n"&gt;after_create&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Post - first after create&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;after_destroy&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Post - first after destroy&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;belongs_to&lt;/span&gt; &lt;span class="ss"&gt;:user&lt;/span&gt;

  &lt;span class="n"&gt;after_create&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Post - second after create&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;after_destroy&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Post - second after destroy&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;
&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;posts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;build&lt;/span&gt;
&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="n"&gt;after&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Post&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="n"&gt;after&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Post&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;second&lt;/span&gt; &lt;span class="n"&gt;after&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;second&lt;/span&gt; &lt;span class="n"&gt;after&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt;

&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;destroy&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Post&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="n"&gt;after&lt;/span&gt; &lt;span class="n"&gt;destroy&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Post&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;second&lt;/span&gt; &lt;span class="n"&gt;after&lt;/span&gt; &lt;span class="n"&gt;destroy&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="n"&gt;after&lt;/span&gt; &lt;span class="n"&gt;destroy&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;second&lt;/span&gt; &lt;span class="n"&gt;after&lt;/span&gt; &lt;span class="n"&gt;destroy&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Take a second and look at that - do you see what's wrong? The
&lt;code&gt;User#after_create&lt;/code&gt; callbacks are called at opposite ends of the Post#after
create callbacks, but the User#after_destroy callbacks are called at the end.
What does this mean? Well basically that after_create is not actually called
after the record is created (and saved to the database) - it's called "after the
record is created and any dependent relations defined before it are also
created". Now that just seems wrong to me. Especially when the after_destroy
callback behaves in a different way.&lt;/p&gt;

&lt;p&gt;It seems that the flow should work like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The user is saved.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;User#after_create&lt;/code&gt; callbacks are executed.&lt;/li&gt;
&lt;li&gt;The post is saved&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;Post#after_create&lt;/code&gt; callbacks are executed.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;Especially when the opposite is true for &lt;code&gt;after_destroy&lt;/code&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The post is destroyed.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;Post#after_destroy&lt;/code&gt; callbacks are executed.&lt;/li&gt;
&lt;li&gt;The user is destroyed.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;User#after_destroy&lt;/code&gt; callbacks are executed.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;The problem right now is that the &lt;code&gt;User#after_create&lt;/code&gt; callbacks are being called
in two places - once after the user is created (if they are defined before the
&lt;code&gt;has_many :posts&lt;/code&gt; declaration) and once after the &lt;code&gt;Post#after_create&lt;/code&gt; callbacks
are executed (if they are defined after the has_many :posts declaration).&lt;/p&gt;

&lt;p&gt;If you're into TDD, you would check that the first case actually produces this
result:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;=&amp;gt; User - first after create
=&amp;gt; User - second after create
=&amp;gt; Post - first after create
=&amp;gt; Post - second after create
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So why is this a problem? Why not just define all your callbacks before your
relations? The first problem with this is that it is inconsistent - after
destroy and after_create should behave in the same manner. The second problem is
that your code might fail and it's not obvious why.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;
  &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;Poster&lt;/span&gt;

  &lt;span class="n"&gt;after_create&lt;/span&gt; &lt;span class="ss"&gt;:do_something&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Poster&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;included&lt;/span&gt; &lt;span class="n"&gt;klass&lt;/span&gt;
    &lt;span class="n"&gt;klass&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;class_eval&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:posts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:dependent&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:destroy&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;While this example is trivial it illustrates how easy it is to mix up the order
or definitions in Ruby. Unbeknownst to us, simply looking at the User class,
this would actually cause our :do_something callback to be executed in the wrong
order.&lt;/p&gt;

     
   &lt;img src="http://feeds.feedburner.com/~r/ablogaboutcode/~4/NdtYR-INeB0" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://ablogaboutcode.com//2011/08/17/after_create-bug-in-rails-3</feedburner:origLink></entry>
 
 <entry>
   <title><![CDATA[Avoiding Nested Callbacks in JavaScript]]></title>
   <link href="http://feedproxy.google.com/~r/ablogaboutcode/~3/7SnjSF2OxTs/avoiding-nested-callbacks-in-javascript" />
   <updated>2011-06-30T00:00:00-07:00</updated>
   <id>http://ablogaboutcode.com//2011/06/30/avoiding-nested-callbacks-in-javascript</id>
   <content type="html">
     
     &lt;p&gt;I was reading through the
&lt;a href="http://visionmedia.github.com/masteringnode"&gt;Mastering Node E-Book&lt;/a&gt;, which is a
great resource for getting started with node.js by the way, and I came across
this code example.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="javascript"&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;fs&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mkdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;./hello&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0777&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;writeFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;./hello/world.txt&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Hello!&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;File created with contents: &amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;readFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;./hello/world.txt&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;UTF-8&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;This code creates a directory &lt;code&gt;./hello&lt;/code&gt;, then writes a file &lt;code&gt;./hello/world.txt&lt;/code&gt;,
and then reads the contents of that file. All the filesystem operations are
handled through callbacks - that's the way we do things in JavaScript. The
example is quite simple and while it's specific to node, it illustrates a pretty
common case of deeply nested callbacks in JavaScript. This set of instructions
might be easy enough to read here, but it doesn't take a genius to figure out
that these nested callbacks will eventually become a bit of a headache.&lt;/p&gt;

&lt;p&gt;Fortunately there is a better way - named callbacks. Here is how the latter code
can be transformed into a less-nested program.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="javascript"&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;fs&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mkdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;./hello&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0777&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;makeDirectory&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;makeDirectory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;writeFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;./hello/world.txt&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Hello!&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;writeFile&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;writeFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;File created with contents: &amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;readFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;./hello/world.txt&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;UTF-8&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;readFile&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;readFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Pretty cool, huh? Well, until you have two or three callbacks that respond
differently to fs.readFile and you start running out of function names, right?
Not to worry, you can create closures for your callbacks as well. For example,
let's say we want to return the result of fs.writeFile, but we want to write two
different files, namely &lt;code&gt;./hello.txt&lt;/code&gt; and &lt;code&gt;./world.txt&lt;/code&gt;. While this example is a
little inane it demonstrates how easily the closures help to partition your code
without having to rely solely on unnamed callbacks.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="javascript"&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;fs&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;writeHello&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;writeFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;./hello.txt&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Hello!&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;writeFile&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;writeFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Wrote hello.txt&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;writeWorld&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;writeFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;./world.txt&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;World!&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;writeFile&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;writeFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Wrote world.txt&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;writeHello&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;writeWorld&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Wait, how did that work, didn't we return before defining that function? Yes,
but not quite, in JavaScript any functions defined using &lt;code&gt;function name(){}&lt;/code&gt; as
opposed to using &lt;code&gt;var&lt;/code&gt; are available immediately upon entering the function or
program body respectively. That means that we can define named callbacks after
our return statements and still have a linear, readable and less-nested program.
You can find a &lt;a href="https://gist.github.com/1055795"&gt;gist of this code on github&lt;/a&gt;,
enjoy!&lt;/p&gt;

     
   &lt;img src="http://feeds.feedburner.com/~r/ablogaboutcode/~4/7SnjSF2OxTs" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://ablogaboutcode.com//2011/06/30/avoiding-nested-callbacks-in-javascript</feedburner:origLink></entry>
 
 <entry>
   <title><![CDATA[A Faster YARD Doc Server with Guard-Yard]]></title>
   <link href="http://feedproxy.google.com/~r/ablogaboutcode/~3/zluvvLpa5tg/a-faster-yard-doc-server-with-guard-yard" />
   <updated>2011-06-21T00:00:00-07:00</updated>
   <id>http://ablogaboutcode.com//2011/06/21/a-faster-yard-doc-server-with-guard-yard</id>
   <content type="html">
     
     &lt;p&gt;I recently started using &lt;a href="http://yardoc.org/"&gt;YARD&lt;/a&gt; to view my documented source
code in an HTML format.  I really like the
&lt;a href="http://rubydoc.info/gems/timezone/0.1.2/frames"&gt;syntax and navigation&lt;/a&gt; that the
web interface provides, and I feel that having this nicely formatted display of
documentation really pushes me to think more about commenting my code while
developing. Starting the YARD server locally is as easy as installing the gem,
generating the docs and starting the server.&lt;/p&gt;

&lt;p&gt;But I found that it's a bit of a pain in the ass to actually view documentation
while it's undergoing changes. While you can run the server in "reload" mode,
this requires your entire documentation to be re-generated on every request, and
I feel that it's wildly inefficient and slow. To remedy this problem I released
a gem that integrates with &lt;a href="https://github.com/guard/guard"&gt;guard&lt;/a&gt; to bring you
a speedy and up-to-date YARD Documentation Server.&lt;/p&gt;

&lt;p&gt;There are two major benefits to the
&lt;a href="https://github.com/panthomakos/guard-yard"&gt;guard-yard&lt;/a&gt; gem.  The first is that
it provides a consolidation of all file-monitoring processes to guard. This
means you only need to run guard to keep your documentation server up-to-date
and running. There is no need to configure the YARD server or re-processes your
documentation on every request. The second benefit is that the docs are updated
quickly. The guard-yard gem only modifies the documentation for files that have
actually changed. This means that viewing your changes happens sooner!&lt;/p&gt;

&lt;p&gt;Staring the YARD server via guard-yard is very easy:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install &lt;a href="https://github.com/guard/guard"&gt;guard&lt;/a&gt;,
&lt;a href="https://github.com/panthomakos/guard-yard"&gt;guard-yard&lt;/a&gt;, and
&lt;a href="https://github.com/lsegal/yard"&gt;yard&lt;/a&gt; gems.&lt;/li&gt;
&lt;li&gt;Update your Guardfile using &lt;code&gt;guard init yard&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Start the Guard server using &lt;code&gt;guard start&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;For additional details check out the
&lt;a href="https://rubygems.org/gems/guard-yard"&gt;gem page&lt;/a&gt;.&lt;/p&gt;

     
   &lt;img src="http://feeds.feedburner.com/~r/ablogaboutcode/~4/zluvvLpa5tg" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://ablogaboutcode.com//2011/06/21/a-faster-yard-doc-server-with-guard-yard</feedburner:origLink></entry>
 
 <entry>
   <title><![CDATA[How Javascript Loading Works - DOMContentLoaded and OnLoad]]></title>
   <link href="http://feedproxy.google.com/~r/ablogaboutcode/~3/5kGe1HUuKEI/how-javascript-loading-works-domcontentloaded-and-onload" />
   <updated>2011-06-14T00:00:00-07:00</updated>
   <id>http://ablogaboutcode.com//2011/06/14/how-javascript-loading-works-domcontentloaded-and-onload</id>
   <content type="html">
     
     &lt;p&gt;There are actually three different windows of time during a web request in which
we can load and execute javascript. These windows are delineated by the
DOMContentLoaded event and the OnLoad event. We can load our scripts before
DOMContentLoaded, after DOMContentLoad, and after OnLoad. But before I dig into
the details of how this is done, what the heck are these two events and when are
they actually triggered?&lt;/p&gt;

&lt;h2&gt;The Events&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://developer.mozilla.org/en/Gecko-Specific_DOM_Events#DOMContentLoaded"&gt;DOMContentLoaded&lt;/a&gt; event is triggered when the page's
Document Object Model (DOM) is ready.  What this means is that the API for
interacting with the content, style and structure of a page is ready to receive
requests from your code. In general this means that the text, css and html are
ready - but it's not quite that simple. Depending on the browser, HTML version,
and where the stylesheet tags are relative to the script tags, the CSS might not
be done rendering by the time this event fires. Fortunately there is a safe and
performant way to ensure that the CSS is loaded first. It's as simple as placing
your external stylesheets in the header and your external javascripts in the
footer. This approach forces the javascript to execute only after the external
stylesheets and HTML body have been loaded. Basically, this means that if you
are placing stylesheets in the header and javascripts in the footer, your DOM
will load all content, structure, and style before the DOMContentLoaded event is
fired. That's a good thing!&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://developer.mozilla.org/en/XUL_Tutorial/More_Event_Handlers#Load_Events"&gt;OnLoad&lt;/a&gt; event is triggered when the entire page has loaded. This
is moment when the globe or loader in your browser's title bar stops spinning.
At this point all scripts and stylesheets have finished loading and have been
executed, and all images have been downloaded and displayed.&lt;/p&gt;

&lt;h2&gt;Loading Javascript&lt;/h2&gt;

&lt;p&gt;So how do we hook into each of these events; and more importantly, when should
we use each? To examine the different hooks, let's have a look at this simple
HTML page and the output that it produces.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="html"&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;jquery.min.js&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;external.js&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;text/javascript&amp;#39;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="c1"&gt;//&amp;lt;![CDATA[&lt;/span&gt;
      &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getScript&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;ajax.js&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;ready&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;DOM Loaded (DOMContentLoaded)&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;head&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;dom.js&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&amp;#39;);
        $.getScript(&amp;#39;dom_ajax.js&amp;#39;);
      });
      $(window).load(function(){
        console.log(&amp;#39;Page Loaded (OnLoad)&amp;#39;);
        $.getScript(&amp;#39;page_ajax.js&amp;#39;);
      });
    //]]&amp;gt;
  &lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;If we examine the javascript console we can see the list of events play out like
this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;external.js Loaded and Executed
DOM Loaded (DOMContentLoaded)
dom.js Loaded and Executed
Page Loaded (OnLoad)
ajax.js Loaded and Executed
dom_ajax.js Loaded and Executed
page_ajax.js Loaded and Executed
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This console output implicates the three windows of javascript loading:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;External javascript (external.js) is loaded before DOMContentLoaded.&lt;/li&gt;
&lt;li&gt;External javascript inserted into HTML during the DOMContentLoaded callback
(dom.js) is loaded before OnLoad.&lt;/li&gt;
&lt;li&gt;AJAX requests do not delay DOMContentLoaded or OnLoad, regardless of when they
are initiated (ajax.js, dom_ajax.js and page_ajax.js).&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Let's take a look at each of these windows and see which one best suits our
needs.&lt;/p&gt;

&lt;h2&gt;Before DOMContentLoaded&lt;/h2&gt;

&lt;p&gt;First, notice that both inline javascript and external javascript (external.js)
is loaded and executed immediately, regardless of the DOM being ready or the
page having been loaded.  This may seem obvious, but it is necessary to execute
this code before DOMContentLoaded so that we can actually hook into the event.
The best way to think of this javascript is as a setup. You shouldn't be
manipulating the DOM yet, since it isn't ready - you should be setting up your
callbacks and then getting out of the way so the rest of the page can load
quickly.&lt;/p&gt;

&lt;h2&gt;After DOMContentLoaded&lt;/h2&gt;

&lt;p&gt;These scritpts (dom.js) are executed once the DOM is ready to be manipulated.
This where you want to put any code that actually changes the page visually as
this is the earliest point at which DOM manipulation is possible, and it will be
executed before the page is displayed. This is a good thing because we don't
want the page elements jumping around and changing style after they are visible
to the user.&lt;/p&gt;

&lt;h2&gt;After OnLoad&lt;/h2&gt;

&lt;p&gt;These scripts (ajax requests and anything in the window.load callback) are
executed after the page has completed loading and the user can view the entire
document. This is a great place to load long-running scripts and scripts that
don't visually alter the page.  Some examples of this include analytics and
reporting libraries and code or data that might be used later and can be
pre-fetched for the user.  Google maps loads all of its map tiles using AJAX so
that the page load is not halted.&lt;/p&gt;

&lt;h2&gt;Takeaway&lt;/h2&gt;

&lt;p&gt;Try to keep this page load process in mind when writing your javascript code.
Simple placement of your code can lead to large gains in overall perceived page
load time.  I'm hoping this blog post clarifies the basic page load events and
allows you to beter determine how and where javascript should be loaded in your
own application. If you have any questions or examples of these methods in use,
please leave a comment.&lt;/p&gt;

     
   &lt;img src="http://feeds.feedburner.com/~r/ablogaboutcode/~4/5kGe1HUuKEI" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://ablogaboutcode.com//2011/06/14/how-javascript-loading-works-domcontentloaded-and-onload</feedburner:origLink></entry>
 
 <entry>
   <title><![CDATA[Recap and Thoughts on the Facebook Deploy and Push Process]]></title>
   <link href="http://feedproxy.google.com/~r/ablogaboutcode/~3/nbtKSy_R1DA/recap-and-thoughts-on-the-facebook-deploy-and-push-process" />
   <updated>2011-05-27T00:00:00-07:00</updated>
   <id>http://ablogaboutcode.com//2011/05/27/recap-and-thoughts-on-the-facebook-deploy-and-push-process</id>
   <content type="html">
     
     &lt;p&gt;Yesterday, Facebook gave a presentation on their front-end push/deploy process
called &lt;a href="https://www.facebook.com/event.php?eid=209798352393506"&gt;Pushing Millions of Lines of Code Five Days a Week&lt;/a&gt;. Facebook
releases code once a week, but they push new code daily. While few companies
operate on this scale there is a lot we can learn from their "push culture" and
the tools they use to promote a bug free deploy process.&lt;/p&gt;

&lt;h2&gt;Culture&lt;/h2&gt;

&lt;p&gt;There was a large focus on push culture. While tools are great and can help,
they don't mean a thing if there isn't a company culture to support a bug-free
and painless deploy process.  Creating this culture early on is important, that
includes ensuring that developers are on the hook for the changes they make.
The further the developer is from the end product and release date, the less
likely they are to be held accountable for their code.  Pushers at Facebook
ensure that a developer is responsible for their code that day, that week and
even if they move to another group within Facebook.&lt;/p&gt;

&lt;h2&gt;Tools&lt;/h2&gt;

&lt;p&gt;For the geekier viewer the tools part is always fun - we love gadgets! Facebook
has built a suite of monitoring tools they use internally to ease the push
process.  For the most part there are free, open-source and DIY alternatives to
a lot of these tools.  Facebook is at a much larger scale than many of us, so in
my Take Away section I am going to focus more on what you can do to implement
these tools and the culture they promote.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;IRC Bots&lt;/strong&gt; are used because all internal communication is done through IRC,
so it's important to provide automated answers to some of the most commonly
asked questions and avoid overwhelming the push engineers. For instance, if a
developer wants to know, "will my revision be in this push?" they need only ask
an IRC bot.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Automated Tests&lt;/strong&gt; are critical because engineers are responsible for writing
unit and selenium tests to support their code. These tests are automated and
they are used to determine if a revision is ready for release.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Shadow Branches&lt;/strong&gt; are pre-live versions of Facebook. Internally facebook.com
points to latest.facebook.com - a version of facebook that is ready for release
this week. These shadow branches ensure the "you are always testing" mentality
and help ferret out bugs before the push begins and during the first phases of
the deploy process.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Error Tracking&lt;/strong&gt; is controlled via a data-centric internal dashboard that
includes information on where the error happened and which developer is to blame
for that line of code.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GateKeeper&lt;/strong&gt; is a fancy tool that developers use to roll-out features to
subsets of users.  Subsets can include percentages of the population, males or
females only, people with or without a certain affiliation or group membership
and more.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Perflab&lt;/strong&gt; is a tool for tracking performance changes on code branches and
revisions and the impact your change has on the site.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HipHop&lt;/strong&gt; is a compiled version of PHP that Facebook has built internally.
It decreases server load by about 50% and turns facebook.com into a 1GB binary
file rather than a collection of PHP files. Facebook compiles in about 10
minutes.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;BitTorrent&lt;/strong&gt; has been modified to distribute the HipHop binary to all
clusters and within clusters of machines.  It is used to roll out changes
quickly and efficiently. A new Facebook build can be rolled out in about 15
minutes on all machines.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Push Karma&lt;/strong&gt; is a tool that is used to privately track how reliable an
individual developer is.  It was emphasized that this is not a public shaming
tool, it is simply used to determine the chance that an individual developer's
changes might mess things up.  If someone is more prone to bugs then a last
minute change is less likely to be accepted into the release.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SVN/Git&lt;/strong&gt; are the SCMs of choice. The central trunk repository is SVN,
developers use Git for daily work and feature development.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;Take Away&lt;/h2&gt;

&lt;p&gt;The main take away is that if you want to focus on a bug-free push culture it's
important to get developers on the hook for their changes and bring them closer
to the final product.  The more QA and administration hurdles a piece of code
has to go over, the less likely this is to happen.  If a developer can see and
use his or her changes they are more likely to feel responsible for them and
they are more likely to catch bugs. The most important tools that promote this
mentality are the shadow branch, error tracking and push karma. The other three
tools that I believe are of great importance to a web-application company are
TDD/BDD, GateKeeper and Performance Monitoring.&lt;/p&gt;

&lt;h4&gt;The Shadow-Branch&lt;/h4&gt;

&lt;p&gt;The easiest way to implement shadow-branch is to have a staging server.  If you
don't already do this, you should. Staging servers are a great way to ensure
that the code you are releasing works in an environment that mimics production
as closely as possible. This usually also means using a live or replicated
version of a live dataset, an external url (even if it's only internally
available), and replicating things like content-delivery networks and user
access patterns.&lt;/p&gt;

&lt;h4&gt;Error Tracking&lt;/h4&gt;

&lt;p&gt;An error tracking tool is also critical, and it's important to dedicate someone
on your team to track these errors.  If you can't automate notifications so that
individual developers are notified of a bug, it's important to designate one
person the task of monitoring errors on your site.  If you don't know there are
errors, you aren't going to fix bugs.&lt;/p&gt;

&lt;h4&gt;Push Karma&lt;/h4&gt;

&lt;p&gt;Push Karma is not as critical and I wouldn't even recommend building a tool to
automate this process, but it's important that someone is aware of who is
introducing bugs and who is responsible for them.  Some adult person needs to be
responsible for determining if a developer has a higher chance of creating bugs,
and if they have gone through the appropriate code-review processes and test
driven development processes.  This ensures that last minute changes and large
releases are smoother. It's important to not publicly or privately shame people.
I think creating a stressful environment around bugs is not healthy. You want
developers that are creative, happy and not stressed about introducing bugs. But
it is important to know who needs a little extra code review and a little bit
more time to release a feature.&lt;/p&gt;

&lt;h4&gt;Test/Behavior Driven Development&lt;/h4&gt;

&lt;p&gt;I think the test automation speaks for itself.  If you are developing a large
web application you cannot manually test everything and you cannot determine all
of the side-effects of your code.  Test/Behavior Driven Development means you
are ensuring your code will work now and later down the road when someone else
makes a change. It's just common sense.&lt;/p&gt;

&lt;h4&gt;GateKeeper&lt;/h4&gt;

&lt;p&gt;I believe it's good to build features with an off-switch, if something goes
wrong you want to be able to turn things off.  Especially with the prevalence of
companies hosting their applications in the cloud, it's important to think about
how you can keep your site running when code or an external service doesn't
work.  Every feature should have an off switch that doesn't require bringing
down your website and re-booting.&lt;/p&gt;

&lt;h4&gt;Performance Monitoring&lt;/h4&gt;

&lt;p&gt;Studies show that small (under one second) degrade in page performance can
result in users walking away.  If a user is on your website for entertainment,
in other words for something other than checking their bank account, you need to
ensure that your site is performant. Make sure you either test performance or
monitor it with tools like NewRelic.&lt;/p&gt;

     
   &lt;img src="http://feeds.feedburner.com/~r/ablogaboutcode/~4/nbtKSy_R1DA" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://ablogaboutcode.com//2011/05/27/recap-and-thoughts-on-the-facebook-deploy-and-push-process</feedburner:origLink></entry>
 
 <entry>
   <title><![CDATA[Spork, RSpec, Sham and Caching Classes]]></title>
   <link href="http://feedproxy.google.com/~r/ablogaboutcode/~3/qFpAZZ4ajrc/spork-rspec-sham-and-caching-classes" />
   <updated>2011-05-18T00:00:00-07:00</updated>
   <id>http://ablogaboutcode.com//2011/05/18/spork-rspec-sham-and-caching-classes</id>
   <content type="html">
     
     &lt;p&gt;This is my favorite testing trifecta:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/rspec/rspec"&gt;RSpec&lt;/a&gt; as the testing framework.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://rubygems.org/gems/spork"&gt;Spork&lt;/a&gt; as the Distributed Ruby environment.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/panthomakos/sham"&gt;Sham&lt;/a&gt; to create model factories.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;The problem I ran into recently though was that when running RSpec tests using
Spork, changes to my models were not causing the files to re-load in the DRB
environment.  This was a big problem - it meant that the benefits provided by
Spork were virtually non-existent because every file change forced me to re-boot
my Spork server. To solve this problem I released a new version of Sham (0.5.0)
and made some changes to my spec_helper.rb and test.rb files. Here is what I
ended up with:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
Ensure your Gemfile is up to date, and update your bundle.


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="ss"&gt;:test&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;rspec-rails&amp;#39;&lt;/span&gt;
  &lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;spork&amp;#39;&lt;/span&gt;
  &lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;sham&amp;#39;&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
Update test.rb to ensure that you aren't caching classes when using Spork.


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cache_classes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;ENV&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;DRB&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;true&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
Modify your spec_helper.rb file, adding the Spork.each_run block.


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;spork&amp;#39;&lt;/span&gt;

&lt;span class="no"&gt;Spork&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;prefork&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;.&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="no"&gt;Spork&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each_run&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="ss"&gt;ActiveSupport&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="ss"&gt;:Dependencies&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;clear&lt;/span&gt;
  &lt;span class="ss"&gt;ActiveRecord&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="ss"&gt;:Base&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;instantiate_observers&lt;/span&gt;
  &lt;span class="ss"&gt;Sham&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="ss"&gt;:Config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;activate!&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="no"&gt;Spork&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;using_spork?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
You're done! &lt;a href="https://gist.github.com/979222"&gt;Here's a complete gist&lt;/a&gt;
of the files.
&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;The Spork.each_run block only gets run when you are actually in the Spork DRB
environment, this ensures that you aren't unnecessarily re-loading your classes
outside of Spork.  The ActiveSupport::Dependencies.clear line re-loads all your
models and controllers. The next line re-instantiates your observers. Finally
the Sham::Config.activate! line reloads Sham so that you can easily create valid
model objects. TDD/BDD in real-time is possible again!&lt;/p&gt;

     
   &lt;img src="http://feeds.feedburner.com/~r/ablogaboutcode/~4/qFpAZZ4ajrc" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://ablogaboutcode.com//2011/05/18/spork-rspec-sham-and-caching-classes</feedburner:origLink></entry>
 
 <entry>
   <title><![CDATA[ActiveRecord 3.1 - Mass-Assignment Roles]]></title>
   <link href="http://feedproxy.google.com/~r/ablogaboutcode/~3/2gKLhkB78bE/activerecord-3-1-mass-assignment-roles" />
   <updated>2011-05-12T00:00:00-07:00</updated>
   <id>http://ablogaboutcode.com//2011/05/12/activerecord-3-1-mass-assignment-roles</id>
   <content type="html">
     
     &lt;p&gt;&lt;a href="https://gist.github.com/958283"&gt;Rails 3.1 introduces the concept of mass-assignment roles&lt;/a&gt; which allow you
to specify accessible attributes for a specific permission or role. For
instance, if you wanted your users to be able to edit their names, but not their
permissions you could limit their accessible attributes but allow administrators
to edit permissions:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="ss"&gt;ActiveRecord&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="ss"&gt;:Base&lt;/span&gt;
  &lt;span class="n"&gt;attr_accessible&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt;
  &lt;span class="n"&gt;attr_accessible&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:permission&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:as&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:admin&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;While this syntax is awesome the AR#new, AR#create and AR#update_attributes
syntax is horrible:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:user&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:as&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:admin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;It seems like the same primitive syntax that AR#find used in Rails 2.x:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:all&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:conditions&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;name = ?&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;That was replaced with elegant chaining in Rails 3.0:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;name = ?&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Why not do the same with mass-assignment roles?&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;as&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:admin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:user&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;or&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;as&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:admin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;attributes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:user&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;I can see the conflict this might cause with scopes, but maybe there's an
elegant balance so that we aren't passing multiple hash parameters to AR#new,
AR#create and AR#update_attributes.&lt;/p&gt;

     
   &lt;img src="http://feeds.feedburner.com/~r/ablogaboutcode/~4/2gKLhkB78bE" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://ablogaboutcode.com//2011/05/12/activerecord-3-1-mass-assignment-roles</feedburner:origLink></entry>
 
 <entry>
   <title><![CDATA[Spork Testing Tip - Caching Classes]]></title>
   <link href="http://feedproxy.google.com/~r/ablogaboutcode/~3/poDL6rx4L8s/spork-testing-tip-caching-classes" />
   <updated>2011-05-09T00:00:00-07:00</updated>
   <id>http://ablogaboutcode.com//2011/05/09/spork-testing-tip-caching-classes</id>
   <content type="html">
     
     &lt;p&gt;&lt;a href="https://github.com/timcharper/spork"&gt;Spork&lt;/a&gt; is a great gem that runs a
distributed Ruby server which you can run your tests against. The benefit of
using a DRb server is that you don't have to wait for Rails to boot up every
time you want to run your RSpec and Cucumber tests, which means doing test or
behavior driven development with these testing frameworks in Rails is actually
possible because you can avoid the 30+ second boot times that often accompany
large Rails applications. Generally to make Spork useful you need to not cache
your classes in your testing environment by adding the following line to
environments/test.rb:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cache_classes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The reason for this is that you want spork to re-load the related classes one
every test-run, so that changes that you make to your classes are re-loaded
rather than using a cached version from when Spork first booted. The downside of
this approach is that you lose the cached class performance boost to your tests
when you are running outside of the DRb server, for example in your continuous
integration environment. To remedy this simply change the configuration line to:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cache_classes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;ENV&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;DRB&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;true&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Spork sets the &lt;code&gt;ENV['DRB']&lt;/code&gt; variable to &lt;code&gt;true&lt;/code&gt; when it is booted, so this line
lets you conditionally cache classes depending on if you are running in the
spork distributed ruby environment. Happy testing!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;UPDATE (June 1, 2011)&lt;/strong&gt;: I've written a more
&lt;a href="http://ablogaboutcode.com/2011/05/18/spork-rspec-sham-and-caching-classes/"&gt;complete post on cached-classes, spork, sham and Rspec&lt;/a&gt;, which includes a
gist of the complete spec_helper.rb file, test.rb file and Gemfile.&lt;/p&gt;

     
   &lt;img src="http://feeds.feedburner.com/~r/ablogaboutcode/~4/poDL6rx4L8s" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://ablogaboutcode.com//2011/05/09/spork-testing-tip-caching-classes</feedburner:origLink></entry>
 
 <entry>
   <title><![CDATA[Proper Git Commit Messages and an Elegant Git History]]></title>
   <link href="http://feedproxy.google.com/~r/ablogaboutcode/~3/IC5rAjNRO4I/proper-git-commit-messages-and-an-elegant-git-history" />
   <updated>2011-03-23T00:00:00-07:00</updated>
   <id>http://ablogaboutcode.com//2011/03/23/proper-git-commit-messages-and-an-elegant-git-history</id>
   <content type="html">
     
     &lt;p&gt;Have you ever run a git log command, looked at the output, and though, "WTF
happened here?". I ran &lt;code&gt;git log&lt;/code&gt; on a project yesterday and found myself staring
at this git commit history:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;commit 26ae8c3f0cf2a3d0b4aa52570711b2047b939592
Merge: 02f1f9a a73ecc6
Author: Programmer One 
Date:   Tue Mar 22 12:03:59 2011 -0700

    Merge branch 'master' of github.com:exampe/app

commit 02f1f9a146936373fcf8918036684ea209782a4b
Author: Programmer One 
Date:   Tue Mar 22 12:01:21 2011 -0700

    fix test

commit a73ecc678165284627f67eeede0eb43512422e71
Merge: f8cbf68 62cab2b
Author: Programmer Two 
Date:   Tue Mar 22 10:17:59 2011 -0700

    Merge branch 'master' of github.com:example/app

commit f8cbf680943e81aa57c5e09226f63817c09a13b5
Author: Programmer Two 
Date:   Tue Mar 22 10:16:53 2011 -0700

    added logged out user page
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;What am I supposed to do with that? This tells me nothing about what's happening
on in the project. If I ran the same command six months from now I would have no
idea what test "fix test" was referring to or what user related page "user page"
was referring to. In fact I have no idea what any of this means now. Let's take
a look at the issues with these commits and explore how we can improve them.&lt;/p&gt;

&lt;h2&gt;What's the big deal with git log anyways?&lt;/h2&gt;

&lt;p&gt;Joel Spolsky put it best when he said, "The difference between a tolerable
programmer and a great programmer is not how many programming languages they
know, and it’s not whether they prefer Python or Java. It’s whether they can
communicate their ideas... By writing clear comments and technical specs, they
let other programmers understand their code, which means other programmers can
use and work with their code instead of rewriting it. Absent this, their code is
worthless. By writing clear technical documentation for end users, they allow
people to figure out what their code is supposed to do, which is the only way
those users can see the value in their code."&lt;/p&gt;

&lt;p&gt;This same concept applies to git commit messages and git history.  The end user
in this case is your fellow programmers and you a couple months later when you
don't remember what you did to fix that bug. If you want to be a good programmer
you'll write good commit messages that others can understand, that properly
documents what you have done. One of the best skills you can learn as a
programmer is to write about your code and to explain what you are doing. Git
commit messages and code comments are the best place to start.&lt;/p&gt;

&lt;h2&gt;Merge and Rebase Commits&lt;/h2&gt;

&lt;p&gt;When your git log has as many merge commits as it does normal commits it means
you need to start rebasing some of your smaller commits.  If your project
doesn't have any merge commits, it means you need to start using branches and
merging your larger feature branch. Every project should have it's own
guidelines around merging and rebasing.&lt;/p&gt;

&lt;p&gt;Why should you merge and rebase? Because using both methods provides a clean
history and it helps differentiate a large branch merge from a simple fix or
patch. Merge commits should have their own comments and they should provide a
history of milestones.&lt;/p&gt;

&lt;p&gt;The difference between merging branches and rebasing branches really comes down
to how you want to format your history.  In my opinion when you have a small
atomic fix that is a single commit it's always best to rebase.  When you have a
large feature history in a separate branch that you've been working on for a
while it's always best to merge.  Anything between these two is really up for
grabs, but think about what you want to convey when you merge your code into
another branch. &lt;strong&gt;Is the merge commit really as significant as your original
commit?&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;What should I include in my commit message?&lt;/h2&gt;

&lt;p&gt;The three basic things to include are a summary or title, a detailed
description, and a tracking or ticket number, if it's applicable. Here is a
sample git commit with all that information:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Fixed bug where user can't signup.

Users were unable to register if they hadn't visited the plans
and pricing page because we expected that tracking
information to exist for the logs we create after a user
signs up.  I fixed this by adding a check to the logger
to ensure that if that information was not available
we weren't trying to write it.

[Fixes #2873942]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is usually followed by the change information for this commit that is
automatically generated by git. Because of the way git logging functions format
commit messages and summaries, it's best to not exceed 50 characters for the
title or summary line. This makes it easier to create summary logs and perform
interactive merging and rebasing. It's also best to use about 72 characters for
each line of the detailed description.  The reason for a seemingly arbitrary 72
characters is that a typical terminal window is 80 characters and the commit
message is indented about 4 characters. If you leave an additional 4 characters
on the other side for nice formatting this leaves you with 72 characters per
line.&lt;/p&gt;

&lt;p&gt;The tracking or ticket number is optional, but most projects use some kind of
tracking or bug management tool so it's nice to be able to keep track of
projects and bugs with a ticket number.  It's often possible to integrate git
with your tracking utility as well, so that your commits appear in your project
tickets.&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;As always, this is all up for some customization.  There are no hard-and-fast
rules about rebasing and merging, but be consistent.  You and your fellow
developers should agree on a set of rules for when to rebase and merge.  There
is no 100% correct git commit message template, but use something that makes
sense for your project. The guidelines you develop should help produce both a
good concise history and a good expanded history.  The main thing to take away
is that you should actively be thinking about your git history and how you can
use it as a tool to understand a project's history.  Treat it as an exercise in
making yourself a better programmer.&lt;/p&gt;

     
   &lt;img src="http://feeds.feedburner.com/~r/ablogaboutcode/~4/IC5rAjNRO4I" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://ablogaboutcode.com//2011/03/23/proper-git-commit-messages-and-an-elegant-git-history</feedburner:origLink></entry>
 
 <entry>
   <title><![CDATA[Rails 3 Patch: Encoding Bug while Action Caching with MemCacheStore]]></title>
   <link href="http://feedproxy.google.com/~r/ablogaboutcode/~3/-jBVKQDvzUo/rails-3-patch-encoding-bug-while-action-caching-with-memcachestore" />
   <updated>2011-03-08T00:00:00-08:00</updated>
   <id>http://ablogaboutcode.com//2011/03/08/rails-3-patch-encoding-bug-while-action-caching-with-memcachestore</id>
   <content type="html">
     
     &lt;p&gt;While upgrading an application from Rails 2.3 and Ruby 1.8.7 to Rails 3.0 and
Ruby 1.9.2 I ran into the following error message:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Encoding::CompatibilityError: incompatible encoding regexp match
(ASCII-8BIT regexp with UTF-8 string)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;After some searching around I was able to determine that this was a
&lt;code&gt;MemCacheStore&lt;/code&gt; issue. In particular it was caused when trying to perform action
caching on a URL that contained special UTF-8 encoded characters, like the
umlaut.  As luck would have it
&lt;a href="https://rails.lighthouseapp.com/projects/8994/tickets/6225-memcachestore-cant-deal-with-umlauts-and-special-characters"&gt;someone else was experiencing this same issue&lt;/a&gt;, but their lighthouse
ticket had been around for a good two months without any activity. I guess not
too many Ruby on Rails developers are performing action caching on pages with
UTF-8 encoded parameters. Anyways, I took it upon myself to create a patch to
solve this issue.&lt;/p&gt;

&lt;p&gt;The bug was located in ActiveSupport's &lt;code&gt;mem_cache_store.rb&lt;/code&gt; on line 33, where
the following regular expression was defined:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="no"&gt;ESCAPE_KEY_CHARS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/[\x00-\x20%\x7F-\xFF]/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;By itself this doesn't seem like much of an issue, but what you might not
realize is that the Rails source code is encoded in US-ASCII, so when your UTF-8
encoded string is gsubbed with this regular expression, you get an
&lt;code&gt;Encoding::CompatibilityError&lt;/code&gt; on the first line of the
&lt;code&gt;ActiveSupport::Cache::MemCacheStrore#escape_key&lt;/code&gt; function:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;escape_key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gsub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;ESCAPE_KEY_CHARS&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;%&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getbyte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;upcase&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;213&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:md5:&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="ss"&gt;Digest&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="ss"&gt;:MD5&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hexdigest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;250&lt;/span&gt;
  &lt;span class="n"&gt;key&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;My solution to this problem was to change the escape_key function so that it was
compatible with any encoded string.  I decided that the simplest solution would
be to force the memcached key into the same encoding as the regular expression,
but to do that I would need to duplicate the key string, because performing a
force_encoding on a string actually changes the string in memory, it doesn't
create a new string.  If the string is not duplicated, the original key will get
sent back to the Rails application with a different encoding and this can cause
issues if you perform any concatenation with that string, since most of the
strings in your app will probably be encoded in UTF-8. Try this out for yourself
in you console:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="irb"&gt;&lt;span class="gp"&gt;irb(main):001:0&amp;gt; &lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;bar&amp;quot;&lt;/span&gt;
&lt;span class="go"&gt;=&amp;gt; &amp;quot;bar&amp;quot;&lt;/span&gt;
&lt;span class="gp"&gt;irb(main):001:0&amp;gt; &lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encoding&lt;/span&gt;
&lt;span class="go"&gt;=&amp;gt; #&amp;lt;Encoding:UTF-8&amp;gt;&lt;/span&gt;
&lt;span class="gp"&gt;irb(main):001:0&amp;gt; &lt;/span&gt;&lt;span class="n"&gt;foo2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;force_encoding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;Encoding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="ss"&gt;:ASCII_8BIT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="go"&gt;=&amp;gt; &amp;quot;bar&amp;quot;&lt;/span&gt;
&lt;span class="gp"&gt;irb(main):001:0&amp;gt; &lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;object_id&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;foo2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;object_id&lt;/span&gt;
&lt;span class="go"&gt;=&amp;gt; true&lt;/span&gt;
&lt;span class="gp"&gt;irb(main):001:0&amp;gt; &lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encoding&lt;/span&gt;
&lt;span class="go"&gt;=&amp;gt; #&amp;lt;Encoding:ASCII-8BIT&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Once the string was encoded in ASCII-8BIT, it was compatible with the regular
expression and no error would be raised. Here's the final function I came up
with:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;escape_key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="c1"&gt;# Fix for EncodedKeyCacheBehavior failing tests in caching_test.rb.&lt;/span&gt;
  &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dup&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;respond_to?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:encoding&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encoding&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;ESCAPE_KEY_CHARS&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encoding&lt;/span&gt;
    &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;force_encoding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;ESCAPE_KEY_CHARS&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encoding&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gsub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;ESCAPE_KEY_CHARS&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;%&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getbyte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;upcase&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;213&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:md5:&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="ss"&gt;Digest&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="ss"&gt;:MD5&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hexdigest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;250&lt;/span&gt;
  &lt;span class="n"&gt;key&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Please give my patch a try, it includes tests for all encoding types and special
characters. If you get your tests passing please leave a comment
&lt;a href="https://rails.lighthouseapp.com/projects/8994/tickets/6225-memcachestore-cant-deal-with-umlauts-and-special-characters"&gt;on the lighthouse ticket&lt;/a&gt; that you were able to verify the fix.&lt;/p&gt;

&lt;p&gt;Update - &lt;a href="https://github.com/rails/rails/pull/219"&gt;This patch&lt;/a&gt; has been merged
into the rails branch as of April 28, 2011.&lt;/p&gt;

     
   &lt;img src="http://feeds.feedburner.com/~r/ablogaboutcode/~4/-jBVKQDvzUo" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://ablogaboutcode.com//2011/03/08/rails-3-patch-encoding-bug-while-action-caching-with-memcachestore</feedburner:origLink></entry>
 
 <entry>
   <title><![CDATA[Hoptoad Error Tracking in Ruby on Rails]]></title>
   <link href="http://feedproxy.google.com/~r/ablogaboutcode/~3/quXJZveRcVM/hoptoad-error-tracking-in-ruby-on-rails" />
   <updated>2011-02-25T00:00:00-08:00</updated>
   <id>http://ablogaboutcode.com//2011/02/25/hoptoad-error-tracking-in-ruby-on-rails</id>
   <content type="html">
     
     &lt;p&gt;What do you do with error messages from your production servers? I used to have
them all sent to my inbox.  I would then have to filter them based on if they
were coming from delayed jobs or what part of the site they were relevant to. I
would then have to sift through this massive email to find the stack-trace of
the environment variables, it was just a pain in the ass.  I recently started
using &lt;a href="http://hoptoadapp.com/pages/home"&gt;Hoptoad&lt;/a&gt; to track my error messages.
Life has been much easier since that decision. Hoptoad is an online application
that acts as an API for receiving your error messages, as well as website for
tracking, grouping and resolving those error messages.&lt;/p&gt;

&lt;p&gt;The Hoptoad interface is quite simple: related errors are grouped together and
you can 'resolve' them with a simple switch to indicate that you have taken care
of the issue.  This is awesome because you don't have to resolve 10 error
messages when there's really only one thing that's going wrong. Hoptoad also
tracks deployments and errors/minute for some additional fun stats. For
organization it splits your error summary, stack trace, environment variables,
request parameters, session variables and similar errors into separate tabs for
easy navigation. Hoptoad is a &lt;a href="https://hoptoadapp.com/account/new"&gt;paid service&lt;/a&gt;
but they offer a free plan for a single project, single user and five error
messages per minute so that you can try the service out, and their 'tadpole', or
smallest paid, plan comes in at $5 per month.&lt;/p&gt;

&lt;p&gt;My favorite gem to get started using Hoptoad is
&lt;a href="https://rubygems.org/gems/hoptoad_notifier"&gt;hoptoad_notifier&lt;/a&gt;. You can get
detailed installation instructions
&lt;a href="https://github.com/thoughtbot/hoptoad_notifier"&gt;here&lt;/a&gt;. My setup goes something
like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
Add the gem to my Gemfile.

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;hoptoad_notifier&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
Install my bundle.

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;bundle install
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
Generate my api key yaml file.

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;rails generate hoptoad --api-key
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
Add a deploy notification to my after_restart script.

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;cd &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;release_path&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &amp;amp;&amp;amp; rake hoptoad:deploy&lt;/span&gt;
&lt;span class="s2"&gt;TO=&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="vi"&gt;@configuration&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:environment&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&lt;/span&gt;
&lt;span class="s2"&gt;REVISION=&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="vi"&gt;@configuration&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:revision&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&lt;/span&gt;
&lt;span class="s2"&gt;REPO=&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="vi"&gt;@configuration&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:repository&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
Add a notification handler to my delayed jobs.

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="c1"&gt;# in config/initializers/delayed_job_with_hoptoad.rb&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Delayed&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Worker&lt;/span&gt;
  &lt;span class="k"&gt;alias&lt;/span&gt; &lt;span class="ss"&gt;:handle_failed_job_without_hoptoad&lt;/span&gt; &lt;span class="ss"&gt;:handle_failed_job&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;handle_failed_job&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;job&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="no"&gt;HoptoadNotifier&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;notify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;handle_failed_job_without_hoptoad&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;job&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;You're set to go. All errors in your app and in your delayed job processes will
get posted to Hoptoad, and Hoptoad will track your deployments.&lt;/p&gt;

     
   &lt;img src="http://feeds.feedburner.com/~r/ablogaboutcode/~4/quXJZveRcVM" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://ablogaboutcode.com//2011/02/25/hoptoad-error-tracking-in-ruby-on-rails</feedburner:origLink></entry>
 
 <entry>
   <title><![CDATA[Scopes in Rails 3]]></title>
   <link href="http://feedproxy.google.com/~r/ablogaboutcode/~3/B-y29BsO2gc/scopes-in-rails-3" />
   <updated>2011-02-19T00:00:00-08:00</updated>
   <id>http://ablogaboutcode.com//2011/02/19/scopes-in-rails-3</id>
   <content type="html">
     
     &lt;p&gt;Scopes have become much more useful in Ruby on Rails 3 with the adoption of
&lt;a href="https://github.com/rails/arel"&gt;Arel&lt;/a&gt; into ActiveRecord. The first and most
obvious benefit related to scopes is that everything is scoped! That means you
no longer have to use find(...) on an ActiveRecord model and have a query
immediately be executed. You can actually build queries up and only execute
them when you use them. For example:&lt;/p&gt;

&lt;p&gt;In Rails 2.x the find method worked like this:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="ss"&gt;:all&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;:joins&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:profile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;:conditions&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;profile.age = ?&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;33&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;This would then execute the query and find all users with age 33. In Rails 3.x
this is much simpler:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;joins&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:profile&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;profile.age = ?&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;33&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Not only is this more readable since you don't have to put your entire query
into a single function call, but the main difference between these two commands
is that the second doesn't execute a query. You actually have to call .all,
.count, .each or .first to get the query to execute. What's great about that?
Well, it means you can chain conditions together before you execute them:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;joins&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:profile&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;profile.age = ?&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;33&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;users.name = ?&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nil?&lt;/span&gt;
&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;profile.email = ?&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nil?&lt;/span&gt;
&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;This really shines when you combine it with scopes. For instance, if we want to
simplify the above code, we can do the following:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;
  &lt;span class="n"&gt;scope&lt;/span&gt; &lt;span class="ss"&gt;:by_age&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;lambda&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;joins&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:profile&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;profile.age = ?&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nil?&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="n"&gt;scope&lt;/span&gt; &lt;span class="ss"&gt;:by_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;lambda&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nil?&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;scope&lt;/span&gt; &lt;span class="ss"&gt;:by_email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;lambda&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;joins&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:profile&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;profile.email = ?&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nil?&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;by_age&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;33&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;by_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;by_email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:email&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Isn't that just awesome!? Not only is the code easier to read and understand,
but it's re-usable and scoped! Here's one more example:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Tag&lt;/span&gt;
  &lt;span class="n"&gt;belongs_to&lt;/span&gt; &lt;span class="ss"&gt;:post&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Post&lt;/span&gt;
  &lt;span class="n"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:tags&lt;/span&gt;
  &lt;span class="n"&gt;belongs_to&lt;/span&gt; &lt;span class="ss"&gt;:user&lt;/span&gt;

  &lt;span class="n"&gt;scope&lt;/span&gt; &lt;span class="ss"&gt;:tagged&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;lambda&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;joins&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:tags&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;tags.name = ?&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;posts.id&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;
  &lt;span class="n"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:posts&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# How many of my posts are tagged with &amp;#39;ruby-on-rails&amp;#39;?&lt;/span&gt;
&lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;users.id = ?&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;232423&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;posts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tagged&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;ruby-on-rails&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;




     
   &lt;img src="http://feeds.feedburner.com/~r/ablogaboutcode/~4/B-y29BsO2gc" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://ablogaboutcode.com//2011/02/19/scopes-in-rails-3</feedburner:origLink></entry>
 
 <entry>
   <title><![CDATA[Ruby Autoloading Explained]]></title>
   <link href="http://feedproxy.google.com/~r/ablogaboutcode/~3/B4iN0Bl-NVk/ruby-autoloading-explained" />
   <updated>2011-01-17T00:00:00-08:00</updated>
   <id>http://ablogaboutcode.com//2011/01/17/ruby-autoloading-explained</id>
   <content type="html">
     
     &lt;p&gt;In the ruby programming language a distinction is made between loading and
autoloading.  For those of you familiar with Rails, this will shed some light on
the change from &lt;code&gt;config.load_paths&lt;/code&gt; to &lt;code&gt;config.autoload_paths&lt;/code&gt; in Rails 3. The
difference lies in &lt;strong&gt;when&lt;/strong&gt; the class is actually called/initialized.&lt;/p&gt;

&lt;p&gt;Let's say I have defined a SpecialLibrary class:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="c1"&gt;# In special_library.rb&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SpecialLibrary&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Loading Special Library&amp;quot;&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;.&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;When I load or require the class, the entire class code is run:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="irb"&gt;&lt;span class="gp"&gt;irb(main):001:0&amp;gt; &lt;/span&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;special_library&amp;#39;&lt;/span&gt;
&lt;span class="go"&gt;Loading Special Library&lt;/span&gt;
&lt;span class="go"&gt;=&amp;gt; true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;When I autoload the class, the class code is only run when I actually use the
class:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="irb"&gt;&lt;span class="gp"&gt;irb(main):001:0&amp;gt; &lt;/span&gt;&lt;span class="nb"&gt;autoload&lt;/span&gt; &lt;span class="ss"&gt;:SpecialLibrary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;special_library&amp;#39;&lt;/span&gt;
&lt;span class="go"&gt;=&amp;gt; nil&lt;/span&gt;
&lt;span class="gp"&gt;irb(main):002:0&amp;gt; &lt;/span&gt;&lt;span class="no"&gt;SpecialLibrary&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;
&lt;span class="go"&gt;Loading Special Library&lt;/span&gt;
&lt;span class="go"&gt;=&amp;gt; #&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The reason &lt;code&gt;config.load_paths&lt;/code&gt; was changed to &lt;code&gt;config.autoload_paths&lt;/code&gt; in Rails 3
is because the paths defined here were being auto-loaded and not simply
required, so &lt;code&gt;config.autoload_paths&lt;/code&gt; is more descriptive and accurately
describes the behavior.&lt;/p&gt;

     
   &lt;img src="http://feeds.feedburner.com/~r/ablogaboutcode/~4/B4iN0Bl-NVk" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://ablogaboutcode.com//2011/01/17/ruby-autoloading-explained</feedburner:origLink></entry>
 
 <entry>
   <title><![CDATA[Using Custom Error Messages for Cleaner Code]]></title>
   <link href="http://feedproxy.google.com/~r/ablogaboutcode/~3/8h6tG4L6S0g/using-custom-error-messages-for-cleaner-code" />
   <updated>2011-01-03T00:00:00-08:00</updated>
   <id>http://ablogaboutcode.com//2011/01/03/using-custom-error-messages-for-cleaner-code</id>
   <content type="html">
     
     &lt;p&gt;Either because you dread 500 Error Messages or you're on some kind of JSON kick
you find yourself writing this style of ruby code:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Group&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;join&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;permitted?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="ss"&gt;:success&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;:message&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;You don&amp;#39;t have the proper permissions to join this group.&amp;quot;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;elsif&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;member?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="ss"&gt;:success&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;:message&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;You are already a member of this group.&amp;quot;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;members&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;:user&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;:success&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:message&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Welcome to the Group!&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GroupsController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationController&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;join&lt;/span&gt;
    &lt;span class="vi"&gt;@group&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Group&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@group&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;current_user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:success&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
      &lt;span class="n"&gt;flash&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:notice&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:message&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
      &lt;span class="n"&gt;redirect_to&lt;/span&gt; &lt;span class="vi"&gt;@group&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="n"&gt;flash&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:error&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:message&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
      &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="ss"&gt;:action&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;request&amp;#39;&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Why?  Well because you don't want to risk throwing a Ruby Exception when it
could cause a 500 Error Message for a user, and you want to be able to control
error messages from your Model.  For example, the join method could return any
one of the following responses:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;:success&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:message&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;You are already a member of this group.&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="ss"&gt;:success&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;:message&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;You don&amp;#39;t have the proper permissions to join this group.&amp;quot;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;:success&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:message&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Welcome to the Group!.&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;So what's wrong with that?  Well, there are a couple of things.&lt;/p&gt;

&lt;p&gt;You introduced conditionals into your model and controller that are entirely
unnecessary.  Conditionals are not the worst thing in the world, but they create
divergent code paths, they make your code harder to understand and harder to
test.  If you can avoid them, it's easier for the next programmer to figure out
what you had in mind.&lt;/p&gt;

&lt;p&gt;You created an additional dependency between your model and controller code.
Dependencies lead to bad things.  The more modular your code is the easier it is
to test and the more versatile it is.  It's easier to use modular code in
background jobs and other objects and functions.&lt;/p&gt;

&lt;p&gt;Thirdly, and most importantly, you are replicating a perfectly good programming
concept known as Exceptions.  Exceptions are a program's way of saying:
something went wrong - something is not as it should be.  Any they are great to
use because they are easy to read and they break the normal code flow, which is
what you would expect if something went wrong.&lt;/p&gt;

&lt;p&gt;How do we fix this code?  Simple: we use Exceptions.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
Create the custom exceptions.

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Group&lt;/span&gt;
  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Error&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Standard&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;StandardError&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AlreadyAMember&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Standard&lt;/span&gt;
      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;message&lt;/span&gt;
        &lt;span class="s2"&gt;&amp;quot;You are already a member of this group.&amp;quot;&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NotPermittedToJoin&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Standard&lt;/span&gt;
      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;message&lt;/span&gt;
        &lt;span class="s2"&gt;&amp;quot;You don&amp;#39;t have the proper permissions to join this group.&amp;quot;&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
Raise the exceptions.

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Group&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;join&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="ss"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="ss"&gt;:NotPermittedToJoin&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;permitted?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="ss"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="ss"&gt;:AlreadyAMember&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;member?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;members&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;:user&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
Catch the exceptions.

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GroupsController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationController&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;join&lt;/span&gt;
    &lt;span class="vi"&gt;@group&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Group&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@group&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt; &lt;span class="n"&gt;current_user&lt;/span&gt;
    &lt;span class="n"&gt;flash&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:notice&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Welcome to the Group!&amp;quot;&lt;/span&gt;
    &lt;span class="n"&gt;redirect_to&lt;/span&gt; &lt;span class="vi"&gt;@group&lt;/span&gt;
  &lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="ss"&gt;Group&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="ss"&gt;:Error&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Standard&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;exception&lt;/span&gt;
    &lt;span class="n"&gt;flash&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:error&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;exception&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;
    &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="ss"&gt;:action&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;request&amp;#39;&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;A gist of this code can be found &lt;a href="https://gist.github.com/1230673"&gt;here&lt;/a&gt;.&lt;/p&gt;

     
   &lt;img src="http://feeds.feedburner.com/~r/ablogaboutcode/~4/8h6tG4L6S0g" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://ablogaboutcode.com//2011/01/03/using-custom-error-messages-for-cleaner-code</feedburner:origLink></entry>
 
 <entry>
   <title><![CDATA[A Simple Ruby Script to Gracefully Terminate System Processes]]></title>
   <link href="http://feedproxy.google.com/~r/ablogaboutcode/~3/PYHt1rBhh1w/a-simple-ruby-script-to-gracefully-terminate-system-processes" />
   <updated>2010-12-18T00:00:00-08:00</updated>
   <id>http://ablogaboutcode.com//2010/12/18/a-simple-ruby-script-to-gracefully-terminate-system-processes</id>
   <content type="html">
     
     &lt;p&gt;To gracefully terminate a system processes you issue the &lt;code&gt;kill -15&lt;/code&gt; command. You
then usually monitor the process to ensure that it terminates.  If it does not,
you issue the &lt;code&gt;kill -9&lt;/code&gt; command to ensure that it does.  Since this is a pretty
common task, I've created a simple Ruby script to automate it.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="c1"&gt;#!/usr/bin/env ruby&lt;/span&gt;

&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;timeout&amp;quot;&lt;/span&gt;

&lt;span class="no"&gt;ARGV&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="k"&gt;begin&lt;/span&gt;
        &lt;span class="no"&gt;Process&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;kill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;TERM&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="ss"&gt;Timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="ss"&gt;:timeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
            &lt;span class="k"&gt;begin&lt;/span&gt;
              &lt;span class="nb"&gt;sleep&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
            &lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sb"&gt;`ps -p &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;match&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="ss"&gt;Timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="ss"&gt;:Error&lt;/span&gt;
        &lt;span class="no"&gt;Process&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;kill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;KILL&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;This script will issue the &lt;code&gt;kill -15&lt;/code&gt; command, monitor the process for up to 30
seconds to make sure it terminates, and if it still exists, issue the &lt;code&gt;kill -9&lt;/code&gt;
command.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;gracefully-kill 1234
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;You can also call this script for multiple process ids:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;gracefully-kill 1234 5678 91011
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;




     
   &lt;img src="http://feeds.feedburner.com/~r/ablogaboutcode/~4/PYHt1rBhh1w" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://ablogaboutcode.com//2010/12/18/a-simple-ruby-script-to-gracefully-terminate-system-processes</feedburner:origLink></entry>
 
 <entry>
   <title><![CDATA[Sham - Lightweight Factories for Ruby on Rails Testing]]></title>
   <link href="http://feedproxy.google.com/~r/ablogaboutcode/~3/e2GMiNjLo94/sham-lightweight-factories-for-ruby-on-rails-testing" />
   <updated>2010-12-06T00:00:00-08:00</updated>
   <id>http://ablogaboutcode.com//2010/12/06/sham-lightweight-factories-for-ruby-on-rails-testing</id>
   <content type="html">
     
     &lt;p&gt;In general test-driven development in Rails couldn't be easier, but while
writing your tests you'll eventually run into the case where you need to create
a valid model so that you can test some extended functionality. Take a look at
this RSpec test.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="no"&gt;Cart&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;should be able to calculate the total price&amp;quot;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="p"&gt;\&lt;/span&gt;
      &lt;span class="ss"&gt;:username&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;username@example.com&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="ss"&gt;:password&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;password&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
      &lt;span class="ss"&gt;:password_confirmation&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;password&amp;quot;&lt;/span&gt;
    &lt;span class="n"&gt;one&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Item One&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:price&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:weight&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="n"&gt;two&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Item Two&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:price&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:weight&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="n"&gt;cart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Cart&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;:user&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;
    &lt;span class="n"&gt;li1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;LineItem&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;:cart&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;cart&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:item&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;one&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:quantity&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="n"&gt;li2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;LineItem&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;:cart&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;cart&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:item&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;two&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:quantity&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="n"&gt;cart&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;li1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;li2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The problem with this approach is that if you modify the validations on &lt;code&gt;Item&lt;/code&gt;,
&lt;code&gt;Cart&lt;/code&gt; or &lt;code&gt;User&lt;/code&gt; you'll end up going back and adjusting your test.  For example,
if you required that items had a quantity that was positive, you would have to
go back and add a quantity parameter every time you create an item -  major pain
in the ass.  Not to mention your tests start to become quite wordy.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="n"&gt;one&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Item One&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;:price&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;:weight&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;:quantity&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Fortunately there are a couple of gems that are available for creating
factories. Factories are "minimally valid models" that can be reused to create
valid models.  I have experimented with a couple of options, like
&lt;a href="https://github.com/thoughtbot/factory_girl"&gt;factory girl&lt;/a&gt; or
&lt;a href="https://github.com/notahat/machinist"&gt;machinist&lt;/a&gt;. But I ran into issues with
sequences (sequentially generated attributes that are used to avoid validation
errors) or I disliked the way the gems and factories were setup and used in my
tests.  This led me to create my own lightweight factory gem called
&lt;a href="https://github.com/panthomakos/sham"&gt;sham&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here's how you can get started using Sham.&lt;/p&gt;

&lt;h2&gt;1. Install the Sham Gem.&lt;/h2&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;gem install sham
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Or add it to your Gemfile:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;sham&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;And re-install your Bundle:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;bundle install
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h2&gt;2a. If you are using &lt;a href="http://rspec.info/"&gt;RSpec&lt;/a&gt; or &lt;a href="http://www.ensta.fr/~diam/ruby/online/ruby-doc-stdlib/libdoc/test/unit/rdoc/classes/Test/Unit.html"&gt;Test::Unit&lt;/a&gt;, enable Sham in your test.rb file.&lt;/h2&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;after_initialize&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="ss"&gt;Sham&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="ss"&gt;:Config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;activate!&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h2&gt;2b. If you are using &lt;a href="http://cukes.info/"&gt;Cucumber&lt;/a&gt;, enable Sham in your features/support/env.rb file.&lt;/h2&gt;&lt;/h2&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;sham&amp;#39;&lt;/span&gt;
&lt;span class="ss"&gt;Sham&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="ss"&gt;:Config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;activate!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h2&gt;3. Create factories with your default attributes.&lt;/h2&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="c1"&gt;# in sham/item_sham.rb&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Item&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Sham&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;options&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;:quantity&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:weight&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:price&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Sham&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;string!&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# in sham/line_item_sham.rb&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LineItem&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Sham&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;options&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;:quantity&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:item&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;Sham&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="ss"&gt;:Base&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# in sham/cart_sham.rb&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Cart&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Sham&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;options&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;:user&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;Sham&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="ss"&gt;:Base&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# in sham/user_sham.rb&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="ss"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="ss"&gt;:Sham&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;options&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="ss"&gt;:username&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;Sham&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;string!&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;@example.com&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="ss"&gt;:password&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;password&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="ss"&gt;:password_confirmation&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;password&amp;quot;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h2&gt;4. Write Your Tests.&lt;/h2&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="no"&gt;Cart&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;should be able to calculate the total price&amp;quot;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;cart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Cart&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sham!&lt;/span&gt;
    &lt;span class="n"&gt;li1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;LineItem&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sham!&lt;/span&gt; &lt;span class="ss"&gt;:cart&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;cart&lt;/span&gt;
    &lt;span class="n"&gt;li2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;LineItem&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sham!&lt;/span&gt; &lt;span class="ss"&gt;:cart&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;cart&lt;/span&gt;
    &lt;span class="n"&gt;cart&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;li1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;li2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Much Simpler!  Here are a couple things to keep in mind:&lt;/p&gt;

&lt;h4&gt;You can override attributes.&lt;/h4&gt;

&lt;p&gt;You can override any attributes that have been defined in a sham.  For example,
either of the following is perfectly acceptable:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="no"&gt;Item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sham!&lt;/span&gt; &lt;span class="ss"&gt;:quantity&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
&lt;span class="no"&gt;Item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sham!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h4&gt;You can create random strings.&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;Sham.string!&lt;/code&gt; will generates a random string that can be used as a filler or to
avoid validation issues.  For example if there is a requirement that your
usernames are unique, you can use Sham.string! to avoid users having the same
username.&lt;/p&gt;

&lt;p&gt;Normally, this would fail because the two users would have the same username:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;:username&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;username@example.com&amp;quot;&lt;/span&gt;
&lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;:username&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;username@example.com&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;But, this will not fail because each username will be globally unique:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sham!&lt;/span&gt; &lt;span class="ss"&gt;:username&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;Sham&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;string!&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;@example.com&amp;quot;&lt;/span&gt;
&lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sham!&lt;/span&gt; &lt;span class="ss"&gt;:username&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;Sham&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;string!&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;@example.com&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h4&gt;You can nest shams.&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;Sham::Base.new(User)&lt;/code&gt; tells Sham that when it's creating a model it should
create a User sham if one is not specified.  That means that either of these two
calls is valid:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="no"&gt;Cart&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sham!&lt;/span&gt; &lt;span class="ss"&gt;:user&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sham!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:username&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;person@example.com&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;Cart&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sham!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Check out the &lt;a href="https://github.com/panthomakos/sham#readme"&gt;documentation&lt;/a&gt; for
additional examples and features. Feel free to
&lt;a href="https://github.com/panthomakos/sham/issues"&gt;file an issue&lt;/a&gt; if something is not
working as you would expect.  There's much more you can do with this gem and
while I do plan on continuing to develop features, they will remain lightweight
and simple.&lt;/p&gt;

     
   &lt;img src="http://feeds.feedburner.com/~r/ablogaboutcode/~4/e2GMiNjLo94" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://ablogaboutcode.com//2010/12/06/sham-lightweight-factories-for-ruby-on-rails-testing</feedburner:origLink></entry>
 
 <entry>
   <title><![CDATA[To be or not to be... RESTful - Ruby on Rails Best Practices]]></title>
   <link href="http://feedproxy.google.com/~r/ablogaboutcode/~3/11zBtpCopFI/to-be-or-not-to-be-restful-ruby-on-rails-best-practices" />
   <updated>2010-11-22T00:00:00-08:00</updated>
   <id>http://ablogaboutcode.com//2010/11/22/to-be-or-not-to-be-restful-ruby-on-rails-best-practices</id>
   <content type="html">
     
     &lt;p&gt;Ruby on Rails assumes you will be developing your controllers and views with a
&lt;a href="http://en.wikipedia.org/wiki/Representational_State_Transfer"&gt;RESTful architecture&lt;/a&gt; in mind.  What this means is that if you have a
table named &lt;code&gt;posts&lt;/code&gt;, a model named &lt;code&gt;Post&lt;/code&gt; and a controller named
&lt;code&gt;PostsController&lt;/code&gt; you have some URLs automatically available to you.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTTP GET /posts: List all the posts in the system.&lt;/li&gt;
&lt;li&gt;HTTP GET /posts/[id]: Show me a specific post.&lt;/li&gt;
&lt;li&gt;HTTP POST /posts: Create a new post.&lt;/li&gt;
&lt;li&gt;HTTP PUT /posts/[id]: Update a specific post.&lt;/li&gt;
&lt;li&gt;HTTP DELETE /posts/[id]: Remove a post.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;In fact, creating the associated migration, model, controller and view is only
a couple of scaffold generation commands away.  Once you have this all setup
though, you begin to ask yourself "&lt;a href="http://stackoverflow.com/questions/4249635/rails-restful-resources-worth-using-or-inflexible-overrated"&gt;What's so great about this?&lt;/a&gt;"  Besides
being easy to create all of these files and hook them up, what's the actual
added benefit of structuring my code this way?  This only becomes more apparent
when you start adding additional functionality, for example you want an
&lt;code&gt;ArchivesController&lt;/code&gt; that lists your blog entries by date.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTTP GET /archives: Show me the archived years.&lt;/li&gt;
&lt;li&gt;HTTP GET /archives/[year]: Show me the archived months for a year.&lt;/li&gt;
&lt;li&gt;HTTP GET /archives/[year]/[month]: Show me the posts for a specific month and year.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;You realize that you don't want all the fancy PUT, POST, DELETE actions, and
your URL structure is actually entirely different from the RESTful architecture.
Do you still have to keep using REST? Should you restructure your
&lt;code&gt;ArchivesController&lt;/code&gt; to fit the RESTful architecture?&lt;/p&gt;

&lt;p&gt;The short answer is no, you don't need to use REST.  REST is great for some
projects and some entities, but not for others.  Generally it's also a good
starting point, and more importantly it creates a basic protocol that you or
other developers, in the case of an API, can depend on.  It doesn't require you
to remember what you need to do to create a new entity, you simply make a POST
request.  That said it's not the be-all-and-end-all of software architecture.
For example, a web-site's marketing pages (/about, /tour, /pricing,
/special-offer-december) usually do not fit well into a RESTful architecture,
and additional functionality like search (HTTP Get /posts/search) or stats (HTTP
Get /posts/stats) is often added in parallel to the RESTful architecture.&lt;/p&gt;

&lt;p&gt;Before you get started, here are some questions you might want to ask yourself:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Does this controller/view deal primarily with an object/entity like a Post, Blog, User, Comment?&lt;/li&gt;
&lt;li&gt;Are create, update, delete, edit and new actions all going to be available on the web?&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;As a guideline, if you answer YES to these two questions, then it's probably
best to start with REST and expect that you will eventually use the architecture
as a building block for additional actions and views you might want to perform.
Otherwise, pick a URL that best represents what the action will show or do
(/archives, /tour, /december-offer) and make sure you use the proper HTTP
Protocols (GET for display, PUT for update, DELETE for removing and POST for
creating).&lt;/p&gt;

     
   &lt;img src="http://feeds.feedburner.com/~r/ablogaboutcode/~4/11zBtpCopFI" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://ablogaboutcode.com//2010/11/22/to-be-or-not-to-be-restful-ruby-on-rails-best-practices</feedburner:origLink></entry>
 
 <entry>
   <title><![CDATA[FULLTEXT Index and SPATIAL Index - MySQL Compatible Rake Tasks]]></title>
   <link href="http://feedproxy.google.com/~r/ablogaboutcode/~3/XxljlHIJLvI/fulltext-index-and-spatial-index-mysql-compatible-rake-tasks" />
   <updated>2010-11-21T00:00:00-08:00</updated>
   <id>http://ablogaboutcode.com//2010/11/21/fulltext-index-and-spatial-index-mysql-compatible-rake-tasks</id>
   <content type="html">
     
     &lt;p&gt;Have you ever run a rake task such as &lt;code&gt;db:test:prepare&lt;/code&gt; or &lt;code&gt;db:schema:load&lt;/code&gt; only
to be presented with an error about key length?&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Mysql::Error: BLOB/TEXT column 'column-name' used in key specification
  without a key length:
CREATE INDEX index-name ON table-name (column-name)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Here are some examples I've encountered:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Mysql::Error: BLOB/TEXT column 'keywords' used in key specification
  without a key length:
CREATE INDEX fulltext_keywords ON article_search (keywords)

Mysql::Error: BLOB/TEXT column 'mbr' used in key specification
  without a key length:
CREATE INDEX spatial_mbr ON client_locations (mbr)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;These errors are the result of the &lt;a href="http://www.rubydoc.info/github/rails/rails/2109d175f24da725313f/ActiveRecord/SchemaDumper"&gt;ActiveRecord::SchemaDumper&lt;/a&gt; class not
being able to generate a schema.rb file with proper commands for creating
&lt;a href="http://dev.mysql.com/doc/refman/5.5/en/fulltext-search.html"&gt;FULLTEXT&lt;/a&gt; and
&lt;a href="http://dev.mysql.com/doc/refman/5.5/en/creating-spatial-indexes.html"&gt;SPATIAL&lt;/a&gt;
MySQL indices.  Fortunately Ruby is a dynamic language, and it's easy to adjust
the way the schema.rb file is generated.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;:  This code assumes your FULLTEXT indices have "fulltext" in their name
and that your SPATIAL indices have "spatial" in their name.  If you don't follow
this convention then you'll need to write your own regular expressions into the
code.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
Create a file called `sd_indexes.rb` in your `config/initializers` directory,
and add the following code.

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;ActiveRecord&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SchemaDumper&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;indexes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;indexes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;indexes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;any?&lt;/span&gt;
        &lt;span class="n"&gt;add_index_statements&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;indexes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;

          &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=~&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;strong&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="sr"&gt;/fulltext/i&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/strong&amp;gt;&lt;/span&gt;
&lt;span class="sr"&gt;            &amp;quot;  execute \&amp;quot;CREATE FULLTEXT INDEX &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sr"&gt; ON &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sr"&gt; (&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;columns&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;,&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sr"&gt;)\&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class="sr"&gt;          elsif index.name =~ &amp;lt;strong&amp;gt;/s&lt;/span&gt;&lt;span class="n"&gt;patial&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/strong&amp;gt;&lt;/span&gt;
&lt;span class="sr"&gt;            &amp;quot;  execute \&amp;quot;CREATE SPATIAL INDEX &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sr"&gt; ON &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sr"&gt; (&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;columns&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;,&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sr"&gt;)\&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class="sr"&gt;          else&lt;/span&gt;
&lt;span class="sr"&gt;            statment_parts = [(&amp;#39;add_index &amp;#39; + index.table.inspect)]&lt;/span&gt;
&lt;span class="sr"&gt;            statment_parts &amp;lt;&amp;lt; index.columns.inspect&lt;/span&gt;
&lt;span class="sr"&gt;            statment_parts &amp;lt; &amp;#39; + index.name.inspect)&lt;/span&gt;
&lt;span class="sr"&gt;            statment_parts &amp;lt; true&amp;#39; if index.unique&lt;/span&gt;

&lt;span class="sr"&gt;            &amp;#39;  &amp;#39; + statment_parts.join(&amp;#39;, &amp;#39;)&lt;/span&gt;
&lt;span class="sr"&gt;          end&lt;/span&gt;
&lt;span class="sr"&gt;        end&lt;/span&gt;

&lt;span class="sr"&gt;        stream.puts add_index_statements.sort.join(&amp;quot;\n&amp;quot;)&lt;/span&gt;
&lt;span class="sr"&gt;        stream.puts&lt;/span&gt;
&lt;span class="sr"&gt;      end&lt;/span&gt;
&lt;span class="sr"&gt;    end&lt;/span&gt;
&lt;span class="sr"&gt;  end&lt;/span&gt;
&lt;span class="sr"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

This code overrides the basic index creation of the `ActiveRecord::SchemaDumper`
class.  When the schema dumper encounters an index, before issuing the standard
`add_index` command, it checks if the index name matches **/fulltext/i** or
**/spatial/i**.  If there is a match, the schema dumper issues a MySQL
[CREATE INDEX](http://dev.mysql.com/doc/refman/5.5/en/create-index.html) command
to create the FULLTEXT or SPATIAL index manually.
  &lt;/li&gt;
  &lt;li&gt;
Generate the schema.rb file so that your changes take effect.
    
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;rake db:schema:dump
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

  &lt;/li&gt;
  &lt;li&gt;
Create your test database from the newly generated schema.rb file.
    
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;rake db:test:prepare
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

  &lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;The added benefit of overriding the &lt;code&gt;ActiveRecord::SchemaDumper#indexes&lt;/code&gt;
function is that the schema.rb file will be properly generated from now on. That
means that the next time you run a migration you won't have to make any
adjustments to the schema.rb file, and you won't have to re-run the
&lt;code&gt;db:schema:dump&lt;/code&gt; rake task.&lt;/p&gt;

     
   &lt;img src="http://feeds.feedburner.com/~r/ablogaboutcode/~4/XxljlHIJLvI" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://ablogaboutcode.com//2010/11/21/fulltext-index-and-spatial-index-mysql-compatible-rake-tasks</feedburner:origLink></entry>
 
 <entry>
   <title><![CDATA[Serving Static Files with Passenger and Nginx]]></title>
   <link href="http://feedproxy.google.com/~r/ablogaboutcode/~3/S2F0oEtrQFY/serving-static-files-passenger-nginx" />
   <updated>2010-11-19T00:00:00-08:00</updated>
   <id>http://ablogaboutcode.com//2010/11/19/serving-static-files-passenger-nginx</id>
   <content type="html">
     
     &lt;p&gt;The &lt;a href="http://wiki.nginx.org/NginxXSendfile"&gt;X-Accel-Redirect HTTP header&lt;/a&gt; is used on Nginx servers to allow
applications to serve static files directly from Nginx.  For those familiar with
&lt;a href="http://john.guen.in/rdoc/x_send_file/"&gt;X-Sendfile&lt;/a&gt;, X-Accel-Redirect is the
Nginx implementation. Using this header to serve static files from a Rails
application has some great benefits, like not requiring a file to be streamed
through the &lt;a href="http://www.modrails.com"&gt;Passenger&lt;/a&gt; and Rails stacks - which can be
costly.  The setup is quite simple.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
Create a controller to serve the file.

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BlogsController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicaitonController&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;show&lt;/span&gt;
    &lt;span class="vi"&gt;@blog&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Blog&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;X-Accel-Redirect&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@blog&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Content-Type&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;application/json&amp;quot;&lt;/span&gt;
    &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="ss"&gt;:nothing&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

  &lt;/li&gt;
  &lt;li&gt;
Write an nginx location block into nginx.conf.
        server {
          ...
          location /blogs/ {
            internal;
            root /data;
          }
        }
  &lt;/li&gt;
  &lt;li&gt;
Serve the file.

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="n"&gt;blog&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Blog&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:path&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;/blogs/my_first_blog.json&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;uri&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;URI&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;http://localhost:3000/blogs/&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;blog&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.json&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="ss"&gt;Net&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="ss"&gt;:HTTP&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="n"&gt;uri&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

  &lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;The request goes something like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The HTTP GET request goes to Nginx, Passenger, and finally to your Rails
BlogsConroller#show action.&lt;/li&gt;
&lt;li&gt;The BlogsController#show action responds with two HTTP headers
(X-Accel-Redirect and Content-Type).&lt;/li&gt;
&lt;li&gt;The X-Accel-Redirect header is trapped on the return trip by Nginx.&lt;/li&gt;
&lt;li&gt;Nginx matches the X-Accel-Redirect header with the location /blogs/ block.&lt;/li&gt;
&lt;li&gt;Nginx serves the file directly from /data/blogs/my_first_blog.json.&lt;/li&gt;
&lt;li&gt;Nginx also persists the &lt;a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.17"&gt;Content-Type HTTP header&lt;/a&gt; and passes
it to the client.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;An additional benefit of this method is that you can use the controller to check
file permissions.  For example:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BlogsController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicaitonController&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;show&lt;/span&gt;
    &lt;span class="vi"&gt;@blog&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Blog&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;current_user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;can_access?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@blog&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;X-Accel-Redirect&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@blog&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;
      &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Content-Type&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;application/json&amp;quot;&lt;/span&gt;
      &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="ss"&gt;:nothing&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="n"&gt;redirect_to&lt;/span&gt; &lt;span class="n"&gt;permission_denied&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;




     
   &lt;img src="http://feeds.feedburner.com/~r/ablogaboutcode/~4/S2F0oEtrQFY" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://ablogaboutcode.com//2010/11/19/serving-static-files-passenger-nginx</feedburner:origLink></entry>
 

</feed>
