<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title>reinh.com</title>
  <link href="http://reinh.com/atom.xml" rel="self"/>
  <link href="http://reinh.com/"/>
  <updated>2011-09-07T10:11:57-07:00</updated>
  <id>http://reinh.com/</id>
  <author>
    <name>Rein Henrichs</name>
    
  </author>

  
  <entry>
    <title>Building a Turing Machine Simulator With Ruby (Part&nbsp;1)</title>
    <link href="http://reinh.com/blog/2011/09/03/building-a-turing-machine-simulator-with-ruby-part-1.html"/>
    <updated>2011-09-03T17:41:00-07:00</updated>
    <id>http://reinh.com/blog/2011/09/03/building-a-turing-machine-simulator-with-ruby-part-1</id>
    <content type="html">&lt;p&gt;To better understand Turing's machine and its contributions to mathematics and
computer science, we will build a simulator in Ruby. This simulator will take a
description of the machine's configuration, create a model of the machine, and
run through its steps. We will be able to observe the action of the head and
changes to the tape at each step. Hopefully this will serve to illuminate some
aspects of Turing's machine that might otherwise be less accessible.&lt;/p&gt;

&lt;!--more--&gt;


&lt;p&gt;Although the Turing machine is often thought of as prefiguring later computer
science innovations such as the state machine, its original purpose was quite
different. Turing created his machine in an attempt to understand the limits of
mechanical computation. That is to say, the limits of &lt;em&gt;computability&lt;/em&gt;. The
paper that introduced the Turing machine, published in 1936, refers to
&quot;computable numbers&quot; and their use in solving David Hilbert's &lt;em&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Entscheidungsproblem&quot;&gt;Entscheidungsproblem&lt;/a&gt;&lt;/em&gt;, or
&quot;decision problem&quot;.&lt;/p&gt;

&lt;h2&gt;Turing's Marvelous Machine&lt;/h2&gt;

&lt;p&gt;Informally, a Turing machine is a mathematical model of a machine that
mechanically operates on a tape. This tape contains squares where the machine
can read or print a symbol using a tape head. The machine can also move left
and right over the tape, one square at a time.  The machine's operation is
fully determined by a list of elementary instructions such as &quot;in state 42, if
the symbol seen is 0, print a 1; if the symbol seen is 1, shift to the right
and change into state 17; in state 17, if the symbol seen is 0, print a 1 and
change into state 6;&quot; etc. Turing called these instructions &lt;em&gt;m-configurations&lt;/em&gt;.
Modern computer scientists typically refer to them as states (as the Turing
machine is a type of &lt;a href=&quot;http://en.wikipedia.org/wiki/Finite-state_machine&quot;&gt;Finite-state machine&lt;/a&gt;). I will refer to
them interchangeably as &quot;instructions&quot; or &quot;states&quot;. Turing, in his paper,
labeled these instructions using gothic script lower-case letters.  We will
simply use lower-case letters.&lt;/p&gt;

&lt;p&gt;A bit more formally, a Turing machine can be specified as the 3-tuple &lt;script type=&quot;math/tex&quot;&gt;M= \langle Q, \Gamma, I \ \rangle&lt;/script&gt;. &lt;script type=&quot;math/tex&quot;&gt;Q&lt;/script&gt; is a finite, non-empty set of &lt;em&gt;states&lt;/em&gt; where &lt;script type=&quot;math/tex&quot;&gt;q_0 \in Q&lt;/script&gt; is the first state; &lt;script type=&quot;math/tex&quot;&gt;\Gamma&lt;/script&gt; is a finite, non-empty set of &lt;em&gt;tape alphabet/symbols&lt;/em&gt; with &lt;script type=&quot;math/tex&quot;&gt;S_0 \in \Gamma&lt;/script&gt; representing a blank, also called &lt;script type=&quot;math/tex&quot;&gt;None&lt;/script&gt; (the only symbol allowed to occur on the tape infinitely often at any step during the computation); and &lt;script type=&quot;math/tex&quot;&gt;I&lt;/script&gt; is a finite, non-emtpy set of instructions. An instruction &lt;script type=&quot;math/tex&quot;&gt;i \in I&lt;/script&gt; can be defined with the 5-tuple, or &lt;em&gt;quint&lt;/em&gt;, &lt;script type=&quot;math/tex&quot;&gt;\langle q_i, S_j, S_k/N/E, L/R, q_m \rangle&lt;/script&gt;, which consists of the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;script type=&quot;math/tex&quot;&gt;q_i \in Q &lt;/script&gt;, the current state.&lt;/li&gt;
&lt;li&gt;&lt;script type=&quot;math/tex&quot;&gt;S_j \in \Gamma&lt;/script&gt;, the symbol scanned.&lt;/li&gt;
&lt;li&gt;The symbol to be printed

&lt;ul&gt;
&lt;li&gt;&lt;script type=&quot;math/tex&quot;&gt;S_k \in \Gamma&lt;/script&gt;, print the symbol &lt;script type=&quot;math/tex&quot;&gt;S_k&lt;/script&gt;&lt;/li&gt;
&lt;li&gt;&lt;script type=&quot;math/tex&quot;&gt;N&lt;/script&gt;, equivalent to &lt;script type=&quot;math/tex&quot;&gt;S_j&lt;/script&gt;, indicates a &quot;noop&quot; (alternatively, print the current symbol again).&lt;/li&gt;
&lt;li&gt;&lt;script type=&quot;math/tex&quot;&gt;E&lt;/script&gt;, equivalent to &lt;script type=&quot;math/tex&quot;&gt;S_0&lt;/script&gt;, print a blank (erasure).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;A head movement instruction:

&lt;ul&gt;
&lt;li&gt;&lt;script type=&quot;math/tex&quot;&gt;L&lt;/script&gt;, move the head left.&lt;/li&gt;
&lt;li&gt;&lt;script type=&quot;math/tex&quot;&gt;R&lt;/script&gt;, move the head right.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;script type=&quot;math/tex&quot;&gt;q_m \in Q&lt;/script&gt;, the new state.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;This is a bit less formal than the definition used by Hopcroft and Ullman, for
instance, but should suffice for our purposes.&lt;/p&gt;

&lt;h2&gt;Our First Turing Machine&lt;/h2&gt;

&lt;p&gt;With the formal definition out of the way, let's turn to Turing's first
machine, which computes the sequence &lt;em&gt;0 1 0 1 0 1&amp;hellip;&lt;/em&gt;. This machine's 3-tuple looks like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Q&lt;/em&gt;, the states: &lt;em&gt;{ b, c, e, f }&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&amp;Gamma;&lt;/em&gt;, the symbols: &lt;em&gt;{ 0, 1}&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;I&lt;/em&gt;, the instructions: &lt;script type=&quot;math/tex&quot;&gt; \{ \langle b, None, 0, R, c \rangle,  \langle c, None, N, R, e \rangle,  \langle e, None, 1, R, f \ \rangle,  \langle f, None, N, R, b \rangle \} &lt;/script&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;In Turing's original table form, these same instructions are represented as:&lt;/p&gt;

&lt;table class=&quot;text-center&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt; &lt;th colspan=&quot;2&quot;&gt;Configuration&lt;/th&gt; &lt;th colspan=&quot;2&quot;&gt;Behavior&lt;/th&gt; &lt;/tr&gt;
        &lt;tr&gt; &lt;th&gt;m-configuration&lt;/th&gt; &lt;th&gt;Tape symbol&lt;/th&gt; &lt;th&gt;Tape operations&lt;/th&gt; &lt;th&gt;Final m-configuration&lt;/th&gt; &lt;/tr&gt;
        &lt;tr&gt; &lt;td&gt;b&lt;/td&gt; &lt;td&gt;None&lt;/td&gt; &lt;td&gt;P0, R&lt;/td&gt; &lt;td&gt;c&lt;/td&gt; &lt;/tr&gt;
        &lt;tr&gt; &lt;td&gt;c&lt;/td&gt; &lt;td&gt;None&lt;/td&gt; &lt;td&gt;R&lt;/td&gt;     &lt;td&gt;e&lt;/td&gt; &lt;/tr&gt;
        &lt;tr&gt; &lt;td&gt;e&lt;/td&gt; &lt;td&gt;None&lt;/td&gt; &lt;td&gt;P1, R&lt;/td&gt; &lt;td&gt;f&lt;/td&gt; &lt;/tr&gt;
        &lt;tr&gt; &lt;td&gt;f&lt;/td&gt; &lt;td&gt;None&lt;/td&gt; &lt;td&gt;R&lt;/td&gt;     &lt;td&gt;b&lt;/td&gt; &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;


&lt;p&gt;Turing describes the above table as follows:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;This [example] table (and all succeeding tables of the same kind) is to be understood to mean that for a configuration described in the first two columns the operations in the third column are carried out successively, and the machine then goes over into the m-configuration in the final column&lt;/p&gt;&lt;/blockquote&gt;


&lt;h2&gt;Once Again, With ASCII&lt;/h2&gt;

&lt;p&gt;For our Turing machine simulator, I decided to use an ASCII representation of
the Turing machine's instructions. In this format, the instructions look like
this:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;Turing's First Example&lt;/span&gt;&lt;a href='https://github.com/reinh/turing/blob/master/examples/0101010101_simple.turing'&gt;on github.com &lt;/a&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class=''&gt;&lt;div class='line'&gt;b, None, P0R, c
&lt;/div&gt;&lt;div class='line'&gt;c, None, R,   e
&lt;/div&gt;&lt;div class='line'&gt;e, None, P1R, f
&lt;/div&gt;&lt;div class='line'&gt;f, None, R,   b&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;The m-configurations (instructions) in my machines will begin with &lt;em&gt;b&lt;/em&gt;, just as Turing's did. (I believe he used &lt;em&gt;b&lt;/em&gt; for &lt;em&gt;begin&lt;/em&gt;.)&lt;/p&gt;

&lt;p&gt;The BNF grammar for this representation is:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;instruction&amp;gt; ::= &amp;lt;ident&amp;gt; &quot;,&quot; &amp;lt;symbol&amp;gt; &quot;,&quot; &amp;lt;operation&amp;gt; &quot;,&quot; &amp;lt;ident&amp;gt; &amp;lt;EOL&amp;gt;
      &amp;lt;ident&amp;gt; ::= &amp;lt;char&amp;gt;
      &amp;lt;symbol ::= &amp;lt;char&amp;gt; | &quot;None&quot;
  &amp;lt;operation&amp;gt; ::= &amp;lt;movement&amp;gt; | &amp;lt;print&amp;gt; &amp;lt;movement&amp;gt;
      &amp;lt;print&amp;gt; ::= 'P' &amp;lt;char&amp;gt;
    &amp;lt;movement ::= 'R' | 'L'
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Representing An Instruction&lt;/h2&gt;

&lt;p&gt;To begin modelling our simulated Turing machine, we need some way to represent
instructions internally. We'll use Ruby arrays as tuples and Ruby symbols as,
well, symbols (with the exception of &lt;em&gt;None&lt;/em&gt;, &lt;em&gt;0&lt;/em&gt; and &lt;em&gt;1&lt;/em&gt;, which will be be
represented as &lt;code&gt;nil&lt;/code&gt; and the integers &lt;code&gt;0&lt;/code&gt; and &lt;code&gt;1&lt;/code&gt;, respectively). Tape operations will be represented as another array of tuples, to wit: &lt;em&gt;Pn&lt;/em&gt; as &lt;code&gt;[ :print, n ]&lt;/code&gt;, &lt;em&gt;E&lt;/em&gt; as &lt;code&gt;[ :erase ]&lt;/code&gt;, &lt;em&gt;L&lt;/em&gt; as &lt;code&gt;[ :left ]&lt;/code&gt;, and &lt;em&gt;R&lt;/em&gt; as &lt;code&gt;[ :right ]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here is our Ruby representation of the above instruction list:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;Turing's First Example (Ruby)  &lt;/span&gt;&lt;/figcaption&gt;
 &lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;div class='line'&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:right&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:right&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;                &lt;span class=&quot;ss&quot;&gt;:e&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:right&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:f&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:right&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;                &lt;span class=&quot;ss&quot;&gt;:b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;h2&gt;Parsing An Instruction&lt;/h2&gt;

&lt;p&gt;Writing a parser for the ASCII instruction format is a fun little exercise. As
a Turing machine is a finite-state machine, it should be no surprise that this
specification grammar forms a regular language (which can be accepted with a
finite-state machine). This means that we can parse it with regular
expressions---without having two problems! (Actually, we'll use the comma
separation to make tokenization a bit easier with &lt;code&gt;String#split&lt;/code&gt;, but we're
getting ahead of ourselves.)&lt;/p&gt;

&lt;p&gt;We'll use a &lt;code&gt;Turing::Parser&lt;/code&gt; class to parse the entire specification. It will
split lines and delegate to &lt;code&gt;Turing::Parser::Line&lt;/code&gt; class to parse individual
instruction lines. This in turn will need to parse (lex) individual tokens into a Ruby
representation. We'll start there:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;parse_token()  &lt;/span&gt;&lt;/figcaption&gt;
 &lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;span class='line'&gt;7&lt;/span&gt;
&lt;span class='line'&gt;8&lt;/span&gt;
&lt;span class='line'&gt;9&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;div class='line'&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Turing&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Parser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Line&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;parse_token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;k&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;None&amp;quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;nil&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;k&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;0&amp;quot;&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;k&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;1&amp;quot;&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;intern&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;This will take a token like &quot;None&quot; and return its Ruby representation, in this
case &lt;code&gt;nil&lt;/code&gt;. Bits will be converted to Ruby Integers (close enough). Characters
will be interned (converted to Ruby Symbols).&lt;/p&gt;

&lt;p&gt;Next, we'll deal with the operations. We can write a simple string scanner that
will lex the operation string and turn it into a list of operation tuples (as
described above).&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;parse_operations()  &lt;/span&gt;&lt;/figcaption&gt;
 &lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;span class='line'&gt;7&lt;/span&gt;
&lt;span class='line'&gt;8&lt;/span&gt;
&lt;span class='line'&gt;9&lt;/span&gt;
&lt;span class='line'&gt;10&lt;/span&gt;
&lt;span class='line'&gt;11&lt;/span&gt;
&lt;span class='line'&gt;12&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;div class='line'&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Turing&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Parser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Line&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;parse_operations&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;actions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;n&quot;&gt;actions&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scan&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/P.|R|L|E/&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;      &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;action&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;      &lt;span class=&quot;k&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;sr&quot;&gt;/P(.)/&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parse_token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vg&quot;&gt;$1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;      &lt;span class=&quot;k&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;R&amp;quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:right&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;      &lt;span class=&quot;k&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;L&amp;quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:left&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;      &lt;span class=&quot;k&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;E&amp;quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:empty&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;Now we can parse each instruction line by converting tokens with &lt;code&gt;parse_token&lt;/code&gt;
and converting the operations with &lt;code&gt;parse_operations&lt;/code&gt; (which, of course, uses
&lt;code&gt;parse_token&lt;/code&gt; itself to lex the tokens it scans):&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;parse_instruction()  &lt;/span&gt;&lt;/figcaption&gt;
 &lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;span class='line'&gt;7&lt;/span&gt;
&lt;span class='line'&gt;8&lt;/span&gt;
&lt;span class='line'&gt;9&lt;/span&gt;
&lt;span class='line'&gt;10&lt;/span&gt;
&lt;span class='line'&gt;11&lt;/span&gt;
&lt;span class='line'&gt;12&lt;/span&gt;
&lt;span class='line'&gt;13&lt;/span&gt;
&lt;span class='line'&gt;14&lt;/span&gt;
&lt;span class='line'&gt;15&lt;/span&gt;
&lt;span class='line'&gt;16&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;div class='line'&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Turing&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Parser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Line&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;vi&quot;&gt;@line&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;parse_instruction&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;symbol&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operations&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;end_state&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@line&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;,&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;      &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parse_token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;n&quot;&gt;symbol&lt;/span&gt;     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parse_token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;symbol&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;n&quot;&gt;operations&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parse_operations&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;operations&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;n&quot;&gt;end_state&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parse_token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;end_state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;symbol&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operations&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;end_state&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;h2&gt;Using A Struct For Instructions&lt;/h2&gt;

&lt;p&gt;We can add a bit of semantic value to the tuples we use to represent machine
instructions by wrapping them in a struct. In this way, the struct is
functioning like an intermediate data type. The struct will also make it easier
to unpack specific values out of the tuple. Structs also have the useful
property of duck typing as arrays (through the use of &lt;code&gt;to_ary&lt;/code&gt;). You can even
splat them, which will come in handy later.&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;Turing::Machine::Instruction  &lt;/span&gt;&lt;/figcaption&gt;
 &lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;span class='line'&gt;7&lt;/span&gt;
&lt;span class='line'&gt;8&lt;/span&gt;
&lt;span class='line'&gt;9&lt;/span&gt;
&lt;span class='line'&gt;10&lt;/span&gt;
&lt;span class='line'&gt;11&lt;/span&gt;
&lt;span class='line'&gt;12&lt;/span&gt;
&lt;span class='line'&gt;13&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;div class='line'&gt;&lt;span class=&quot;no&quot;&gt;Turing&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Machine&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Instruction&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Struct&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:symbol&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:operations&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:end_state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Turing&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Parser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Line&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;parse_instruction&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;symbol&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operations&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;end_state&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@line&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;,&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;      &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parse_token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;n&quot;&gt;symbol&lt;/span&gt;     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parse_token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;symbol&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;n&quot;&gt;operations&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parse_operations&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;operations&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;n&quot;&gt;end_state&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parse_token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;end_state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;no&quot;&gt;Turing&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Machine&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Instruction&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;symbol&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operations&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;end_state&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;h2&gt;Parsing The Machine Specification&lt;/h2&gt;

&lt;p&gt;Now that we can parse in individual line, parsing the entire specification is
just a matter of mapping lines to their parsed version:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;parse_specification()  &lt;/span&gt;&lt;/figcaption&gt;
 &lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;span class='line'&gt;7&lt;/span&gt;
&lt;span class='line'&gt;8&lt;/span&gt;
&lt;span class='line'&gt;9&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;div class='line'&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Turing&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Parser&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;machine_spec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;vi&quot;&gt;@machine_spec&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;machine_spec&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;parse_specification&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;vi&quot;&gt;@machine_spec&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Line&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parse_instruction&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;h2&gt;That's (Not) All, Folks&lt;/h2&gt;

&lt;p&gt;In upcoming parts, we'll use these instructions to form the basis of our Turing
machine's configuration system; we'll implement the machine's
tape and tape head, which will allow us to step through its execution; and we'll add a
simple renderer that will print out the machine's operations so we can follow along.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Ch-Ch-Ch-Changes</title>
    <link href="http://reinh.com/blog/2009/09/21/ch-ch-ch-changes.html"/>
    <updated>2009-09-21T00:00:00-07:00</updated>
    <id>http://reinh.com/blog/2009/09/21/ch-ch-ch-changes</id>
    <content type="html">&lt;p&gt;A couple months ago, I resigned my position at Hashrocket. This was not an easy
decision for me. Working with the rocketeers has been a very fulfilling and
edifying experience. The people at Hashrocket are passionate about what they do
and extremely competent. I was given challenging and rewarding
responsibilities. Hashrocket was a great job and I would recommend it to
anyone. Why, then, did I chose to leave?&lt;/p&gt;

&lt;!--more--&gt;


&lt;p&gt;In the end, it came down to a need for personal growth. At Hashrocket, I have
had the opportunity to work with interesting clients on interesting projects,
to lead a number of talented development teams and to consult on Rails
development and Agile methodologies to large businesses. Thanks to Hashrocket,
I have expanded my core competencies and matured as a developer. Certainly I
could have stayed with Hashrocket and continued this process. There was more to
do and more to learn. In the end, though, I felt that it was time to for me to
take on a new set of challenges. My friend and former boss, Obie Fernandez, has
been wonderfully supportive of me in this and I owe him a great debt of
gratitude. I am happy to say that my departure from Hashrocket has been
entirely amicable. They are a great bunch, one and all, and I am fortunate to
have worked with them.&lt;/p&gt;

&lt;p&gt;As a consultant for the past eight years, both freelance and with Hashrocket, I
have worked with many clients. This work has been more or less successful, my
clients have been more or less happy, and the work has been more or less
satisfying, but there is a common factor in its transient nature. I work on a
project for weeks or months, provide as much value as my abilities allow, and
then move on to another project once my role is complete. Consultants rarely
experience the satisfaction and sense of accomplishment of a job well done, the
rewards of the successful completion of a long and often arduous project life
cycle.&lt;/p&gt;

&lt;p&gt;So, to make a long story short, I wanted to find a project that I could call
home. I wanted to feel a sense of ownership in the project and its outcome. I
also wanted to learn new skills and develop new competencies. The problem is
that I didn't yet know where home was, so I decided to start by taking some
time off and then sort of figure things out from there. This was risky,
especially in our current economic climate. Luckily, I've never been shy about
making such decisions. After all, I love a good adventure, and adventures
always entail a certain amount of risk.&lt;/p&gt;

&lt;p&gt;During my vacation, I spent a lot of time playing piano and writing music. It
felt good to give my creative muscles some much-needed exercise. I assessed my
career and my goals. I read a lot. I played some video games. I quickly found,
however, that living without a
&quot;&lt;a href=&quot;http://37signals.com/svn/posts/1930-mojito-island-is-a-mirage&quot;&gt;dedicated purpose&lt;/a&gt;&quot;
was less than satisfying. I was not happy leaving my tools in
the corner to gather dust: they needed to be used. So, how best to use them?&lt;/p&gt;

&lt;p&gt;I decided, after some consideration, that what I wanted was the opportunity to
shape the destiny of a project that I believed in. I wanted to do more than sit
behind a desk and code. Luckily, I was presented with just such an opportunity
only a few weeks after leaving Hashrocket. Rick Bradley, a good friend of mine
and an excellent developer, had a client who was looking for a full-time hire.
I was reluctant to become Yet Another Developer but I decided to look into it.
I'm sure glad I did: the position turned out to be just what I was looking for.&lt;/p&gt;

&lt;p&gt;The client was &lt;a href=&quot;http://reductivelabs.com/&quot;&gt;Reductive Labs&lt;/a&gt;, the
company behind &lt;a href=&quot;http://reductivelabs.com/trac/puppet/&quot; title=&quot;puppet -
  Trac&quot;&gt;Puppet&lt;/a&gt;, the Ruby-based configuration management tool. This in and
of itself was interesting. The Puppet codebase covers a large area both
topographically and conceptually. It has a significant installation base and a
large open source community. It would be a challenging project to work on and a
welcome test of my abilities.&lt;/p&gt;

&lt;p&gt;I don't have a Computer Science background. I've never taken any courses in
programming. I am entirely self-taught. Puppet, on the other hand, has a lot of
Serious Business going on: a parser-compiler, a graphing library, client-server
systems, and so on. I have experience in some of these areas, but in others I
have only a basic theoretical knowledge gleaned by way of an intense curiosity
and a love of reading. I had read the &lt;a
  href=&quot;http://dragonbook.stanford.edu/&quot;&gt;Dragon Book&lt;/a&gt;, for instance, but I
had no experiential background in language design or writing parsers and
compilers. Luckily, my lack of a formal education was not a barrier to entry
(nor should it be if you have the skills needed to execute or the ability to
acquire them, but that's a topic for another post).&lt;/p&gt;

&lt;p&gt;I spent a week in Portland getting to know the code and the company. While
Puppet is older than Rails, the code has until recently been under the sole
stewardship of Reductive founder and CEO Luke Kanies. As a company, Reductive
is small and young, but the technology is relatively mature. This is an
interesting combination of both the pioneering spirit of a startup and the
stability of an established open source project.&lt;/p&gt;

&lt;p&gt;During the day, I spent my time pairing with Luke and talking with the founders
about their plans for Reductive Labs and Puppet. Luke has a piercing
intelligence and a compelling vision for the future of both Puppet and
Reductive Labs itself. I quickly saw that I would not just be yet another a
developer, rather that I would also have the opportunity to lead teams,
collaborate with a large and active open source community, and even more
importantly, to help Luke and the rest of the Reductive team make design and
strategy decisions that would inform the growth of both Puppet and the company.
Plus, I would be &quot;forced&quot; to relocate to Portland, one of my favorite cities.
Bonus.&lt;/p&gt;

&lt;p&gt;Apparently my visit was a success: I'm pleased to say that Luke offered me a
position immediately after my trip and I accepted just as quickly. As I grow
into my new responsibilities at Reductive, I find that they scale well with my
abilities. Luke seems happy to let me do what I'm good at and I enjoy the
opportunity to carve out my own role within a growing company. Most
importantly, I feel like I have the opportunity to accomplish something
significant. Nothing matters more to my sense of fulfillment and satisfaction.&lt;/p&gt;

&lt;p&gt;My faithful readers have most likely been lamenting this blog's recent lack of
content. Hopefully my little story helps explain this conspicuous absence.
Expect more posts in the near future. I've got plenty to talk about.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Simplify Your Dev Environment With Passenger&nbsp;Pane</title>
    <link href="http://reinh.com/blog/2009/04/17/simplify-your-dev-environment-with-passenger-pane.html"/>
    <updated>2009-04-17T00:00:00-07:00</updated>
    <id>http://reinh.com/blog/2009/04/17/simplify-your-dev-environment-with-passenger-pane</id>
    <content type="html">&lt;p&gt;On OS X? Develop web applications with Ruby? Want drag-and-drop and
point-and-click development server management? Then you need Passenger Pane.
We'll walk you through the installation process and show you how to get a
simple Rack application up and running. Thanks to
&lt;a href=&quot;http://jasonnoble.org&quot;&gt;Jason Noble&lt;/a&gt; for his help getting everything working.&lt;/p&gt;

&lt;!--more--&gt;


&lt;p&gt;Passenger Pane is an OS X preference pane designed to work in concert with
Phusion Passenger and your OS X Leopard's default Apache2 installation (the
same one that serves your Web Sharing). Setup is pretty simple and will
probably take about 10 minutes.&lt;/p&gt;

&lt;p&gt;Here's what we're going to do:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install Phusion Passenger&lt;/li&gt;
&lt;li&gt;Install Passenger Pane&lt;/li&gt;
&lt;li&gt;Serve a &quot;Hello World!&quot; Rack endpoint&lt;/li&gt;
&lt;li&gt;Profit!&lt;/li&gt;
&lt;/ol&gt;


&lt;h2&gt;Install Phusion Passenger&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;http://www.modrails.com&quot;&gt;Phusion Passenger&lt;/a&gt; is the (not so) new hotness in the
Rails deployment world. Phusion is great for serving Rails applications via
Apache in production (especially in concert with Rails Enterprise Edition,
which provides a 33% memory savings over standard MRI Ruby), but it's also
great for simplifying your development environment.&lt;/p&gt;

&lt;p&gt;The Phusion team have done a great job on the passenger install. Here are the
&lt;a href=&quot;http://www.modrails.com/install.html&quot;&gt;official installation instructions&lt;/a&gt;.
We'll repeat them here for the sake of convenience.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Open a Terminal window.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install the passenger gem:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo gem install passenger
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install the passenger apache2 module:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo passenger-install-apache2-module
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Include the module and some supporting configuration settings into an apache conf file. The code will be provided by the passenger install script.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finally, add a &lt;code&gt;Directory&lt;/code&gt; directive to your apache2 config that
allows access to the directory where your app source codes are located. You
can put this at the bottom of your &lt;code&gt;passenger.conf&lt;/code&gt; file
(replace my source directory with yours):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;Directory /Users/reinh/code/&amp;gt;
  Order Allow,Deny
  Allow from all
&amp;lt;/Directory&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: We put the passenger apache configuration in
&lt;code&gt;/etc/apach2/other/passenger.conf&lt;/code&gt; (a file we created). The default apache2
&lt;code&gt;httpd.conf&lt;/code&gt; imports all &lt;code&gt;.conf&lt;/code&gt; files in &lt;code&gt;/etc/apache2/other&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;Install Passenger Pane&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;http://www.fngtps.com/2008/06/putting-the-pane-back-into-deployment&quot;&gt;Passenger Pane&lt;/a&gt;
gives you a Preference Pane that lets you add, remove and manage apps deployed
on Phusion Passenger. Drag-and-drop to serve a new app and restart with a
single click &amp;mdash; it even provides host entries for each app so you don't
have to mess with virtual hosts or your hosts file. This is great for serving
multiple applications simultaneously or just generally being awesome.&lt;/p&gt;

&lt;p&gt;Installation is simple. Download the preference pane from
&lt;a href=&quot;http://www.fngtps.com/2008/06/putting-the-pane-back-into-deployment&quot;&gt;their homepage&lt;/a&gt;
and double-click to install. If you installed Passenger correctly (as above),
this should just work. If not, look for errors in Console.app or a helpful
notice in the preference pane and ask for help on the
&lt;a href=&quot;http://groups.google.com/group/phusion-passenger&quot;&gt;Passenger forums&lt;/a&gt; or in the
&lt;code&gt;#passenger&lt;/code&gt; channel on &lt;code&gt;irc.freenode.net&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;After installing Passenger Pane, you will need to restart Apache. The simplest
way to do this on OS X is to open the Sharing preference pane and uncheck and
recheck Web Sharing.&lt;/p&gt;

&lt;h2&gt;Serve A &quot;Hello World!&quot; Rack Endpoint&lt;/h2&gt;

&lt;p&gt;Let's test that everything is working by creating a simple
&lt;a href=&quot;http://rack.rubyforge.org/&quot;&gt;Rack&lt;/a&gt; &quot;Hello World!&quot; endpoint.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Install &lt;code&gt;rack&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo gem install rack
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a new directory called &lt;code&gt;rack-hello-world&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a file inside it called &lt;code&gt;config.ru&lt;/code&gt; with these contents:&lt;/p&gt;

&lt;p&gt;``` ruby&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;run lambda{|env| [200, {&quot;Content-Type&quot; =&amp;gt; &quot;text/plain&quot;}, [&quot;Hello World!&quot;]]}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;```&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a &lt;code&gt;public&lt;/code&gt; directory inside &lt;code&gt;rack-hello-world&lt;/code&gt; (you'll see why later).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Drag the &lt;code&gt;rack-hello-world&lt;/code&gt; folder into your Passenger Pane panel (if
you're using TextMate, you can drag it from the project panel). You will
probably need to click the lock first to allow modifications.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Browse to &lt;a href=&quot;http://rack-hello-world.local&quot;&gt;http://rack-hello-world.local&lt;/a&gt; and behold the awesome!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Profit!!!&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;If you've done this correctly, your Passenger Pane should look similar to this:&lt;/p&gt;

&lt;p&gt;&lt;img class=&quot;none&quot; src=&quot;http://reinh.com/images/passenger_pane.png&quot;&gt;&lt;/p&gt;

&lt;p&gt;Your browser should be showing you your glorious &quot;Hello World!&quot; homepage.&lt;/p&gt;

&lt;p&gt;Now you can drag in the app folders of any Rails, Merb, Sinatra or Ramaze
applications and have them instantly served by Passenger. In fact, any Ruby web
application that can run on Rack can be run in Passenger Pane. How's that for a
painless local development environment?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Why (I hear you asking) did we create a public directory? The answer is
that Apache expects to serve a public directory and will fail if one is not
found under the root of the app you're serving. If you had not created the
directory, you would have to look at your apache error log, which is usually located at
&lt;code&gt;/var/log/apache2/error_log&lt;/code&gt;, to find out what went wrong.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>A Git Workflow for Agile Teams</title>
    <link href="http://reinh.com/blog/2009/03/02/a-git-workflow-for-agile-teams.html"/>
    <updated>2009-03-02T00:00:00-08:00</updated>
    <id>http://reinh.com/blog/2009/03/02/a-git-workflow-for-agile-teams</id>
    <content type="html">&lt;p&gt;An efficient workflow for developers in Agile teams that handles features and
bugs while keeping a clean and sane history.&lt;/p&gt;

&lt;p&gt;At &lt;a href=&quot;http://hashrocket.com&quot;&gt;Hashrocket&lt;/a&gt; we use git both internally and in our
Agile mentoring and training. Git gives us the flexibility to design a version
control workflow that meets the needs of either a fully Agile team or a team
that is transitioning towards an Agile process.&lt;/p&gt;

&lt;!--more--&gt;


&lt;p&gt;There are many usable git workflows. Indeed, git is really &quot;a tool for
designing VCS workflows&quot; rather than a Version Control System itself. Or, as
Linus would say, git is just a stupid content tracker.&lt;/p&gt;

&lt;p&gt;This is by no means a normative document or my attempt to define The One True
Workflow. I have found this workflow to be productive and relatively painless,
especially for teams that are still learning and transitioning towards a more
Agile process. I invite you to comment below and describe the git workflow that
works best for you.&lt;/p&gt;

&lt;h2&gt;Credits&lt;/h2&gt;

&lt;p&gt;Anyone interested in using git in an Agile environment should read Josh
Susser's &lt;cite&gt;Agile Git and the Story Branch Pattern&lt;/cite&gt;. This workflow
is based largely on his.&lt;/p&gt;

&lt;p&gt;The process of squashing commits into more atomic and incremental units has
been described by Justin Reagor in &lt;cite&gt;A &quot;Squash&quot; WorkFlow in Git&lt;/cite&gt;.
Justin's post also references a &lt;code&gt;git rebase -i&lt;/code&gt; walkthrough by MadCoder
that provides a good explanation the interactive rebase process.&lt;/p&gt;

&lt;p&gt;Thanks also to &lt;a href=&quot;http://www.rickbradley.com/&quot;&gt;Rick Bradley&lt;/a&gt; of &lt;a href=&quot;http://www.ogtastic.com/&quot;&gt;OG Consulting&lt;/a&gt;
and &lt;a href=&quot;http://blog.hasmanythrough.com/&quot;&gt;Josh Susser&lt;/a&gt; of &lt;a href=&quot;http://pivotallabs.com&quot;&gt;Pivotal Labs&lt;/a&gt;
for many fruitful and often hilarious discussions about git, Agile and ponies.&lt;/p&gt;

&lt;h2&gt;Feature Development&lt;/h2&gt;

&lt;p&gt;Our git feature development workflow consists of these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Pull to update your local master&lt;/li&gt;
&lt;li&gt;Check out a feature branch&lt;/li&gt;
&lt;li&gt;Do work in your feature branch, committing early and often&lt;/li&gt;
&lt;li&gt;Rebase frequently to incorporate upstream changes&lt;/li&gt;
&lt;li&gt;Interactive rebase (squash) your commits&lt;/li&gt;
&lt;li&gt;Merge your changes with master&lt;/li&gt;
&lt;li&gt;Push your changes to the upstream&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;First, and while in your master branch (&lt;code&gt;git checkout master&lt;/code&gt;), pull in the
most recent changes:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git pull origin master
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This should never create a merge commit because we are never working directly
in master.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;NB:&lt;/em&gt; Whenever you perform a pull, merge or rebase, make sure that you
run tests directly afterwards. Git may not show any conflicts but that doesn't
mean that two changes are compatible. Also run tests before you commit (of
course).&lt;/p&gt;

&lt;p&gt;We begin with the topmost available story in &lt;a href=&quot;http://pivotaltracker.com&quot;&gt;Pivotal Tracker&lt;/a&gt;.
Let's say that it's &lt;em&gt;#3275: User Can Add A
Comment To a Post&lt;/em&gt;. First, check out a feature branch named with the story id
and a short, descriptive title:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git checkout -b 3275-add-commenting
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The id allows us to easily track this branch back to the story that spawned it.
The title is there to give us humans a little hint as to what's in it. Do some
work on this branch, committing early and often (for instance, whenever your
tests pass). Rebase against the upstream frequently to prevent your branch from
diverging significantly:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git fetch origin master
git rebase origin/master
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;em&gt;NB:&lt;/em&gt; This is often done by checking master out and pulling, but this method
requires extra steps:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git checkout master
git pull
git checkout 3275-add-commenting
git rebase master
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Once work on the feature is complete, you will have a branch with a lot of
small commits like &quot;adding a model and a migration&quot;, &quot;adding a controller and
some views&quot;, &quot;oh crap - adding tests&quot; and so on. This is useful while
developing but larger, incremental commits are more easier to maintain. We will
use an interactive rebase to squash them together. Also, squashing
these commits together will allow us to pretend that we wrote the tests
first&amp;hellip;&lt;/p&gt;

&lt;p&gt;We want the rebase to affect only the commits we've made to this branch, not
the commits that exist on the upstream. To ensure that we only deal with the
&quot;local&quot; commits, use:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git rebase -i origin/master
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Git will display an editor window with a list of the commits to be modified,
something like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;pick 3dcd585 Adding Comment model, migrations, spec
pick 9f5c362 Adding Comment controller, helper, spec
pick dcd4813 Adding Comment relationship with Post
pick 977a754 Comment belongs to a User
pick 9ea48e3 Comment form on Post show page
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now we tell git what we to do. Change these lines to:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;pick 3dcd585 Adding Comment model, migrations, spec
squash 9f5c362 Adding Comment controller, helper, spec
squash dcd4813 Adding Comment relationship with Post
squash 977a754 Comment belongs to a User
squash 9ea48e3 Comment form on Post show page
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Save and close the file. This will squash these commits together into one
commit and present us with a new editor window where we can give the new commit
a message. We'll use the story id and title for the subject and list the
original commit messages in the body:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[#3275] User Can Add A Comment To a Post

* Adding Comment model, migrations, spec
* Adding Comment controller, helper, spec
* Adding Comment relationship with Post
* Comment belongs to a User
* Comment form on Post show page
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This also follows Tim Pope's &lt;a href=&quot;http://www.tpope.net/node/106&quot;&gt;git commit message best
practices&lt;/a&gt;. Now, save and close your editor.
This commit is now ready to be merged back into master. First rebase against
any recent changes in the upstream. Then merge your changes back into master:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git checkout master
git merge 3275-add-commenting
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And finally, push your changes to the upstream:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git push origin master
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Bug Fixes&lt;/h2&gt;

&lt;p&gt;Bugfixes will use the same workflow as feature work. Name your bugfix branch
after the bug id and give it a descriptive name. Prefix the branch name with
&quot;bug&quot; to help you keep track of them, for instance:
&lt;code&gt;bug-3845-empty-comments-allowed&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Do work in your bugfix branch, committing early and often. Rebase frequently
against the upstream and again when you are finished. Then, use an interactive
rebase to squash &lt;em&gt;all&lt;/em&gt; the commits together. Use the bug id and title for the
subject of the new commit. Include &quot;BUG&quot; or &quot;BUGFIX&quot; to make these commits
easier to identify. For instance:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[#3278] BUGFIX: Empty Comments Should Not Be Allowed
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;em&gt;NB:&lt;/em&gt; With a bugfix, squash the commits down into one and exactly one commit
that completely represents that bugfix. Half of a bugfix is useless.&lt;/p&gt;

&lt;h2&gt;QA Branch Management&lt;/h2&gt;

&lt;p&gt;In a truly Agile process, as Josh Susser explained to me, you simply deploy
directly from your latest &quot;green&quot; build. While this may seem impossible, there
are real world examples of the viability of Continuous Deployment.&lt;/p&gt;

&lt;p&gt;For most of the teams we train, this sort of extreme agility is a goal rather
than a way of life. They are transitioning towards a fully Agile process from a
more rigorous one and often have a significant investment in Quality Assurance.
For these teams, I recommend a compromise solution: Use a remote QA branch that
is fast-forward merged from the latest &quot;green&quot; (all CI tests pass) master build
for QA deployments.&lt;/p&gt;

&lt;p&gt;If you don't already have a QA branch, create one from the current master
(assuming it's green) and then push it to your git host:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git checkout -b qa
git push origin qa:refs/heads/qa
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To update an existing QA branch with the latest changes from master, do this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git checkout qa
git merge master
git push origin qa
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Ensure that the master branch is green when you merge. Also ensure that this
merge is always a Fast Forward merge. If it is not, it means that commits have
been made in the QA branch that are not in the master branch. QA should be
merged into from master only, never worked on directly.&lt;/p&gt;

&lt;h2&gt;Production Tagging&lt;/h2&gt;

&lt;p&gt;While an Agile team will be deploying continuously, most teams will require a
more rigorous vetting process before a build is deployed to production. Tags
provide a simple way for QA to vet a particular build.&lt;/p&gt;

&lt;p&gt;Once QA has signed off on a build as ready for production, a tag should be made
and deployed. In git, a tag can be created with &lt;code&gt;git tag &amp;lt;name&amp;gt;&lt;/code&gt;. It is
important that tag naming is consistent and it is useful if they sort in a
meaningful way (latest last, for instance). Two good options are a timestamp or
product version. Use whichever is more meaningful to your team.&lt;/p&gt;

&lt;p&gt;The process of creating a timestamped production tag can be automated with a
simple script or a git alias like this one:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git config alias.datetag '!git tag `date &quot;+%Y%m%d%H%M&quot;`'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;With this alias, &lt;code&gt;git datetag&lt;/code&gt; will create a new tag from &lt;code&gt;HEAD&lt;/code&gt; with the
current timestamp. You will want to be in the QA branch. If the QA branch has
moved beyond the last commit vetted by your QA team, be sure to checkout that
commit first.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Story Driven Development With&nbsp;Rails</title>
    <link href="http://reinh.com/blog/2008/09/12/story-driven-development-with-rails.html"/>
    <updated>2008-09-12T00:00:00-07:00</updated>
    <id>http://reinh.com/blog/2008/09/12/story-driven-development-with-rails</id>
    <content type="html">&lt;p&gt;As a follow up on &lt;a href=&quot;http://reinh.com/blog/2008/08/29/incremental-stories-and-micro-releases.html&quot;&gt;writing incremental stories&lt;/a&gt;,
we're going to take the first story and walk through a behavior driven
development process to implement it in a simple Rails application.&lt;/p&gt;

&lt;p&gt;We will focus on making small, iterative changes and following a strict
test-first philosophy where we write granular unit tests and implement them
with just enough code to make them pass.&lt;/p&gt;

&lt;!--more--&gt;


&lt;p&gt;Let's review our first story:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;Story #1 &lt;/span&gt;&lt;/figcaption&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;span class='line'&gt;7&lt;/span&gt;
&lt;span class='line'&gt;8&lt;/span&gt;
&lt;span class='line'&gt;9&lt;/span&gt;
&lt;span class='line'&gt;10&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class=''&gt;&lt;div class='line'&gt;As A User I Want To View A List Of Projects
&lt;/div&gt;&lt;div class='line'&gt;So that I can find a project that interests me
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;Acceptance:
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;* All projects shown in list
&lt;/div&gt;&lt;div class='line'&gt;* List is paginated
&lt;/div&gt;&lt;div class='line'&gt;* List is sorted by age
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;Cost: 1 Point&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;At this point, let's assume that this story is on top of our current iteration.
First, we'll need to review the story for any missing information and
communicate with the client to clear up any questions. Keep in mind that a
story is just a way to capture a conversation about a feature. It is not set in
stone. After talking to the client, we find that we will need to display a
project's author name and title and that the title will need to link to that
project's page. Let's update the story appropriately.&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;Story #1 &lt;/span&gt;&lt;/figcaption&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;span class='line'&gt;7&lt;/span&gt;
&lt;span class='line'&gt;8&lt;/span&gt;
&lt;span class='line'&gt;9&lt;/span&gt;
&lt;span class='line'&gt;10&lt;/span&gt;
&lt;span class='line'&gt;11&lt;/span&gt;
&lt;span class='line'&gt;12&lt;/span&gt;
&lt;span class='line'&gt;13&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class=''&gt;&lt;div class='line'&gt;As A User I Want To View A List Of Projects
&lt;/div&gt;&lt;div class='line'&gt;So that I can find a project that interests me
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;Acceptance:
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;* All projects shown in list
&lt;/div&gt;&lt;div class='line'&gt;* Show title for each project
&lt;/div&gt;&lt;div class='line'&gt;* Show author name for each project
&lt;/div&gt;&lt;div class='line'&gt;* Project title links to the project's page
&lt;/div&gt;&lt;div class='line'&gt;* List is paginated
&lt;/div&gt;&lt;div class='line'&gt;* List is sorted by project age
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;Cost: 1 Point&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;Now that the story is complete, deliverable and acceptable, we can begin work
on the new feature. A implementation plan should be forming in your head. Now
is the time to divide the work into testable units. In our case we already have
a Project model with the requisite fields (let's say) so our work will focus on
the controller and view.&lt;/p&gt;

&lt;h2&gt;Test All The F---ing Time&lt;/h2&gt;

&lt;p&gt;Client sign-off on well written acceptance tests means that the specifications
you write and the feature that is implemented as a result will be more closely
in line with the client's expectations. This minimizes the kind of impedance
mismatch between expectation and execution that so often plagues a project with
poor client communication and a disorganized process.&lt;/p&gt;

&lt;p&gt;Now it's time to take our acceptance tests and use them to drive our iterative,
test-driven development process. Let's take it from the top.&lt;/p&gt;

&lt;h3&gt;All Projects Shown in List&lt;/h3&gt;

&lt;p&gt;Let's start with the controller. A list of projects needs an index action.
Starting at the top, we will need to load all of the projects. Let's write a
test for this:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;spec/controllers/projects_controller_spec.rb  &lt;/span&gt;&lt;/figcaption&gt;
 &lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;span class='line'&gt;7&lt;/span&gt;
&lt;span class='line'&gt;8&lt;/span&gt;
&lt;span class='line'&gt;9&lt;/span&gt;
&lt;span class='line'&gt;10&lt;/span&gt;
&lt;span class='line'&gt;11&lt;/span&gt;
&lt;span class='line'&gt;12&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;div class='line'&gt;&lt;span class=&quot;n&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ProjectsController&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;n&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;getting a list of products&amp;quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;loads all the projects&amp;quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;      &lt;span class=&quot;n&quot;&gt;projects&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mock_model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;      &lt;span class=&quot;no&quot;&gt;Project&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stub!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;and_return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;projects&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;      &lt;span class=&quot;n&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;index&amp;#39;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;      &lt;span class=&quot;n&quot;&gt;assigns&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:projects&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;projects&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;&lt;em&gt;Note:&lt;/em&gt; Stubbing the call to &lt;code&gt;Project.all&lt;/code&gt; has the immediate benefit of
eliminating the database from our test but is potentially more brittle since we
cannot be sure that this interface point to our Project model will not need to
change in the future.&lt;/p&gt;

&lt;p&gt;On a side note, I tend to view controller tests as integration-level tests
rather than unit tests. As such, I usually do write tests that touch the
database since these are often less brittle. If you write tests that touch the
database, ActiveRecord factories such as &lt;a href=&quot;http://giantrobots.thoughtbot.com/2008/6/6/waiting-for-a-factory-girl&quot;&gt;Factory Girl&lt;/a&gt;
or &lt;a href=&quot;http://b.logi.cx/2007/11/26/object-daddy&quot;&gt;object daddy&lt;/a&gt; are useful for
populating the database with valid records in known states.&lt;/p&gt;

&lt;p&gt;Now we can write the implementation:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;app/controllers/projects_controller.rb  &lt;/span&gt;&lt;/figcaption&gt;
 &lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;div class='line'&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ProjectsController&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ApplicationController&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;index&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;vi&quot;&gt;@projects&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Project&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;all&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;Then we have to display a list of projects. We'll write a view test to cover this:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;spec/views/projects/index.html.erb_spec.rb  &lt;/span&gt;&lt;/figcaption&gt;
 &lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;span class='line'&gt;7&lt;/span&gt;
&lt;span class='line'&gt;8&lt;/span&gt;
&lt;span class='line'&gt;9&lt;/span&gt;
&lt;span class='line'&gt;10&lt;/span&gt;
&lt;span class='line'&gt;11&lt;/span&gt;
&lt;span class='line'&gt;12&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;div class='line'&gt;&lt;span class=&quot;n&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;/projects/index&amp;quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;n&quot;&gt;before&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:each&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;vi&quot;&gt;@project&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mock_model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;vi&quot;&gt;@projects&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;vi&quot;&gt;@project&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;n&quot;&gt;assigns&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:projects&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@projects&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;n&quot;&gt;render&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;projects/index&amp;#39;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;should include a list of projects&amp;quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;have_tag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;li.project&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:count&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@projects&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;And the implementation:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;app/views/projects/index.html.erb  &lt;/span&gt;&lt;/figcaption&gt;
 &lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='rhtml'&gt;&lt;div class='line'&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;err&quot;&gt;&amp;lt;&lt;/span&gt;%% @projects.each do |project| &lt;span class=&quot;err&quot;&gt;%&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;nt&quot;&gt;&amp;lt;li&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;project&amp;quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;err&quot;&gt;&amp;lt;&lt;/span&gt;%% end &lt;span class=&quot;err&quot;&gt;-%&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; View tests can often be brittle. They can be made less brittle by
testing only for semantically appropriate tags, classes and ids whenever
possible. Using semantically rich markup in your views will make it much easier
to write robust view tests -- and is also a great practice for its own sake.
{:.note}&lt;/p&gt;

&lt;h3&gt;Show Title for Each Project&lt;/h3&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;spec/views/projects/index.html.erb_spec.rb  &lt;/span&gt;&lt;/figcaption&gt;
 &lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;span class='line'&gt;7&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;div class='line'&gt;&lt;span class=&quot;n&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;/projects/index&amp;quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;c1&quot;&gt;# SNIP&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;should show the title for each project&amp;quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;have_tag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;li.project .title&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@project&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;




&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;app/views/projects/index.html.erb  &lt;/span&gt;&lt;/figcaption&gt;
 &lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;span class='line'&gt;7&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='rhtml'&gt;&lt;div class='line'&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;err&quot;&gt;&amp;lt;&lt;/span&gt;%% @projects.each do |project| &lt;span class=&quot;err&quot;&gt;%&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;nt&quot;&gt;&amp;lt;li&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;project&amp;quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;      &lt;span class=&quot;nt&quot;&gt;&amp;lt;h2&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;title&amp;quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;lt;&lt;/span&gt;%%= project.title &lt;span class=&quot;err&quot;&gt;%&amp;gt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;err&quot;&gt;&amp;lt;&lt;/span&gt;%% end &lt;span class=&quot;err&quot;&gt;-%&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;h3&gt;Show Author Name for Each Project&lt;/h3&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;spec/views/projects/index.html.erb_spec.rb  &lt;/span&gt;&lt;/figcaption&gt;
 &lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;span class='line'&gt;7&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;div class='line'&gt;&lt;span class=&quot;n&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;/projects/index&amp;quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;c1&quot;&gt;# SNIP&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;should show the author name for each project&amp;quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;have_tag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;li.project .author_name&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@project&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;author_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;




&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;app/views/projects/index.html.erb  &lt;/span&gt;&lt;/figcaption&gt;
 &lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;span class='line'&gt;7&lt;/span&gt;
&lt;span class='line'&gt;8&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='rhtml'&gt;&lt;div class='line'&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;err&quot;&gt;&amp;lt;&lt;/span&gt;%% @projects.each do |project| &lt;span class=&quot;err&quot;&gt;%&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;nt&quot;&gt;&amp;lt;li&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;project&amp;quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;      &lt;span class=&quot;nt&quot;&gt;&amp;lt;h2&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;title&amp;quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;lt;&lt;/span&gt;%%= project.title &lt;span class=&quot;err&quot;&gt;%&amp;gt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;      &lt;span class=&quot;nt&quot;&gt;&amp;lt;p&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;author_name&amp;quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;lt;&lt;/span&gt;%%= project.author_name &lt;span class=&quot;err&quot;&gt;%&amp;gt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;err&quot;&gt;&amp;lt;&lt;/span&gt;%% end &lt;span class=&quot;err&quot;&gt;-%&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; We are using an accessor on our project model, &lt;code&gt;Project#author_name&lt;/code&gt;.
There's a good chance that this name will be taken from an associated User or
Author model in any non-trivial Rails application. From an object oriented
standpoint, however, having the author name hang directly from the Project
model improves encapsulation.&lt;/p&gt;

&lt;p&gt;The benefits of this were already seen in the test, where we were able to stub
&lt;code&gt;author_name&lt;/code&gt; directly on the Project mock. Without the accessor, we would be
forced to stub &lt;code&gt;#author&lt;/code&gt; on the Project mock to return an Author mock that then
stubs &lt;code&gt;#name&lt;/code&gt; just so that we could properly test the method chain
&lt;code&gt;project.author.name&lt;/code&gt; that is used in the view. Violating the &lt;a href=&quot;http://en.wikipedia.org/wiki/Law_of_Demeter&quot;&gt;Law of Demeter&lt;/a&gt;
makes testing harder.&lt;/p&gt;

&lt;h3&gt;Project Title Links to the Project's Page&lt;/h3&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;spec/views/projects/index.html.erb_spec.rb  &lt;/span&gt;&lt;/figcaption&gt;
 &lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;span class='line'&gt;7&lt;/span&gt;
&lt;span class='line'&gt;8&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;div class='line'&gt;&lt;span class=&quot;n&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;/projects/index&amp;quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;c1&quot;&gt;# SNIP&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;should have project titles that link to the project page&amp;quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;have_tag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;li.project .title a[href=?]&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;project_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vi&quot;&gt;@project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;      &lt;span class=&quot;ss&quot;&gt;:text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@project&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;




&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;app/views/projects/index.html.erb  &lt;/span&gt;&lt;/figcaption&gt;
 &lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;span class='line'&gt;7&lt;/span&gt;
&lt;span class='line'&gt;8&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='rhtml'&gt;&lt;div class='line'&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;err&quot;&gt;&amp;lt;&lt;/span&gt;%% @projects.each do |project| &lt;span class=&quot;err&quot;&gt;%&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;nt&quot;&gt;&amp;lt;li&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;project&amp;quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;      &lt;span class=&quot;nt&quot;&gt;&amp;lt;h2&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;title&amp;quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;lt;&lt;/span&gt;%%= link_to project.title, project &lt;span class=&quot;err&quot;&gt;%&amp;gt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;      &lt;span class=&quot;nt&quot;&gt;&amp;lt;p&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;author_name&amp;quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;lt;&lt;/span&gt;%%= project.author_name &lt;span class=&quot;err&quot;&gt;%&amp;gt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;err&quot;&gt;&amp;lt;&lt;/span&gt;%% end &lt;span class=&quot;err&quot;&gt;-%&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;The story is now about half complete. I'll leave pagination and default sort
order as an exercise for the user. In fact, these could also have been broken
out into a secondary story or stories given that what we have done so far is an
incremental unit of work.&lt;/p&gt;

&lt;p&gt;I hope this rather contrived example shows how stories with well written
acceptance tests inform a test- or behavior- driven development process and
help bridge the gap between what the client expects and what the developement
team delivers.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Hack && Ship</title>
    <link href="http://reinh.com/blog/2008/08/27/hack-and-and-ship.html"/>
    <updated>2008-08-27T00:00:00-07:00</updated>
    <id>http://reinh.com/blog/2008/08/27/hack-and-and-ship</id>
    <content type="html">&lt;p&gt;When the &lt;a href=&quot;http://ogtastic.com/&quot;&gt;OG Consulting&lt;/a&gt; &lt;a href=&quot;http://b.logi.cx/&quot;&gt;guys&lt;/a&gt; were
down at &lt;a href=&quot;http://hashrocket.com/&quot;&gt;Hashrocket&lt;/a&gt; working on our latest 3-2-1, they
introduced us to a pair of bash scripts called &lt;em&gt;hack&lt;/em&gt; and &lt;em&gt;ship&lt;/em&gt; that they use
to streamline their everyday git workflow. They're so useful that we adopted
them immediately and we've been using them religiously ever since. I estimate
that these little scripts save me about an hour a day and, what's more, they
make it easy to follow the &lt;em&gt;commit early, commit often&lt;/em&gt; mindset that's so
useful to the agile process.&lt;/p&gt;

&lt;!--more--&gt;


&lt;h2&gt;Simple Software Process&lt;/h2&gt;

&lt;p&gt;Here's our typical workflow (before hack and ship):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Start a feature in &quot;Pivotal Tracker&quot;:https://www.pivotaltracker.com&lt;/li&gt;
&lt;li&gt;Checkout a working branch for this feature&lt;/li&gt;
&lt;li&gt;Write a test&lt;/li&gt;
&lt;li&gt;Write an implementation to make the test pass&lt;/li&gt;
&lt;li&gt;Repeat 3 and 4 until the feature is complete&lt;/li&gt;
&lt;li&gt;Commit changes to git with a &quot;useful commit message&quot;:http://www.tpope.net/node/106&lt;/li&gt;
&lt;li&gt;Checkout the master branch&lt;/li&gt;
&lt;li&gt;Update the master branch&lt;/li&gt;
&lt;li&gt;Checkout the working branch&lt;/li&gt;
&lt;li&gt;Rebase the master branch into the working branch&lt;/li&gt;
&lt;li&gt;Checkout the master branch&lt;/li&gt;
&lt;li&gt;Merge the working branch into the master branch&lt;/li&gt;
&lt;li&gt;Push the changes to the origin repository (usually on &quot;github&quot;:https://github.com/)&lt;/li&gt;
&lt;li&gt;Repeat.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;This is pretty simple (if a bit longwinded). We each probably do this dozens of times a day. Could it be simpler? You bet!&lt;/p&gt;

&lt;h2&gt;Simplified Software Process&lt;/h2&gt;

&lt;p&gt;I'd like to introduce you to the Simplified Software Process. While it may not
be a very good process, it does have one thing going for it: it's &lt;em&gt;simple&lt;/em&gt;. We
like simple. So when we saw Rick Bradley's super simple bash scripts for
automating these common git tasks, we jumped on them. These scripts are
designed to work with the basic git workflow we outlined above. And they have
awesome names.&lt;/p&gt;

&lt;p&gt;Here's &lt;a href=&quot;gist.github.com/7641&quot;&gt;&lt;em&gt;hack&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;div&gt;&lt;script src='https://gist.github.com/7641.js?file='&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;pre&gt;&lt;code&gt;#!/bin/sh -x
# git name-rev is fail
CURRENT=`git branch | grep '\*' | awk '{print $2}'`
git checkout master
git pull origin master
git checkout ${CURRENT}
git rebase master&lt;/code&gt;&lt;/pre&gt;&lt;/noscript&gt;&lt;/div&gt;


&lt;p&gt;And &lt;a href=&quot;http://gist.github.com/7642&quot;&gt;&lt;em&gt;ship&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;div&gt;&lt;script src='https://gist.github.com/7642.js?file='&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;pre&gt;&lt;code&gt;#!/bin/sh -x
# git name-rev is fail
CURRENT=`git branch | grep '\*' | awk '{print $2}'`
git checkout master
git merge ${CURRENT}
git push origin master
git checkout ${CURRENT}&lt;/code&gt;&lt;/pre&gt;&lt;/noscript&gt;&lt;/div&gt;


&lt;p&gt;Now our process looks like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Start a feature in Pivotal Tracker&lt;/li&gt;
&lt;li&gt;Checkout a working branch for this feature&lt;/li&gt;
&lt;li&gt;Write a test&lt;/li&gt;
&lt;li&gt;Write an implementation to make the test pass&lt;/li&gt;
&lt;li&gt;Repeat 3 and 4 until the feature is complete&lt;/li&gt;
&lt;li&gt;Commit changes to git with a useful commit message&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hack&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ship&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Repeat.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;We even wrote ourselves &lt;a href=&quot;http://gist.github.com/7640&quot;&gt;&lt;em&gt;a little alias&lt;/em&gt;&lt;/a&gt; to make this even easier:&lt;/p&gt;

&lt;div&gt;&lt;script src='https://gist.github.com/7640.js?file='&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;pre&gt;&lt;code&gt;alias ssp=&amp;quot;hack &amp;amp;&amp;amp; rake &amp;amp;&amp;amp; ship&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;/noscript&gt;&lt;/div&gt;


&lt;p&gt;Which brings the workflow down to three easy steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Test&lt;/li&gt;
&lt;li&gt;Implement&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ssp&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;Combine this with a Continuous Integration build like
&lt;a href=&quot;http://cruisecontrolrb.thoughtworks.com/&quot;&gt;cruisecontrol.rb&lt;/a&gt; and a deployment
to a staging server that takes less than a minute - we love
&lt;a href=&quot;http://engineyard.com/&quot;&gt;EngineYard&lt;/a&gt; - and you have the perfect recipe for
agile, iterative, test-driven, micro-release oriented development. I've never
been happier with my development process.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Rocking the Hoedown</title>
    <link href="http://reinh.com/blog/2008/08/10/rocking-the-hoedown.html"/>
    <updated>2008-08-10T00:00:00-07:00</updated>
    <id>http://reinh.com/blog/2008/08/10/rocking-the-hoedown</id>
    <content type="html">&lt;p&gt;We had a great time at the Ruby Hoedown this weekend. The
&lt;a href=&quot;http://hashrocket.com&quot;&gt;Hashrocket&lt;/a&gt; crew was out in force (and there was much
debauchery in the Hashrocket RV). We got to meet or get better acquainted with
a lot of great rubyists and hear a lot of entertaining, informative talks.&lt;/p&gt;

&lt;!--more--&gt;


&lt;h2&gt;Jim and Joe's Mock Dialog&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;http://onestepback.org/&quot;&gt;Jim Weirich&lt;/a&gt; and &lt;a href=&quot;http://objo.com/&quot;&gt;Joe O'Brien&lt;/a&gt;
presented their talk about mocks and stubs in the form of a short play in three
acts. This was very timely for me since mocking properly in tests is area we
have been discussing quite a bit at Hashrocket.&lt;/p&gt;

&lt;p&gt;One thing they said that struck a chord was that complex mocks are a code smell
that can clue you in to problems or hot spots for refactoring in the code under
test.&lt;/p&gt;

&lt;p&gt;The presentation style was fresh and the tips they provided should be very
valuable to anyone using mocks in testing (which should be everyone).&lt;/p&gt;

&lt;h2&gt;Ruby Best Practice Patterns&lt;/h2&gt;

&lt;p&gt;I'm afraid I played a little trick on poor Jeremy and my dear audience. Instead
of spending an hour giving examples of patterns and practices, I thought it
might be fun to take a more satirical slant on the material. The resulting
talk, &lt;em&gt;Unfactoring From Patterns: Job Security Through Code Obscurity&lt;/em&gt;,
turned out to be a modest success (if I do say so myself) and I think rather
more entertaining to boot.&lt;/p&gt;

&lt;p&gt;I did have time to show a few actual patterns but the dialog during the
question and answer period was especially valuable. David Black, Yehuda Katz
and others made some great points and I really enjoyed getting a chance to
discuss one of my favorite topics with such a receptive and informed audience.&lt;/p&gt;

&lt;h2&gt;We Ain't Got No Keynote&lt;/h2&gt;

&lt;p&gt;Chris decided to forgo the slides to tell us a more personal story about his
growth from a lowly PHP hacker to the successful rubyist, entreprenuer and
open-source champion that he is today. Chris is an exemplar for me of the right
way to go about creating a personal and company brand.&lt;/p&gt;

&lt;p&gt;Chris's years of passion for tinkering, experimenting and exploring really have
payed off in a big way. I think his story could rightly be considered
inspirational. I'm sure a lot of people left his talk and started side projects
this very weekend. I really enjoyed his talk (even if he did tell people not to
buy my book).&lt;/p&gt;

&lt;h2&gt;Flog Your Tests, Test Your Flog&lt;/h2&gt;

&lt;p&gt;Testing is such a crucial part of my process that I was very excited to hear
Rick Bradley's account of his rather epic battle to add tests to flog. The
irony here, of course, is that flog itself is a testing tool.&lt;/p&gt;

&lt;p&gt;This talk combined two of my favorite topics: testing and refactoring. Rick's
war stories had some great takeaways: the importance of integration tests to
characterize the behavior of the existing system, the ways in which code that
is written test first differs from code that is written without tests, the
utter importance of testing all the f--king time. Bryal Liles will have more to
say on that last topic in a bit.&lt;/p&gt;

&lt;p&gt;I really can't say enough about Rick's talk. Hashrocket often takes on
applications with little or no testing for our Rescue Missions and Rick's
deliberate, careful, comprehensive methodology is exactly the process we try to
follow when we refactor and resuscitate our clients' code back to health. Rick
could very well write the Hashrocket Rescue Mission manual.&lt;/p&gt;

&lt;h2&gt;MIDI Machinations and Hungry Hungry Hippos&lt;/h2&gt;

&lt;p&gt;Giles Bowkett is a mad genius. Perhaps more importantly, he's an artist who can
ship. He lured us all to a talk about archaeopteryx, his amazing MIDI
generator, and then proceeded to smack us all with the enlightenment stick.&lt;/p&gt;

&lt;p&gt;I won't spoil his talk for people who haven't seen it. Suffice it to say that
it was far more than I expected. Giles's opinions on software development are
unique and somewhat iconoclastic. Be careful, the code he writes might blow
some people's minds. Giles's &lt;a href=&quot;http://gilesbowkett.blogspot.com/2008/04/my-approach-to-giving-presentations.html&quot;&gt;presentation style&lt;/a&gt;
is engaging and he can be down right hilarious at times. Also, hippos are
scary!&lt;/p&gt;

&lt;h2&gt;Wrap It Up!&lt;/h2&gt;

&lt;p&gt;Taking a road trip down to the Hoedown with the Hashrocket crew was one of the
best conference experiences I've had so far. The talks were great, but I think
the after-conference festivities were the real hilight. Watching Obie and Jason
play beer pong on a table constructed of pool noodles (watch the video),
playing werewolf with a crew of drunken rubyists and spending time with some of
my favorite conference friends. Who could ask for more? Also, Jeremy has big
plans for next year's Hoedown. They involve words like &quot;free&quot; and &quot;Nashville&quot;.
I would be inclined to add &quot;awesome&quot; as well.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Adding Epicycles: Copernicus On Software&nbsp;Development</title>
    <link href="http://reinh.com/blog/2008/07/20/adding-epicycles-copernicus-on-software-development.html"/>
    <updated>2008-07-20T00:00:00-07:00</updated>
    <id>http://reinh.com/blog/2008/07/20/adding-epicycles-copernicus-on-software-development</id>
    <content type="html">&lt;p&gt;Most software projects suffer from increasing complexity over their lifetime.
One of the most common ways that a project grows in complexity is known as
&quot;Adding Epicycles&quot;.&lt;/p&gt;

&lt;!--more--&gt;


&lt;p&gt;The geocentric model of the solar system is a very old one. First postulated by
Plato and Aristotle in the 6th century BC, the idea that the Earth is at the
center of the universe was later refined and standardized in Claudius Ptolemy's
main astronomical book, Almagest. It is also an excellent example of a very
common design failure in software development.&lt;/p&gt;

&lt;h2&gt;Ptolemy's Faulty Assumption&lt;/h2&gt;

&lt;p&gt;It seems like a pretty obvious idea: sun, stars, planets&amp;hellip; everything
&lt;em&gt;looks&lt;/em&gt; as if it goes around the Earth. Indeed, it was almost two thousand
years before Copernicus was able to provide a convincing alternative.&lt;/p&gt;

&lt;h2&gt;Ptolemy's Great Design Failure&lt;/h2&gt;

&lt;p&gt;As people began to make better and better observations of the motions of the
various heavenly bodies, they began to notice that their movements were often
far more complex than the Ptolemaic system could allow. The planets were
particularly troublesome in this regard.&lt;/p&gt;

&lt;p&gt;The logical step when a hypothesis no longer fits with observation is to
reconsider that hypothesis and possibly discard it in place of a more fitting
candidate. This is precisely what did not happen when Ptolemy set out to
catalog the arrangements and movements of the celestial spheres.&lt;/p&gt;

&lt;p&gt;What he did instead was add smaller circles that the planets move in, and then
have these circles move on top of their orbital circles. These circles on top
of circles - or &lt;em&gt;epicycles&lt;/em&gt; - form the basis of Ptolemy's new and &quot;improved&quot;
geocentric model.&lt;/p&gt;

&lt;p&gt;Ptolemy's greatest mistake was not made in adopting the geocentric model in the
first place. It was made in not abandoning it when it no longer fit observed
fact. Rather than throw out his bad design, he added more and more layers of
bad design to try to fit the new observations.&lt;/p&gt;

&lt;h2&gt;Copernicus's Great Refactor&lt;/h2&gt;

&lt;p&gt;This process of adding more and more complexity onto complexity continued
through iteration after iteration for almost two thousand years until
Copernicus stepped in. He fixed the bad design at the root of the ridiculously
complex and unwieldy Ptolemaic system by putting the Sun at the center. This
simple change had a profoundly simplifying effect on our understanding of the
motion of the planets and other heavenly bodies.&lt;/p&gt;

&lt;p&gt;Copernicus's heliocentric model is in retrospect a rather simple and obvious
paradigm shift. Nevertheless, it marked the start of the Scientific Revolution
and is often regarded as the starting point of modern astronomy.&lt;/p&gt;

&lt;h2&gt;Copernicus on Software Development&lt;/h2&gt;

&lt;p&gt;What does all of this mean for software developers? It means that if your
system is built on a bad design, trying to accomodate that problem will only
lead you to add more and more levels of bad design. Eventually the whole system
will come crashing down under the weight of this accumulated technical debt.&lt;/p&gt;

&lt;p&gt;This process of iteratively adding layers of complexity and bad design to
attempt to shore up a faulty assumption or hopelessly flawed abstraction is
called &lt;a href=&quot;http://c2.com/cgi/wiki?AddingEpicycles&quot;&gt;Adding Epicycles&lt;/a&gt; in honor of
Ptolemy and his great design failure. The right thing to do is to follow
Copernicus's lead and correct the faulty assumption or poor abstraction that is
at the heart of your design failure. The sooner you do this, the sooner you can
start simplifying your code.&lt;/p&gt;

&lt;p&gt;Correcting a critical design flaw will often cause these layers of circle upon
circle upon preposterous circle of complexty to vanish, leaving your code clean
and clear and simple. Just try not to anger the Pope.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Ruby Patterns: Query Method</title>
    <link href="http://reinh.com/blog/2008/07/17/ruby-patterns-query-method.html"/>
    <updated>2008-07-17T00:00:00-07:00</updated>
    <id>http://reinh.com/blog/2008/07/17/ruby-patterns-query-method</id>
    <content type="html">&lt;p&gt;Today, we will learn how the Query Method pattern handles a set of tensions we often
face while designed object oriented systems.&lt;/p&gt;

&lt;!--more--&gt;


&lt;p&gt;What are patterns? Patterns are learnable and reusable answers to common
programming questions. They are decisions made in response to a number of
different concerns (or tensions). A well written pattern resolves each of the
tensions harmoniously and provides a set of repeatable steps for its
reapplication.&lt;/p&gt;

&lt;p&gt;Let's look at a situation where various tensions pull us towards the need to
make a harmonious design decision and attempt to derive a pattern for future
use. As we do so, we will try to keep in mind the tensions at play and come up
with steps that can be used to reapply the pattern in the future.&lt;/p&gt;

&lt;p&gt;The Query Method pattern answers a particularly common question, &quot;How can I ask
an object for information about itself?&quot; The tensions at play include a desire
to maintain proper encapsulation, a desire to keep code DRY(Don't Repeat
Yourself) and a desire to maintain or improve the readability of the resulting
solution.&lt;/p&gt;

&lt;p&gt;If you don't really care about the discovery process and you want to skip
straight to the pattern itself, it's &lt;a href=&quot;#bottom&quot;&gt;at the bottom&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Discovering A Pattern&lt;/h2&gt;

&lt;p&gt;In a recent blog post on
&lt;a href=&quot;http://www.stephenchu.com/2008/06/learning-encapsulation-should-come.html&quot;&gt;the value of learning encapsulation before learning rails&lt;/a&gt;,
Stephen Chu gives an excellent example of a fragment of ruby code that could be
improved by application of the Query Method pattern. I'll use a slightly
different example:&lt;/p&gt;

&lt;p&gt;``` ruby&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;puts &quot;#{@post.title} is recent.&quot; if @post.published_at &amp;lt; 2.days.ago
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;```&lt;/p&gt;

&lt;p&gt;Let's look at this code in light of some of the different tensions:&lt;/p&gt;

&lt;h3&gt;Encapsulation&lt;/h3&gt;

&lt;p&gt;In his post, Stephen points out that this code breaks encapsulation by yanking
state information out of the object for comparison. The comparison is being
made on post information but it is being made outside the context of the post.
We can change the code a bit to make this more clear:&lt;/p&gt;

&lt;p&gt;``` ruby&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Blog
  def recent_post_list
    @posts.each do |post|
      puts &quot;#{post.title} is recent.&quot; if post.published_at &amp;lt; 2.days.ago
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;```&lt;/p&gt;

&lt;p&gt;The blog that is creating this recent post list shouldn't and needn't know how
to determine if a post is recent. This is the post's responsibility. The blog
should simply ask the post if it is recent and let the post make the
calculation. This desire for encapsulation is the first tension.&lt;/p&gt;

&lt;h3&gt;Don't Repeat Yourself&lt;/h3&gt;

&lt;p&gt;This code seems simple enough. It does one thing and appears to do it
efficiently. There is no violation of DRY yet, but it isn't to difficult to
imagine other situations where we might need to know if a post is recent.&lt;/p&gt;

&lt;p&gt;Let's say we are generating an HTML page and we want to apply a special class
to recent posts. We will need to duplicate this logic inside that method as
well. What if we later decide that we want posts in the last three days instead
of two? Now we have to find each instance of this code fragment so that we can
change it appropriately.&lt;/p&gt;

&lt;p&gt;What a pain! Clearly this code is not DRY and its maintainability is
compromised as a result. This is the second tension.&lt;/p&gt;

&lt;h3&gt;Readability&lt;/h3&gt;

&lt;p&gt;This code looks pretty readable. &lt;code&gt;published_at&lt;/code&gt; and &lt;code&gt;2.days.ago&lt;/code&gt; reveal their
intention quite clearly. If any improvement is to be made, you may think, it
will be incremental and relatively small. Nevertheless, improved readability
means improved maintainability, so it is always worth consideration. This is
the third tension.&lt;/p&gt;

&lt;h2&gt;Composing A Pattern&lt;/h2&gt;

&lt;p&gt;This list of tensions isn't exhaustive but it should be sufficient for us to
begin considering a solution. How can we improve this code in a way that most
effectively addresses all of them?&lt;/p&gt;

&lt;p&gt;This is a case where the tensions are not in direct opposition. It should be
pretty easy to come up with a solution. Let's try to formulate such a pattern,
including the steps necessary to reapply it again in the future.&lt;/p&gt;

&lt;h3&gt;Encapsulation and DRY&lt;/h3&gt;

&lt;p&gt;First, we'll start by encapsulating the comparison inside the post object:&lt;/p&gt;

&lt;p&gt;``` ruby&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Post
  def is_published_at_less_than_two_days_ago?
    published_at &amp;lt; 2.days.ago
  end
end

puts &quot;#{@post.title} is recent.&quot; if @post.is_published_at_less_than_two_days_ago?
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;```&lt;/p&gt;

&lt;p&gt;This resolves the encapsulation tension. By factoring the behavior to a single
location it also resolves the DRY tension. It doesn't do much for our
readability tension, though. Let's see what we can do about that.&lt;/p&gt;

&lt;h3&gt;Readability&lt;/h3&gt;

&lt;p&gt;Patterns can often be improved by the inclusion of smaller, more granular
patterns. In this case, the readability can be improved by providing the method
with an Intention Revealing Selector. An intention revealing selector is, as
the name suggests, one that informs to the user of the intention of the method
rather than its implementation.&lt;/p&gt;

&lt;p&gt;Our current selector - and the code it is based on - informs the user of the
method's implementation. It answers the &quot;how&quot; question. An Intention Revealing
Selector answers the more useful &quot;why&quot; question, as in: why does this method
exist, why would I want to use it?&lt;/p&gt;

&lt;p&gt;So: why does this method exist? It exists so that the post can be asked if it
is recent or not. An intention revealing name for this selector would use the
word &quot;recent&quot; to answer the &quot;why&quot; question.&lt;/p&gt;

&lt;p&gt;The Ruby idiom for a method that is intended to return a boolean value is to
end it with a &quot;?&quot;. Let's apply the Intention Revealing Selector pattern by
giving the method an intention revealing name and ending it with a
&quot;?&quot;.&lt;/p&gt;

&lt;p&gt;``` ruby&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Post
  def recent?
    published_at &amp;lt; 2.days.ago
  end
end

puts &quot;#{post.title} is recent.&quot; if post.recent?
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;```&lt;/p&gt;

&lt;p&gt;I think you'll agree that this new method resolves all of the tensions
harmoniously. The behavior is properly encapsulated, it is DRY because it is
defined Once And Only Once, and it is significantly more readable than the
original because it reveals its intention rather than its implementation.&lt;/p&gt;

&lt;p&gt;Thus, we can formulate the Query Method Pattern as such:&lt;/p&gt;

&lt;h2&gt;Formulating The Query Method Pattern&lt;/h2&gt;

&lt;p&gt;When you want to query an object about itself in a way that is properly
encapsulated, DRY and more readable, follow these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Write a method that performs the query.&lt;/li&gt;
&lt;li&gt;Put it inside the object that holds the information being queried.&lt;/li&gt;
&lt;li&gt;Give it an Intention Revealing Selector.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;The next time you're faced with this design question, you can apply the Query
Method pattern.&lt;/p&gt;

&lt;p&gt;Hopefully this process will help you begin to identify patterns of your own. If
you're interested in learning more about patterns (and you should be), I highly
recommend
&lt;a href=&quot;http://www.amazon.com/Smalltalk-Best-Practice-Patterns-Kent/dp/013476904X&quot;&gt;Smalltalk Best Practice Patterns&lt;/a&gt;
by Kent Beck (non-affiliate link). It's worth learning Smalltalk just to be
able to understand the code examples.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>A Thinking Man's Sphinx</title>
    <link href="http://reinh.com/blog/2008/07/14/a-thinking-mans-sphinx.html"/>
    <updated>2008-07-14T00:00:00-07:00</updated>
    <id>http://reinh.com/blog/2008/07/14/a-thinking-mans-sphinx</id>
    <content type="html">&lt;p&gt;Today, we'll explore the differences between UltraSphinx and ThinkingSphinx and
why we chose to switch to ThinkingSphinx.&lt;/p&gt;

&lt;!--more--&gt;


&lt;p&gt;We've recently switched a number of projects to
&lt;a href=&quot;http://ts.freelancing-gods.com/&quot;&gt;ThinkingSphinx&lt;/a&gt; here at
&lt;a href=&quot;http://www.hashrocket.com&quot;&gt;Hashrocket&lt;/a&gt;. These projects were originally using
SOLR or &lt;a href=&quot;http://blog.evanweaver.com/files/doc/fauna/ultrasphinx/files/README.html&quot;&gt;UltraSphinx&lt;/a&gt;.
UltraSphinx is written by &lt;a href=&quot;http://blog.evanweaver.com/&quot;&gt;Evan Weaver&lt;/a&gt;.
ThinkingSphinx is written by &lt;a href=&quot;http://freelancing-gods.com/&quot;&gt;Pat Allan&lt;/a&gt;. They
have some similarities: both use Sphinx (obviously); both are based on the
underlying Ruby API for Sphinx, &lt;a href=&quot;http://riddle.freelancing-gods.com/&quot;&gt;Riddle&lt;/a&gt;
(also by Pat Allan); both have excellent documentation and well-written
tutorials. The similarities pretty much end there, however, and the differences
are far more interesting.&lt;/p&gt;

&lt;h2&gt;Basic Sphinx Configuration&lt;/h2&gt;

&lt;p&gt;Both plugins help you generate a sphinx.conf file for your each of your rails
environments, but they do it in drastically different ways. ThinkingSphinx lets
you use a configuration format you are already used to at the expense of
reduced configuration options. UltraSphinx is more flexible but less Rubyish.&lt;/p&gt;

&lt;h3&gt;UltraSphinx&lt;/h3&gt;

&lt;p&gt;UltraSphinx generates the sphinx.conf file from a base configuration file. This
base file uses the sphinx configuration syntax, passing it through ERB for some
DRYness. A base file can be specified per-environment. It puts all of its
configuration information in &lt;code&gt;RAILS_ROOT/config/ultrasphinx/&lt;/code&gt;. This provides
fine-grained - if rather tediously verbose - control over the multitude of
Sphinx configuration options.&lt;/p&gt;

&lt;h3&gt;ThinkingSphinx&lt;/h3&gt;

&lt;p&gt;ThinkingSphinx uses a YAML configuration file that it locates at
&lt;code&gt;RAILS_ROOT/config/sphinx.yml&lt;/code&gt;. It accepts a YAML hash of configuration
settings. These settings allow you to specify most of the basic Sphinx
configuration options with ease but you may be out of luck if the option you
need isn't available.&lt;/p&gt;

&lt;h2&gt;Basic Index Configuration&lt;/h2&gt;

&lt;p&gt;Let's start with a basic example of a sphinx index declaration. Keep in mind
that your indexes will likely be significantly more complex in the real world.&lt;/p&gt;

&lt;h3&gt;UltraSphinx&lt;/h3&gt;

&lt;p&gt;UltraSphinx uses a declarative &lt;code&gt;is_indexed&lt;/code&gt; statement in the model that feels
vaguely similar in style to an association or named scope declaration. This is
the usage example given in the
&lt;a href=&quot;http://blog.evanweaver.com/files/doc/fauna/ultrasphinx/files/README.html&quot;&gt;README&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;``` ruby&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Post
  is_indexed :fields =&amp;gt; ['created_at', 'title', 'body']
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;```&lt;/p&gt;

&lt;p&gt;This seems simple enough for such a simple case. We'll see how it looks for
less trivial cases.&lt;/p&gt;

&lt;h3&gt;ThinkingSphinx&lt;/h3&gt;

&lt;p&gt;ThinkingSphinx, on the other hand, uses a &lt;code&gt;define_index&lt;/code&gt; block in the model to
allow the individual index configuration options to be stated declaratively.
The canonical example from UltraSphinx would look like this in ThinkingSphinx:&lt;/p&gt;

&lt;p&gt;``` ruby&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Post
  define_index do
    indexes created_at, title, body
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;```&lt;/p&gt;

&lt;p&gt;The first thing you may notice is that the same index configuration is three
lines in ThinkingSphinx instead of one in UltraSphinx. If you look closely,
you'll also see that the field names are not symbols as you might expect but
method calls. We'll get into why this is in a moment.&lt;/p&gt;

&lt;h2&gt;Real World Index Configuration&lt;/h2&gt;

&lt;p&gt;Your real world applications are likely to require a significantly more complex
index declaration to meet the search needs of your users. Let's look at an
example of such a real world Sphinx index declaration.&lt;/p&gt;

&lt;h3&gt;UltraSphinx&lt;/h3&gt;

&lt;p&gt;Here's an example of a more realistic UltraSphinx index configuration. This is
the type of configuration you're likely to use on any non-trivial project.&lt;/p&gt;

&lt;p&gt;``` ruby&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Post &amp;lt; ActiveRecord::Base
  belongs_to :blog
  belongs_to :category

  is_indexed :conditions =&amp;gt; &quot;posts.state = 'published'&quot;,
             :fields     =&amp;gt; [{:field =&amp;gt; 'title', :sortable =&amp;gt; true},
                             {:field =&amp;gt; 'body'},
                             {:field =&amp;gt; 'cached_tag_list'}],
             :include    =&amp;gt; [{:association_name =&amp;gt; &quot;blog&quot;,
                              :field            =&amp;gt; &quot;title&quot;,
                              :as               =&amp;gt; &quot;blog&quot;,
                              :sortable         =&amp;gt;  true},
                             {:association_name =&amp;gt; &quot;blog&quot;,
                              :field            =&amp;gt; &quot;description&quot;,
                              :as               =&amp;gt; &quot;blog_description&quot;},
                             {:association_name =&amp;gt; &quot;category&quot;,
                              :field            =&amp;gt; &quot;title&quot;,
                              :as               =&amp;gt; &quot;category&quot;,
                              :sortable         =&amp;gt;  true}]
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;```&lt;/p&gt;

&lt;p&gt;This is about as pretty as it's going to get - and that's not very pretty.
Large, deeply nested hashes of arrays of hashes are not easily scannable and
will become exponentially difficult to maintain as their size and complexity
increases.&lt;/p&gt;

&lt;h3&gt;ThinkingSphinx&lt;/h3&gt;

&lt;p&gt;Let's look at that same example translated to ThinkingSphinx.&lt;/p&gt;

&lt;p&gt;``` ruby&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Post &amp;lt; ActiveRecord::Base
  belongs_to :blog
  belongs_to :category

  define_index do
    indexes title, :sortable =&amp;gt; true
    indexes body, cached_tag_list

    indexes blog.description, :as =&amp;gt; :blog_description
    indexes blog.title,       :as =&amp;gt; :blog,     :sortable =&amp;gt; true
    indexes category.title,   :as =&amp;gt; :category, :sortable =&amp;gt; true

    where &quot;posts.state = 'published'&quot;
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;```&lt;/p&gt;

&lt;p&gt;Not only did the number of lines decrease, the readability is far greater. I
know which one I'd rather write. More importantly, I know which one I'd rather
have to maintain weeks or months downline when it needs to be modified.&lt;/p&gt;

&lt;p&gt;Notice that the declarations use methods rather than symbols. ThinkingSphinx
uses some interesting metaprogramming to allow this. Notice also that indexed
fields on associations are specified in the same way you would access that
field. Simple.&lt;/p&gt;

&lt;h2&gt;Sphinx Rake Tasks&lt;/h2&gt;

&lt;p&gt;Both UltraSphinx and ThinkingSphinx provide a number of rake tasks for common
sphinx tasks such as generating the configuration file; generating the index;
and starting, stopping, and restarting the searchd daemon. Both provide
abbreviations for the more common task, such as &lt;code&gt;ts:in&lt;/code&gt; for
&lt;code&gt;thinking_sphinx:index&lt;/code&gt; or &lt;code&gt;us:conf&lt;/code&gt; for &lt;code&gt;ultrasphinx:configure&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;Deployment and Configuration Management&lt;/h2&gt;

&lt;p&gt;Both UltraSphinx and ThinkingSphinx are pretty simple to deploy. You should
symlink your configuration file from a shared location into your app's path
after deployment, just as you probably do for your &lt;code&gt;database.yml&lt;/code&gt; file. You
will probably want to run the configuration task after you update the code.
Here, for instance, is a Capistrano task to run your ThinkingSphinx
configuration task:&lt;/p&gt;

&lt;p&gt;``` ruby&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;namespace :sphinx do
  desc &quot;Generate the ThinkingSphinx configuration file&quot;
  task :configure do
    run &quot;cd #{release_path} &amp;amp;&amp;amp; rake thinking_sphinx:configure&quot;
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;```&lt;/p&gt;

&lt;p&gt;You'll want to have this task run after each deployment:&lt;/p&gt;

&lt;p&gt;``` ruby&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;after &quot;deploy:update_code&quot;, &quot;sphinx:configure&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;```&lt;/p&gt;

&lt;p&gt;You can create other tasks relatively easily for reindexing and managing the
searchd daemon. I found a good guide to
&lt;a href=&quot;http://www.updrift.com/article/deploying-a-rails-app-with-thinking-sphinx&quot;&gt;deploying a rails app with ThinkingSphinx&lt;/a&gt;
linked from Pat Allan's blog. I found a useful set of
&lt;a href=&quot;http://github.com/ruberion/ruberion_server_tools/tree/master/recipes/tasks/ultrasphinx.rb&quot;&gt;UltraSphinx capistrano tasks&lt;/a&gt;
in Ruberion's server tools plugin on Github. If you chose to host with
&lt;a href=&quot;http://www.engineyard.com/&quot;&gt;EngineYard&lt;/a&gt;, they can manage either configuration
for you with their pre-baked builds and deploy tasks.&lt;/p&gt;

&lt;h2&gt;Real World Experience&lt;/h2&gt;

&lt;p&gt;We ran into a number of issues when setting up UltraSphinx:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;UltraSphinx loads your models without loading the full rails environment. This means that if
your models depend on any of your lib files or any gems frozen in vendor/gems, you will have to
require all of these files explicitly in each model. This is a pain.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The fundamentally sound design and code of UltraSphinx are somewhat undermined by poorly
implemented exception handling. This means that while most of the time things work swimmingly,
when they fail you're really sunk! The errors that you receive are often useless in diagnosing
the actual problem.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We had bugs in our index that only existed on our staging and production slices. These caused
page counts to be incorrect and nil records to be returned in certain cases. In certain cases it
also caused 5xx errors.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;Moving To ThinkingSphinx&lt;/h3&gt;

&lt;p&gt;After another Hashrocket team had success moving their project from SOLR to
ThinkingSphinx, I decided to move our project as well. Moving to ThinkingSphinx
proved to be a relatively painless experience. The process was essentially
five-fold:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Uninstall UltraSphinx and install ThinkingSphinx.&lt;/li&gt;
&lt;li&gt;Translate your &lt;code&gt;is_indexed&lt;/code&gt; declaration into a @define_index@ block and change your search actions to use the ThinkingSphinx API.&lt;/li&gt;
&lt;li&gt;Rewrite your deployment tasks to run the ThinkingSphinx rake tasks.&lt;/li&gt;
&lt;li&gt;Stop searchd and then run your new configure, index and startd start tasks.&lt;/li&gt;
&lt;li&gt;PROFIT!&lt;/li&gt;
&lt;/ul&gt;

</content>
  </entry>
  
  <entry>
    <title>Git Push: Just The Tip</title>
    <link href="http://reinh.com/blog/2008/04/18/git-push-just-the-tip.html"/>
    <updated>2008-04-18T00:00:00-07:00</updated>
    <id>http://reinh.com/blog/2008/04/18/git-push-just-the-tip</id>
    <content type="html">&lt;p&gt;Today we delve into the world of &lt;code&gt;git push&lt;/code&gt;, one of the most often used git
tools. &lt;code&gt;git push&lt;/code&gt; is typically used to update a remote ref and associated
objects based on a local ref -- in other words, to push your local changes to an
upstream repository -- but you can also use it to create or delete remote
branches and &lt;del&gt;much, much more!&lt;/del&gt; actually, that's about it.&lt;/p&gt;

&lt;!--more--&gt;


&lt;h2&gt;Just The Tip&lt;/h2&gt;

&lt;p&gt;The most common use of &lt;code&gt;git push&lt;/code&gt; is to push your local changes to your public
upstream repository. Assuming that the upstream is a remote named &quot;origin&quot; (the
default remote name if your repository is a clone) and the branch to be updated
to/from is named &quot;master&quot; (the default branch name), this is done with:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git push origin master
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Get used to this. You'll be doing it a lot.&lt;/p&gt;

&lt;h2&gt;A Bit Deeper&lt;/h2&gt;

&lt;p&gt;Git uses the term &quot;refspec&quot; when describing the usage of some of its commands.
A refspec is essentially a name that git can resolve to a commit object. This
can be the name of a branch or an arbitrary &quot;SHA1 expression&quot; such as
&lt;code&gt;master~4&lt;/code&gt;, among
&lt;a href=&quot;http://www.kernel.org/pub/software/scm/git/docs/git-rev-parse.html&quot;&gt;others&lt;/a&gt;.
Git gives you a lot of ways to refer to a commit but for most purposes you'll
just use the name of a branch with &lt;code&gt;git push&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;a href=&quot;http://www.kernel.org/pub/software/scm/git/docs/git-pull.html&quot;&gt;kernel.org manpage for git pull&lt;/a&gt;
will rather cryptically tell you that &quot;The canonical format of a
&amp;lt;refspec&amp;gt; parameter is &lt;code&gt;+?&amp;lt;src&amp;gt;:&amp;lt;dst&amp;gt;&lt;/code&gt;&quot;. Most of the time this translates
to &lt;code&gt;&amp;lt;branch to push from&amp;gt;:&amp;lt;branch to push to&amp;gt;&lt;/code&gt;. The branch to push from and the
colon are optional. If left out, git will push from the local branch to the
remote branch of the same name. If no refspec is used at all, git will push all
&quot;heads&quot; (f.e. branches) on the local to matching heads that exist on the
remote.&lt;/p&gt;

&lt;p&gt;In practice, this means that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;git push origin&lt;/code&gt; will push changes from all local branches to matching branches the origin remote.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git push origin master&lt;/code&gt; will push changes from the local master branch to the remote master branch.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git push origin master:staging&lt;/code&gt; will push changes from the local master branch to the remote staging branch &lt;em&gt;if it exists&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;Tips and Tricks&lt;/h2&gt;

&lt;h3&gt;Create a Remote Branch&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;git push origin master:refs/heads/staging&lt;/code&gt; will create the branch &lt;code&gt;staging&lt;/code&gt; in
the origin by copying the local @master@ branch&lt;/p&gt;

&lt;h3&gt;Delete a Remote Branch&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;git push origin :staging&lt;/code&gt; will delete the branch &lt;code&gt;staging&lt;/code&gt; from the origin repository.&lt;/p&gt;

&lt;h3&gt;Set Up A Branch's Default Remote&lt;/h3&gt;

&lt;p&gt;You can use git config to assign a default remote to a given branch. This
default remote will be used to push that branch unless otherwise specified.&lt;/p&gt;

&lt;p&gt;This is already done for you when you use &lt;code&gt;git clone&lt;/code&gt;, allowing you to use &lt;code&gt;git
push&lt;/code&gt; without any arguments to push the local master branch to update the
origin repository's master branch.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git config branch.&amp;lt;name&amp;gt;.remote &amp;lt;remote&amp;gt;&lt;/code&gt; can be used to specify this manually.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Custom Textile Tags For Great Justice</title>
    <link href="http://reinh.com/blog/2008/04/09/customize-textile-tags-for-great-justice.html"/>
    <updated>2008-04-09T00:00:00-07:00</updated>
    <id>http://reinh.com/blog/2008/04/09/customize-textile-tags-for-great-justice</id>
    <content type="html">&lt;p&gt;Taking some inspiration (and code) from the quirky but lovable why's original
post on &lt;a href=&quot;http://redhanded.hobix.com/inspect/usingRedcloth3.html&quot;&gt;adding yer custom blocks&lt;/a&gt; to RedCloth and
the inimitable Geoff Grosenbach's foray into the world of
&lt;a href=&quot;http://nubyonrails.com/articles/about-this-blog-custom-textile&quot;&gt;custom textile figure tags&lt;/a&gt;,
we're going to implement a customer textile tag for our blog's thumbnail
images.&lt;/p&gt;

&lt;!--more--&gt;


&lt;p&gt;RedCloth's textile implementation uses some simple metaprogramming to create
its own tags, which allows you to (more or less) easily create new tags to suit
your own needs. The basic formula is: write a &lt;code&gt;textile_#{ tag }&lt;/code&gt; method, where
&lt;code&gt;tag&lt;/code&gt; is the name of the tag you want to create. This method takes four
arguments, tag, atts, cite and content, which are parsed from the textile by
the RedCloth engine.&lt;/p&gt;

&lt;p&gt;For our purposes, we're only concerned with content and atts, so I'll leave the
rest as an exercise for the gentle reader. The html we're trying to create
looks like this:&lt;/p&gt;

&lt;p&gt;``` ruby&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;div class=&quot;img&quot; id=&quot;figure-1-1&quot;&amp;gt;
  &amp;lt;a class=&quot;fig&quot; href=&quot;http://reinh.com/images/image.jpb&quot;&amp;gt;
    &amp;lt;img src=&quot;http://reinh.com/images/thumbs/image.jpg&quot; alt=&quot;Figure 1.1&quot; /&amp;gt;
  &amp;lt;/a&amp;gt;
  &amp;lt;p&amp;gt;Figure 1.1&amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;```&lt;/p&gt;

&lt;p&gt;The tag we want to use to create it looks like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;fig. 1.1 | image.jpg
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That's quite a bit shorter and more elegant. Jumping right in to the good
stuff, the method definition for our new tag looks like this:&lt;/p&gt;

&lt;p&gt;``` ruby&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def textile_fig(tag, atts, cite, content)
  span_class = &quot;img &quot;
  if atts =~ /class=&quot;([^\&quot;]+)&quot;/
    span_class += $1
  end
  (figure_number, img_url) = content.split(&quot;|&quot;).map { |w| w.strip }
  figure_name = &quot;Figure #{figure_number}&quot;
  figure_id = &quot;figure-#{figure_number}&quot;.tr(&quot;.&quot;, &quot;-&quot;)

  &amp;lt;&amp;lt;-TAG
  &amp;lt;div class=&quot;#{span_class}&quot; id=&quot;#{figure_id}&quot;&amp;gt;
    &amp;lt;a class=&quot;fig&quot; href=&quot;http://reinh.com/images/#{img_url}&quot;&amp;gt;
      &amp;lt;img src=&quot;http://reinh.com/images/thumbs/#{img_url}&quot; alt=&quot;#{figure_name}&quot; /&amp;gt;
    &amp;lt;/a&amp;gt;
    &amp;lt;p&amp;gt;#{figure_name}&amp;lt;/p&amp;gt;
  &amp;lt;/div&amp;gt;
  TAG
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;```&lt;/p&gt;

&lt;p&gt;Let's break that down.&lt;/p&gt;

&lt;p&gt;``` ruby&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;span_class = &quot;img &quot;
if atts =~ /class=&quot;([^\&quot;]+)&quot;/
  span_class += $1
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;```&lt;/p&gt;

&lt;p&gt;This adds any classes in atts (in the form of &lt;code&gt;class=&quot;foo&quot;&lt;/code&gt;) to the base class,
img.&lt;/p&gt;

&lt;p&gt;``` ruby&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(figure_number, img_url) = content.split(&quot;|&quot;).map { |w| w.strip }
figure_name = &quot;Figure #{figure_number}&quot;
figure_id = &quot;figure-#{figure_number}&quot;.tr(&quot;.&quot;, &quot;-&quot;)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;```&lt;/p&gt;

&lt;p&gt;This breaks &lt;code&gt;fig 1.1 | image.jpg&lt;/code&gt; down into two parts by splitting on the &lt;code&gt;|&lt;/code&gt;
and then normalizes them a bit to be used later.&lt;/p&gt;

&lt;p&gt;Finally, the relevant parts are jammed into the html prototype and spit back as
the method's return value for insertion into your textile document (and for
great justice, of course).&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Simple Git Continuous Integration</title>
    <link href="http://reinh.com/blog/2008/02/12/git-pre-commit-hook.html"/>
    <updated>2008-02-12T00:00:00-08:00</updated>
    <id>http://reinh.com/blog/2008/02/12/git-pre-commit-hook</id>
    <content type="html">&lt;p&gt;The easiest way to prevent a broken build is to run your tests before you
commit. This can be done with a simple git hook. Preventing your developers
(and yourself) from breaking the build is as simple as putting this in your
.git/hooks/pre-commit and making it executable: &lt;code&gt;chmod +x
.git/hooks/pre-commit&lt;/code&gt;.&lt;/p&gt;

&lt;!--more--&gt;


&lt;p&gt;``` sh&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/bin/sh
rake spec 2&amp;gt; /dev/null
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;```&lt;/p&gt;

&lt;p&gt;This will stop the commit if the specs don’t pass.&lt;/p&gt;

&lt;p&gt;This isn’t a replacement for a more robust CI system but it does make it a lot
harder to do something stupid. Redirecting &lt;code&gt;STDERR&lt;/code&gt; to &lt;code&gt;/dev/null&lt;/code&gt; is optional but
recommended since the &lt;code&gt;STDERR&lt;/code&gt; output of failing specs isn’t useful. It you use
Test::Unit instead of RSpec (for shame), use rake test instead. Likewise,
anything that returns proper error codes (0 for success, &gt; 0 for failure) can
be used.&lt;/p&gt;

&lt;p&gt;This is mainly useful if your specs take under a minute to run, otherwise it
becomes tedious. If you have long-running specs, I suggest using a special task
that runs an abridged set of core specs instead.&lt;/p&gt;
</content>
  </entry>
  
</feed>

