<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" xml:lang="en-US">
  <title>Relevance - Relevance Weblog</title>
  <id>tag:blog.thinkrelevance.com,2009:mephisto/</id>
  <generator version="0.8.0" uri="http://mephistoblog.com">Mephisto Drax</generator>
  
  <link href="http://blog.thinkrelevance.com/" rel="alternate" type="text/html" />
  <updated>2009-10-20T12:21:55Z</updated>
  <link rel="self" href="http://feeds.feedburner.com/relevance-llc" type="application/atom+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><entry xml:base="http://blog.thinkrelevance.com/">
    <author>
      <name>glenn</name>
    </author>
    <id>tag:blog.thinkrelevance.com,2009-10-20:11504</id>
    <published>2009-10-20T12:16:00Z</published>
    <updated>2009-10-20T12:21:55Z</updated>
    <category term="names" />
    <category term="naming" />
    <category term="rspec" />
    <link href="http://feedproxy.google.com/~r/relevance-llc/~3/W4Y3QmNGDks/the-power-of-names" rel="alternate" type="text/html" />
    <title>The Power of Names</title>
<content type="html">
            &lt;p&gt;Last week I had a great time at the &lt;a href="http://www.railssummit.com.br/en/pages/home"&gt;Latin America Rails Summit&lt;/a&gt;.
(Thanks to the &lt;a href="http://www.locaweb.com/default.html"&gt;organizers&lt;/a&gt; for inviting me!)
During breaks in the action here and there, I spent time working on &lt;a href="http://github.com/relevance/tarantula"&gt;Tarantula&lt;/a&gt;,
and for a lot of that time I was sitting with &lt;a href="http://chadfowler.com/"&gt;Chad Fowler&lt;/a&gt; and &lt;a href="http://davidchelimsky.net/"&gt;David Chelimsky&lt;/a&gt;.
David was working on &lt;a href="http://rspec.info/"&gt;RSpec&lt;/a&gt;, and asked Chad and me for help coming up with a good name for a method.
The ensuing conversation struck all of us as a great example of the power of good names.&lt;/p&gt;

&lt;p&gt;It’s often very difficult to find just the right name for something in a program.
It’s also hard to understand why names are so important.
Names are just symbols, after all, and in some sense they’re arbitrary.
Certainly the computer doesn’t care what name you use for something, as long as you’re consistent.
And programmers are fairly good at dealing with arbitrary names;
think of all the acronyms we use without ever thinking of what the letters stand for,
and repurposed words like “bus,” “mask,” and “string,” with technical meanings that bear little resemblance to the original English meanings.&lt;/p&gt;

&lt;p&gt;So if we can deal with non-optimal names just fine, and choosing good names is really difficult, it hardly seems worth it.
But good programmers understand the value of names.
This story illustrates how hard it can be to find just the right name,
and also how good names can help you to understand your own program and domain in deeper ways.&lt;/p&gt;

&lt;h2&gt;Wrapping Assertions&lt;/h2&gt;

&lt;p&gt;David was working on RSpec’s built-in &lt;a href="http://weblog.jamisbuck.org/2006/4/20/writing-domain-specific-languages"&gt;DSL&lt;/a&gt; for defining matchers.
A matcher in RSpec is the object that actually tests a particular condition to determine whether or not it holds,
along with a method that’s used to select the desired matcher.
There was a time when creating a matcher was a bit cumbersome, but David and other RSpec contributors have made it much easier over time, and part of that is a little DSL.
Here’s an example, from the RSpec docs:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Spec::Matchers.define :be_in_zone do |zone|
  match do |player|
    player.in_zone?(zone)
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That snippet creates a matcher called &lt;code&gt;be_in_zone&lt;/code&gt; that checks whether a supplied player (the &lt;em&gt;actual&lt;/em&gt; value, in traditional unit-testing parlance) is in the &lt;em&gt;expected&lt;/em&gt; zone.
With that matcher defined, a programmer can write an expectation in this form:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;bob.should be_in_zone(3)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In some situations, RSpec needs to work with assertions defined for test/unit.
That works just fine;
when using RSpec with Rails, for example, you can use Rails’ custom assertions like &lt;code&gt;assert_select&lt;/code&gt; and it just works.
But RSpec users would like to be able to easily wrap an assertion in an RSpec matcher, so that their tests are more consistent.&lt;/p&gt;

&lt;p&gt;That’s the feature David was working on:
support in the matcher DSL for calling a test/unit assertion and mapping that to RSpec semantics.
The matcher needs to call the assertion, determine the result, and report that result the way an RSpec matcher is supposed to.&lt;/p&gt;

&lt;p&gt;David wrote the first version without thinking about names very much (just to get it working) and came up with the &lt;code&gt;wrapped_assertion&lt;/code&gt; method, used like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Spec::Matchers.define :equal do |expected|
  match do |actual|
    wrapped_assertion(AssertionFailedError) do
      assert_equal expected, actual
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Both test/unit and RSpec recognize three results of a check: success, failure, and error.
Success is when everything happens as expected.
An error occurs when the code under test (or perhaps the test itself) raises some unexpected exception.
Failure, on the other hand, happens when the code all seems to work (in the sense of not raising any exceptions) but one of the expectations is not met.
In test/unit, failure is indicated when an assertion raises &lt;code&gt;AssertionFailedError&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So two of the three situations are indicated when an exception is raised;
the distinction lies in &lt;em&gt;which&lt;/em&gt; exception.
The definition of &lt;code&gt;wrapped_assertion&lt;/code&gt; is explicit about that:
it takes an argument that is the exception class representing failure.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def wrapped_assertion(error_to_rescue)
  begin
    yield
    true
  rescue error_to_rescue
    false
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As you can see, the matcher is supposed to indicate success by returning &lt;code&gt;true&lt;/code&gt; and failure by returning &lt;code&gt;false&lt;/code&gt;.
Any unexpected exception just bubbles out of the method, indicating an error.&lt;/p&gt;

&lt;p&gt;When that was working, David checked it in and asked Chad and me for our thoughts about a better name than &lt;code&gt;wrapped_assertion&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;He started by explaining the situation and refreshing our memory about the semantics.
We promptly threw out some possibilities:
&lt;code&gt;fail_when&lt;/code&gt;, &lt;code&gt;fail_on&lt;/code&gt;, &lt;code&gt;fail_on_raise&lt;/code&gt; … I don’t remember all of the suggestions,
but I know those were in the mix.
And I think we settled on &lt;code&gt;fail_when_raises&lt;/code&gt;, because that made sense even if the parameter was optional and omitted:
&lt;code&gt;fail_when_raises&lt;/code&gt; will fail when any exception is thrown, whereas &lt;code&gt;fail_when_raises(AssertionFailedError)&lt;/code&gt; will fail only when that explicit error is thrown.&lt;/p&gt;

&lt;p&gt;That was that, we thought.
It was dinner time, so we closed our laptops and forgot about the problem.&lt;/p&gt;

&lt;h2&gt;Keeping the Domains Straight&lt;/h2&gt;

&lt;p&gt;The next day, however, we found ourselves around a different table, back to working on our three different projects.
David realized he wasn’t happy with the method name, for a subtle reason.&lt;/p&gt;

&lt;p&gt;This is a method that bridges two domains: the test/unit domain and the RSpec domain.
Inside the method, test/unit rules: we call an assert method and interpret the result.
Outside the method, however, is the domain of RSpec.
The method name needs to be expressed in RSpec terminology that’s appropriate for the situation.&lt;/p&gt;

&lt;p&gt;The test/unit terminology of success, failure, and error &lt;em&gt;does&lt;/em&gt; apply to RSpec, but not at the level of matchers.
A match expression is not a complete expectation in RSpec; it only constitutes an expectation when matched with a &lt;em&gt;should&lt;/em&gt; or &lt;em&gt;should_not&lt;/em&gt;, like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;actual.should match(expected)
# or
actual.should_not match(expected)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So the matcher either matches or not, and returns true or false to indicate that.
The presence of &lt;code&gt;should&lt;/code&gt; or &lt;code&gt;should_not&lt;/code&gt; indicates whether that match was expected, and translates it to success or failure.
(This allows a single matcher to handle both positive and negative expectations, as opposed to test/unit assertions, which tend to come in positive/negative pairs such as &lt;code&gt;assert_equal&lt;/code&gt; and &lt;code&gt;assert_not_equal&lt;/code&gt;.)&lt;/p&gt;

&lt;p&gt;Method names including the words “fail” or “succeed” were letting the test/unit domain leak out of the method body.
A better name would be expressed in RSpec terminology.
We toyed with &lt;code&gt;false_when_raises&lt;/code&gt; until Chad suggested &lt;code&gt;match_unless_raises&lt;/code&gt; and we all knew it was right.&lt;/p&gt;

&lt;h2&gt;Deeper Understanding&lt;/h2&gt;

&lt;p&gt;At that point we all thought we were done, and I mentioned that it would be good to blog about the whole dialogue;
many programmers don’t take names very seriously, and it would be good to show the real experience of three good 
programmers spending more than 5 minutes, in two separate conversations spread across two days, on a name for one simple method.&lt;/p&gt;

&lt;p&gt;But the big payoff was yet to come.
Once the correct name was in place, it helped David to see something important about his problem domain.&lt;/p&gt;

&lt;p&gt;Let’s look at that original example again, now with the new name:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Spec::Matchers.define :equal do |expected|
  match do |actual|
    match_unless_raises(AssertionFailedError) do
      assert_equal expected, actual
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There’s repetition there—the parallel structure of &lt;code&gt;match&lt;/code&gt; and &lt;code&gt;match_unless_raises&lt;/code&gt;—that is a clue to something wrong.
David noticed it immediately and realized that &lt;code&gt;match_unless_raises&lt;/code&gt; should be promoted to the same level of the API as &lt;code&gt;match&lt;/code&gt;.
Now the example is beautifully simple:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Spec::Matchers.define :equal do |expected|
  match_unless_raises(AssertionFailedError) do |actual|
    assert_equal expected, actual
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That’s all it takes to write a matcher that wraps a test/unit assertion.&lt;/p&gt;

&lt;p&gt;A lot has been written about the importance of names in programming, including Tim Ottinger’s classic
&lt;a href="http://www.objectmentor.com/resources/articles/Naming.pdf"&gt;Ottinger’s Rules for Variable and Class Naming&lt;/a&gt;.
Good names help us communicate with other programmers, and with our customers.
The notion of the &lt;a href="http://c2.com/cgi/wiki?UbiquitousLanguage"&gt;ubiquitous language&lt;/a&gt; that features so prominently in &lt;a href="http://en.wikipedia.org/wiki/Domain-driven_design"&gt;domain-driven design&lt;/a&gt;
is based largely on the choice of good, meaningful, shared names.&lt;/p&gt;

&lt;p&gt;But good names also reflect the clarity of our thinking, and help us to communicate with &lt;em&gt;ourselves&lt;/em&gt; about our own thoughts.
And when we get the names right, our code and the problem domain can speak clearly to us, revealing accidental complexity
and the underlying simplicity we’re searching for.&lt;/p&gt;

&lt;p&gt;Good names are worth the trouble.&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/relevance-llc/~4/W4Y3QmNGDks" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://blog.thinkrelevance.com/2009/10/20/the-power-of-names</feedburner:origLink></entry>
  <entry xml:base="http://blog.thinkrelevance.com/">
    <author>
      <name>stu</name>
    </author>
    <id>tag:blog.thinkrelevance.com,2009-10-19:11496</id>
    <published>2009-10-19T18:52:00Z</published>
    <updated>2009-10-19T18:54:23Z</updated>
    <category term="Clojure" />
    <category term="clojure" />
    <link href="http://feedproxy.google.com/~r/relevance-llc/~3/DTihSCfvWwg/the-case-for-clojure" rel="alternate" type="text/html" />
    <title>The Case for Clojure</title>
<content type="html">
            &lt;p&gt;The case for Clojure is &lt;a href="http://www.infoq.com/presentations/Value-Identity-State-Rich-Hickey"&gt;richly detailed&lt;/a&gt; and &lt;a href="http://www.pragprog.com/titles/shcloj/programming-clojure"&gt;well-documented&lt;/a&gt;. But sometimes you just want the elevator pitch. OK, but I hope your building has four elevators:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Concurrency is not the problem! &lt;em&gt;State&lt;/em&gt; is the problem. Clojure's sweet spot is any application that has state."&lt;/li&gt;
&lt;li&gt;"Don't burn your legacy code! Clojure is a better Java than Java."&lt;/li&gt;
&lt;li&gt;"Imperative programming and gratuitous complexity go hand in hand. Write functional Clojure and get shit done."&lt;/li&gt;
&lt;li&gt;"Design Patterns are a disease, and Clojure is the cure."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Any one of these ideas would justify giving Clojure a serious look. The four together are a perfect storm. Over the next few months I will be touring the United States and Europe to expand on each of these themes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Clojure's sweet spot is any application that has state." At &lt;a href="http://www.oredev.org"&gt;Oredev&lt;/a&gt;, I will be &lt;a href="http://www.oredev.org/Prod/Oredev/site.nsf/docsbycodename/speaker?opendocument&amp;amp;amp;sp_id=CB24F56F26E811FDC12575D5003AC6B7"&gt;speaking&lt;/a&gt; on Clojure and Clojure concurrency. I will demonstrate how Clojure's functional style simplifies code, and how mere mortals can use Clojure's elegant concurrency support.&lt;/li&gt;
&lt;li&gt;"Clojure is a better Java than Java." I will be speaking on Clojure and other &lt;a href="http://blog.thinkrelevance.com/2008/9/24/java-next-overview"&gt;Java.next&lt;/a&gt; languages at NFJS in &lt;a href="http://www.nofluffjuststuff.com/conference/atlanta/2009/10/home"&gt;Atlanta&lt;/a&gt; and &lt;a href="http://www.nofluffjuststuff.com/conference/reston/2009/11/home"&gt;Reston&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;"Design Patterns are a disease, and Clojure is the cure." I will sing a &lt;a href="http://www.rubyconf.org/talks/13-clojure-for-ruby-programmers"&gt;siren song of Clojure&lt;/a&gt; to my Ruby brethren at RubyConf.&lt;/li&gt;
&lt;li&gt;"Write functional Clojure and get shit done." At &lt;a href="http://qconsf.com/sf2009/conference/"&gt;QCon&lt;/a&gt;, I will give an &lt;a href="http://qconsf.com/sf2009/presentation/Clojure+in+the+Field"&gt;experience report&lt;/a&gt; on Clojure in commercial development. Our results so far: green across the board. Both Relevance and our clients have been pleased with Clojure.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Want to learn about all four of these ideas, and more? Early in 2010, I will be co-teaching the &lt;a href="https://pragmaticstudio.com/clojure"&gt;Pragmatic Studio: Clojure&lt;/a&gt; with some fellow named Rich Hickey.&lt;/p&gt;

&lt;p&gt;If you can't make it to any of the events listed above, at least you can follow along with the slides and code. All of my Clojure slides are Creative-Commons licensed, and you can follow their development &lt;a href="http://github.com/stuarthalloway"&gt;on Github&lt;/a&gt;. Likewise, all the sample code is released under open-source licenses, including&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the &lt;a href="http://github.com/stuarthalloway/programming-clojure"&gt;sample code&lt;/a&gt; for &lt;a href="http://www.pragprog.com/titles/shcloj/programming-clojure"&gt;Programming Clojure&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;a port of &lt;a href="http://github.com/stuarthalloway/practical-cl-clojure"&gt;examples&lt;/a&gt; from &lt;a href="http://gigamonkeys.com/book/"&gt;Practical Common Lisp&lt;/a&gt; to Clojure&lt;/li&gt;
&lt;li&gt;&lt;a href="http://github.com/stuarthalloway/clj-relevance"&gt;various examples&lt;/a&gt; from the blog&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And remember: think globally, but act only through the unified update model.&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/relevance-llc/~4/DTihSCfvWwg" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://blog.thinkrelevance.com/2009/10/19/the-case-for-clojure</feedburner:origLink></entry>
  <entry xml:base="http://blog.thinkrelevance.com/">
    <author>
      <name>stu</name>
    </author>
    <id>tag:blog.thinkrelevance.com,2009-10-07:11458</id>
    <published>2009-10-07T10:59:00Z</published>
    <updated>2009-10-25T23:41:50Z</updated>
    <category term="Clojure" />
    <category term="clojure" />
    <link href="http://feedproxy.google.com/~r/relevance-llc/~3/NSH6gt_ce6E/brians-functional-brain-take-1-5" rel="alternate" type="text/html" />
    <title>Brian's Functional Brain, Take 1.5</title>
<content type="html">
            &lt;p&gt;Last week, Lau wrote two excellent sample apps (and &lt;a href="http://blog.bestinclass.dk/index.php/2009/10/brians-functional-brain/"&gt;blog&lt;/a&gt; &lt;a href="http://blog.bestinclass.dk/index.php/2009/10/brians-transient-brain/"&gt;posts&lt;/a&gt;) demonstrating Brian's Brain in Clojure. Continuing with the first version of that example, I am going to demonstrate&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;using different data structures&lt;/li&gt;
&lt;li&gt;visual unit tests&lt;/li&gt;
&lt;li&gt;JMX integration (gratuitous!)&lt;/li&gt;
&lt;li&gt;an approach to Clojure source code organization&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Make sure you read through Lau's &lt;a href="http://blog.bestinclass.dk/index.php/2009/10/brians-functional-brain/"&gt;original post&lt;/a&gt; first, and understand the code there.&lt;/p&gt;

&lt;h2&gt;Data Structures&lt;/h2&gt;

&lt;p&gt;In a functional language like Clojure, it is easy to experiment with using different structures to represent the same data. Rather than being hidden in a rat's nest of mutable object relationships, your data is right in front of you in simple persistent data structures. In Lau's implementation, the board is represented by a list of lists, like so:&lt;/p&gt;

&lt;pre&gt;&lt;code class="clojure"&gt;(([:on 0 0] [:off 0 1] [:on 0 2]) 
 ([:on 1 0] [:on 1 1] [:off 1 2]))
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Each cell in the list knows its state (&lt;code&gt;:on&lt;/code&gt;, &lt;code&gt;:off&lt;/code&gt;, or &lt;code&gt;:dying&lt;/code&gt;), and its x and y coordinates on the board. The board data structure is used for two purposes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the &lt;code&gt;step&lt;/code&gt; function applies the rules of the automaton, returning the board's next state&lt;/li&gt;
&lt;li&gt;the &lt;code&gt;render&lt;/code&gt; function draws the board on a Swing panel&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These two functions have slightly different needs: the &lt;code&gt;step&lt;/code&gt; function cares only about the state of adjacent cells, and can ignore the coordinates, while the &lt;code&gt;render&lt;/code&gt; function needs both.&lt;/p&gt;

&lt;p&gt;How hard would it be to convert the data to a form that stores only the state? Not hard at all:&lt;/p&gt;

&lt;pre&gt;&lt;code class="clojure"&gt;(defn without-coords [board]
  (for [row board]
    (for [[state] row] state)))
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You could write &lt;code&gt;without-coords&lt;/code&gt; as a one-liner using &lt;code&gt;map&lt;/code&gt;, but I prefer how the nested &lt;code&gt;for&lt;/code&gt;s visually call out the fact that you are manipulating two dimentional data.&lt;/p&gt;

&lt;p&gt;Without the coords, the board is easier to read:&lt;/p&gt;

&lt;pre&gt;&lt;code class="clojure"&gt;((:on :off :on)) 
 (:on :on :off))
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you choose to store the board this way, you will need to get the coordinates back for rendering. That's easy too, again using nested &lt;code&gt;for&lt;/code&gt;s to demonstrate that you are transforming two-dimensional data:&lt;/p&gt;

&lt;pre&gt;&lt;code class="clojure"&gt;(defn with-coords [board]
  (for [[row-idx row] (indexed board)]
    (for [[col-idx val] (indexed row)]
         [val row-idx col-idx])))
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So, with a couple of tiny functions, you can easily convert between two different representations of the data. Why not use both formats, picking the right one for each function's needs?&lt;/p&gt;

&lt;p&gt;When performance is critical, there is another advantage to using different data formats: caching. Consider the &lt;code&gt;step&lt;/code&gt; funtion, which uses the &lt;code&gt;rules&lt;/code&gt; function to determine the next value of each cell:&lt;/p&gt;

&lt;pre&gt;&lt;code class="clojure"&gt;(defn rules
  [above [_ cell _ :as row] below]
  (cond
   (= :on    cell)                              :dying
   (= :dying cell)                              :off  
   (= 2 (active-neighbors above row below))     :on   
   :else                                        :off  ))
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The "without coordinates" format used by &lt;code&gt;step&lt;/code&gt; and &lt;code&gt;rules&lt;/code&gt; passes only exactly the data needed. As a result, the universe of legal inputs to &lt;code&gt;rules&lt;/code&gt; is small enough to fit in a small cache in memory. And in-memory caching is trivial in Clojure, simply call &lt;code&gt;memoize&lt;/code&gt; on a function. (It turns out that for this particular example, the calculation is simple enough that &lt;code&gt;memoize&lt;/code&gt; won't buy you anything. Lau's &lt;a href="http://blog.bestinclass.dk/index.php/2009/10/brians-transient-brain/"&gt;second post&lt;/a&gt; demonstrates more useful optimizations: transients and double-buffering. But in some problems a cacheable funtion result is a performance lifesaver.)&lt;/p&gt;

&lt;p&gt;If you use comprehensions such as Clojure's &lt;code&gt;for&lt;/code&gt; to convert inputs to exactly the data a function needs, your functions will be simpler to read and write. This "caller makes right" approach is not always appropriate. When it is appropriate, it is far less tedious to implement than the related adapter pattern from OO programming.&lt;/p&gt;

&lt;p&gt;Since multiple data formats are so easy, you can use yet another format for testing.&lt;/p&gt;

&lt;h2&gt;Testing&lt;/h2&gt;

&lt;p&gt;Brian's Brain is a simulation in two dimensions, it would be nice to write tests with a literal, visual, 2-d representation. In other words:&lt;/p&gt;

&lt;pre&gt;&lt;code class="clojure"&gt;; this sucks
(is (= :on (rules (cell-with-two-active-neighbors))))

; this rocks
O..
...  =&gt; O     
..O
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In the literal form above the &lt;code&gt;O&lt;/code&gt; is an &lt;code&gt;:on&lt;/code&gt; cell, and the &lt;code&gt;.&lt;/code&gt; is an &lt;code&gt;:off&lt;/code&gt; cell.&lt;/p&gt;

&lt;p&gt;Creating this representation is easy. The &lt;code&gt;board-&amp;gt;str&lt;/code&gt; function converts a board to a compact string form:&lt;/p&gt;

&lt;pre&gt;&lt;code class="clojure"&gt;(defn board-&gt;str
  "Convert from board form to string form:

   O.O         [[ :on     :off  :on    ]
   |.|     ==   [ :dying  :off  :dying ]
   O.O          [ :on     :off  :on    ]]
"
  [board]
  (str-join "\n" (map (partial str-join "") (board-&gt;chars board))))
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;board-&amp;gt;chars&lt;/code&gt; helper is equally simple:&lt;/p&gt;

&lt;pre&gt;&lt;code class="clojure"&gt;(def state-&gt;char {:on \O, :dying \|, :off \.})
(defn board-&gt;chars
  [board]
  (map (partial map state-&gt;char) board))
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;With the new stringified board format, you can trivially write tests like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class="clojure"&gt;(deftest test-rules
  (are [result boardstr] (= result (apply rules (str-&gt;board boardstr)))
       :dying  "...
                .O.
                ..."

       :off    "O.O
                ...
                O.O"

       :on     "|||
                O.O
                |||"))
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;are&lt;/code&gt; macro makes it simple to run the same tests over multiple inputs, and with liberal use of whitespace the tests line up visually. It isn't perfect, but I think it is good enough.&lt;/p&gt;

&lt;p&gt;One last note: the string format used in tests is basically ASCII art, so you can have a console based GUI almost for free:&lt;/p&gt;

&lt;pre&gt;&lt;code class="clojure"&gt;(defn launch-console []
  (doseq [board (iterate step (new-board))]
    (println (board-&gt;str board))))
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;JMX Integration&lt;/h2&gt;

&lt;p&gt;Ok, JMX integration is gratuitous for an example like this. But clojure.contrib.jmx is so easy to use I couldn't resist. You can store the total number of iterations perfomed in a thread-safe Clojure atom:&lt;/p&gt;

&lt;pre&gt;&lt;code class="clojure"&gt;(def status (atom {:iterations 0}))
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then, just expose the atom as a JMX mbean. &lt;/p&gt;

&lt;pre&gt;&lt;code class="clojure"&gt;(defn register-status-mbean []
  (jmx/register-mbean (Bean. status) "lau.brians-brain:name=Automaton"))
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Yes, it is that easy. Create any Clojure reference type, point it at a map, and register a bean. You can now access the iteration counter from a JMX client such as the jconsole application that ships with the JDK.&lt;/p&gt;

&lt;p&gt;To make the mbean report real data, wrap the automaton's iterations in an &lt;code&gt;update-stage&lt;/code&gt; helper function that both does the work, and updates the counter.&lt;/p&gt;

&lt;pre&gt;&lt;code class="clojure"&gt;(defn update-stage
  "Update the automaton (and associated metrics)."
  [stage]
  (swap! stage step)
  (swap! status update-in [:iterations] inc))
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you haven't seen &lt;code&gt;update-in&lt;/code&gt; (and its cousins &lt;code&gt;get-in&lt;/code&gt; and &lt;code&gt;assoc-in&lt;/code&gt;) before, go and study them for a moment now. They make working with non-trivial data structures a joy.&lt;/p&gt;

&lt;p&gt;You might disagree with my choice of atoms. With a pair of references, you could keep the iteration count exactly coordinated with the simulator. Or, with a reference plus an agent you push the work of updating the iteration count out of the main loop. Whatever you choose, Clojure makes it easy to both (a) implement state and (b) keep the statefulness separate from the bulk of your code. &lt;/p&gt;

&lt;h2&gt;Source Code Organization&lt;/h2&gt;

&lt;p&gt;Lau's original code weighed in at a trim 67 lines. Now that the app supports three different data formats, a console UI, and JMX integration, it is up to around 150 lines. How should we organize such a monster of an app?  Two obvious choices are: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;put everything in one file and one namespace&lt;/li&gt;
&lt;li&gt;split out namespaces by functional area, e.g. automaton, swing gui, and console gui&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I don't love either approach. The single file approach is confusing for the reader, because there are multiple different things going on. The multiple namespace approach is a pain for callers, because they get weighed down under a bunch of namespaces to do a single thing. &lt;/p&gt;

&lt;p&gt;A third option is &lt;code&gt;immigrate&lt;/code&gt;. With &lt;code&gt;immigrate&lt;/code&gt; you can organize your code into multiple namespaces for the benefit of readers, and then immigrate them all into a blanket namespace for casual users of the API. But immigrate may be &lt;a href="http://groups.google.com/group/compojure/browse_thread/thread/400aac94e536e633#"&gt;too cute&lt;/a&gt; for their own good.&lt;/p&gt;

&lt;p&gt;Instead, I chose to use one namespace for the convenience of callers, and mutilple files to provide sub-namespace organization for readers of code. I mimiced the structure &lt;a href="http://github.com/tomfaulhaber"&gt;Tom Faulhaber&lt;/a&gt; used in clojure-contrib's pprint library: a top level file that calls &lt;code&gt;load&lt;/code&gt; on several files in a subdirectory of the same name (minus the .clj extension):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;lau/brians_brain.clj  
lau/brians_brain/automaton.clj
lau/brians_brain/board.clj
lau/brians_brain/console_gui.clj
lau/brians_brain/swing_gui.clj
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I also used this layout for clojure-contrib's JMX library.&lt;/p&gt;

&lt;h2&gt;Parting Shots&lt;/h2&gt;

&lt;p&gt;Over the course of Lau's two exampples and this one, you have seen:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;an initial working application in under 100 lines of code&lt;/li&gt;
&lt;li&gt;transforming data structures for performance optimization&lt;/li&gt;
&lt;li&gt;transforming data structures for readability&lt;/li&gt;
&lt;li&gt;a second (console) gui&lt;/li&gt;
&lt;li&gt;optimizing the Swing gui with double buffering&lt;/li&gt;
&lt;li&gt;optimizing with transients&lt;/li&gt;
&lt;li&gt;visual tests&lt;/li&gt;
&lt;li&gt;easy addition of monitoring with JMX&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And here are some things you haven't seen:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;classes&lt;/li&gt;
&lt;li&gt;interfaces&lt;/li&gt;
&lt;li&gt;uncontrolled mutation&lt;/li&gt;
&lt;li&gt;broken concurrency&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Would it be possible to write a threadsafe Brian's Brain using mutable OO? Of course. Is there a benefit to doing so? I would love to hear your thoughts on the subject, especially in the form of code.&lt;/p&gt;

&lt;h2&gt;Further Reading&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blog.bestinclass.dk/index.php/2009/10/brians-functional-brain/"&gt;Brians functional brain&lt;/a&gt; (Lau's original post)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.bestinclass.dk/index.php/2009/10/brians-transient-brain/"&gt;Brians Transient! Brain&lt;/a&gt; (Lau's followup)&lt;/li&gt;
&lt;li&gt;The &lt;a href="http://github.com/stuarthalloway/clj-relevance"&gt;clj-relevance&lt;/a&gt; repos has the completed code from this blog post at &lt;code&gt;src/lau/brians_brain&lt;/code&gt;, and will be the home for future Clojure examples on this blog&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.pragprog.com/titles/shcloj/programming-clojure"&gt;Programming Clojure&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
          &lt;img src="http://feeds.feedburner.com/~r/relevance-llc/~4/NSH6gt_ce6E" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://blog.thinkrelevance.com/2009/10/7/brians-functional-brain-take-1-5</feedburner:origLink></entry>
  <entry xml:base="http://blog.thinkrelevance.com/">
    <author>
      <name>stu</name>
    </author>
    <id>tag:blog.thinkrelevance.com,2009-10-06:11452</id>
    <published>2009-10-06T12:44:00Z</published>
    <updated>2009-10-16T14:40:00Z</updated>
    <category term="nfjs" />
    <category term="retrospective" />
    <link href="http://feedproxy.google.com/~r/relevance-llc/~3/uuz4bwLqm70/nfjs-the-retro-twin-cities-edition" rel="alternate" type="text/html" />
    <title>NFJS, the Retro (Twin Cities Edition)</title>
<content type="html">
            &lt;p&gt;We had a terrific conference retrospective this weekend at the &lt;a href="http://www.nofluffjuststuff.com/conference/minneapolis/2009/10/home"&gt;Twin Cities NFJS show&lt;/a&gt;. Eight people participated, with me facilitating. The conversation was good, and everyone left excited to implement the SMART goals that we chose.&lt;/p&gt;

&lt;p&gt;As usual, we followed the basic structure from the &lt;a href="http://www.pragprog.com/titles/dlret/agile-retrospectives"&gt;Agile Retrospectives Book&lt;/a&gt;: Setting the Stage, Gathering Information, Generating Insights, Deciding What To Do, and Closing.&lt;/p&gt;

&lt;h2&gt;Setting the Stage&lt;/h2&gt;

&lt;p&gt;The NFJS conference retro is an odd beast: a sixty-minute retro embedded in a &lt;a href="http://blog.thinkrelevance.com/2009/3/25/agile-retrospectives"&gt;ninety-minute talk&lt;/a&gt; about using retros in your own organization. This poses a few special challenges: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The team needs to have a working agreement to occasionally "go meta" and talk about the mechanics of the retro &lt;em&gt;during&lt;/em&gt; the retro. This risks reducing the value of the retro, but so far attendees have found it effective.&lt;/li&gt;
&lt;li&gt;The team isn't really a team: it is a subset of the conference attendees thrown together for the first time to do the retro. So, the facilitator has to choose the activities in real time to match the size and composition of the group.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sticking to the time box, we covered these ground rules in the first five minutes.&lt;/p&gt;

&lt;h2&gt;Gathering Information&lt;/h2&gt;

&lt;p&gt;To gather information, we used the team radar activity from the book. A few minutes of brainstorming identified about ten possible items to rate. That is too many to actually rate, so we used dot voting to narrow down to four items. Each participant used a Sharpie to make three dots next to the items they considered most important. As usual, the moving about the room helped people get engaged physically and mentally.&lt;/p&gt;

&lt;p&gt;The items and their individual rating (1=worst, 10=best) follow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;meaningful content: 8, 7, 8, 7, 7, 7, 7&lt;/li&gt;
&lt;li&gt;speaker quality: 9, 8, 8, 8, 8, 8, 9&lt;/li&gt;
&lt;li&gt;track organization/session selection: 7, 8, 6, 6, 6, 6, 5&lt;/li&gt;
&lt;li&gt;price/value: 8, 7, 6, 6, 8, 7, 6, 8&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These numbers are quite high; overall possibly the highest I have seen at a conference retro. Also, the lowest scores were on track organization. When selecting talks for a conference it is almost impossible to please everyone, so while the scores were lower I was not optimistic about finding a useful recommendation. (Note that as the facilitator I kept these musings strictly to myself during the retro!)&lt;/p&gt;

&lt;h2&gt;Generating Insights&lt;/h2&gt;

&lt;p&gt;To generate insights we used the learning matrix. This exercise uses four quadrants (happy/sad/ideas/appreciation) to guide brainstorming. In the interest of space I will not reproduce the matrix results here: the information would be meaningless without pages of explanatory text.&lt;/p&gt;

&lt;p&gt;Unusually, the "ideas" section filled up first. In fact, to hit the time box we didn't even manage to fill the other quadrants.&lt;/p&gt;

&lt;h2&gt;Deciding What To Do&lt;/h2&gt;

&lt;p&gt;To keep to our sixty-minuted time box, we agreed to dot vote for two items on the ideas list, and convert them to SMART goals. A SMART goal nees to be &lt;em&gt;S&lt;/em&gt;pecific, &lt;em&gt;M&lt;/em&gt;easurable, &lt;em&gt;A&lt;/em&gt;chievable, &lt;em&gt;R&lt;/em&gt;elevant, and &lt;em&gt;T&lt;/em&gt;imely.&lt;/p&gt;

&lt;p&gt;We ended up selecting these goals:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;By February 2010, update the website and printed materials to include a single-line of text describing the "recommended audience." Free text might seem dumb compared to some kind of tagging, and it is delibarately so. We started to discuss a system of categories and realized that this would make the goal more complex, and therefore less likely to be implemented. Keep it simple.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;By February 2010, run a birds-of-a-feather (BOF) session titled "What To Do on Monday!" Everyone agreed that the conference talks were inspiring, and included ideas that could create massive improvements back at the day job. But massive improvements are often beyond the immediate control of conference attendees, and it is frustrating to go back to work on Monday and not be able to start a new practice. The BOF will allow attendees and speakers to look across all the conference topics and generate a list of bite-sized ideas. If the BOF goes well, we will use it to generate an outline for a formal talk.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;February 2010 might seem like a long way off, but since the retro was a breakout team that did not include the people who would actually have to implement the recommendations, it seemed wise to allow the work to be done during the winter off-season for the NFJS tour.&lt;/p&gt;

&lt;h2&gt;Closing&lt;/h2&gt;

&lt;p&gt;To close the retro, we did a quick thumbs up/down/sideways check to see if the participants found the retro useful. Votes were seven up, one sideways.&lt;/p&gt;

&lt;p&gt;All in all, a good sixty minutes. I am excited about implementing the new ideas, and I think that the regular recurring nature of NFJS provides a great opportunity to close the feedback loop faster than at a conference that runs less frequently.&lt;/p&gt;

&lt;h2&gt;Recommended Reading&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.pragprog.com/titles/dlret/agile-retrospectives"&gt;Agile Retrospectives&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.thinkrelevance.com/2009/7/7/relevance-agile-bibliography"&gt;Relevance Agile Bibliography&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://howwework.thinkrelevance.com/"&gt;How We Work&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
          &lt;img src="http://feeds.feedburner.com/~r/relevance-llc/~4/uuz4bwLqm70" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://blog.thinkrelevance.com/2009/10/6/nfjs-the-retro-twin-cities-edition</feedburner:origLink></entry>
  <entry xml:base="http://blog.thinkrelevance.com/">
    <author>
      <name>glenn</name>
    </author>
    <id>tag:blog.thinkrelevance.com,2009-09-30:11429</id>
    <published>2009-09-30T11:55:00Z</published>
    <updated>2009-09-30T11:55:50Z</updated>
    <category term="gems" />
    <category term="list of n things" />
    <category term="plugins" />
    <category term="rails" />
    <category term="ruby" />
    <link href="http://feedproxy.google.com/~r/relevance-llc/~3/mVpbdbA_GYQ/10-must-have-rails-plugins-and-gems-2009-edition" rel="alternate" type="text/html" />
    <title>10 Must-Have Rails Plugins and Gems (2009 Edition)</title>
<content type="html">
            &lt;p&gt;When Paul Graham wrote that the “list of n things” is a
&lt;a href="http://www.paulgraham.com/nthings.html"&gt;degenerate case of the essay&lt;/a&gt;, our first thought was
“Wow!  That’s for us!”
And we’re going one step farther: we’re recycling an old “list of n things” essay from last year.&lt;/p&gt;

&lt;p&gt;Seriously, we’ve been thinking of revisiting &lt;a href="http://blog.thinkrelevance.com/2008/6/16/10-must-have-rails-plugins"&gt;10 must-have Rails plugins&lt;/a&gt; for a while now.
There is a place for lists like that, and the Rails plugin and add-on space has been moving quickly.
We are always looking for better ways to do things, so we try out a lot of the plugins that come along.
Our list of favorites—the ones that we use on almost every project—is almost completely different than last year’s model.&lt;/p&gt;

&lt;p&gt;There’s one important change in focus:
the plugins and gems that are solely related to testing are gone from this list.
Of course, that doesn’t mean we’re down on testing.
On the contrary, we built &lt;a href="http://runcoderun.com/"&gt;RunCodeRun&lt;/a&gt; because we think testing is so vital.
We’re saving the testing tools for the &lt;a href="http://blog.runcoderun.com/"&gt;RunCodeRun blog&lt;/a&gt;; we’ll be writing another degenerate essay there as a counterpart to this one.&lt;/p&gt;

&lt;p&gt;There are numerous other plugins we use for special needs, such as PDF generation or attachment handling.
But our favorites are the ones that we use on almost every project.
So here they are, along with brief comments explaining why you want to check them out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://github.com/josevalim/inherited_resources"&gt;Inherited Resources&lt;/a&gt;: eliminates most of the boilerplate code from our controllers.
(The new &lt;a href="http://ryandaigle.com/articles/2009/8/10/what-s-new-in-edge-rails-default-restful-rendering"&gt;controller responder&lt;/a&gt; feature in Rails 3 is similar in intent.)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://github.com/justinfrench/formtastic"&gt;Formtastic&lt;/a&gt;: takes most of the pain out of writing the markup for HTML forms.
(Together, Inherited Resources and Formtastic make a nice alternative to scaffolding frameworks like Streamlined and &lt;a href="http://activescaffold.com/"&gt;ActiveScaffold&lt;/a&gt;.)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://github.com/relevance/cap_gun"&gt;CapGun&lt;/a&gt;: provides easy build notifications (see &lt;a href="http://blog.thinkrelevance.com/2009/9/16/easy-build-notifications-with-capgun"&gt;this previous post&lt;/a&gt; for more info).&lt;/li&gt;
&lt;li&gt;&lt;a href="http://faker.rubyforge.org/"&gt;Faker&lt;/a&gt;: helps us generate fake data.
We use it for testing, but mostly for providing demo data for development and staging environments.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.thoughtbot.com/projects/clearance"&gt;Clearance&lt;/a&gt;: feature-rich authentication and signup.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://github.com/abedra/safe-erb"&gt;Safe ERB&lt;/a&gt;: helps ensure that our apps are not vulnerable to cross-site scripting attacks.
(We look forward to similar functionality being baked into Rails 3.)&lt;/li&gt;
&lt;li&gt;RedHill on Rails Core: we use this primarily to declare foreign key references in our database schemas.
Telling the database about table relationships adds a small cost to our projects, but we’ve found that the benefits outweigh that cost.
(It’s unclear where this plugin lives at the moment, but there are numerous forks of it on &lt;a href="http://github.com/"&gt;GitHub&lt;/a&gt;.)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://newrelic.com/get-RPM.html"&gt;RPM&lt;/a&gt;: Rails Performance Management from &lt;a href="http://newrelic.com/"&gt;New Relic&lt;/a&gt;;
wonderful for discovering and diagnosing performance problems.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://github.com/mislav/will_paginate"&gt;will_paginate&lt;/a&gt;: the nicest, easiest pagination plugin we’ve seen.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.hoptoadapp.com/"&gt;hoptoad&lt;/a&gt;: great, customer-friendly notifications about exceptions that happen in the app.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Don’t reinvent the wheel!
Use these plugins (or others like them), and definitely consider contributing to them if they fall short of what you need!&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/relevance-llc/~4/mVpbdbA_GYQ" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://blog.thinkrelevance.com/2009/9/30/10-must-have-rails-plugins-and-gems-2009-edition</feedburner:origLink></entry>
  <entry xml:base="http://blog.thinkrelevance.com/">
    <author>
      <name>glenn</name>
    </author>
    <id>tag:blog.thinkrelevance.com,2009-09-23:11411</id>
    <published>2009-09-23T12:15:00Z</published>
    <updated>2009-09-23T12:15:50Z</updated>
    <category term="gems" />
    <category term="logging" />
    <category term="rails" />
    <category term="ruby" />
    <link href="http://feedproxy.google.com/~r/relevance-llc/~3/NAIGBwmGO9o/quick-and-easy-logging-with-logbuddy" rel="alternate" type="text/html" />
    <title>Quick and Easy Logging with LogBuddy</title>
<content type="html">
            &lt;p&gt;Good logging is crucial for effective problem diagnosis in production.
Plus, easy logging remains a terrific debugging technique during development.
As helpful as “real debuggers” are, sometimes a debugging log statement is exactly what you need to find a problem quickly.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://github.com/relevance/log_buddy"&gt;LogBuddy&lt;/a&gt; is a little gem that makes good logging easier.
It helps even in Rails, which already has good logging support,
and it’s a bigger help when building gems and standalone Ruby apps, 
where you have to start from scratch with logging.&lt;/p&gt;

&lt;p&gt;What does LogBuddy do for you that Rails doesn’t already?
There are numerous small features, but here are the big ones:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It ensures that &lt;code&gt;logger&lt;/code&gt; is available &lt;em&gt;everywhere&lt;/em&gt;, not just in classes that extend parts of the framework.&lt;/li&gt;
&lt;li&gt;It makes it &lt;em&gt;extremely&lt;/em&gt; easy to add informative debugging messages with annotated output and full exception info.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;Installing and Adding LogBuddy to Your Project&lt;/h2&gt;

&lt;p&gt;To install the latest release of LogBuddy, just install the gem:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ gem install relevance-log_buddy --source http://gems.github.com/
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then add a &lt;code&gt;require 'log_buddy'&lt;/code&gt; statement to your app.
If it’s a Rails app, it’s best to add this to &lt;code&gt;environment.rb&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;config.gem 'relevance-log_buddy',
           :source =&amp;gt; "http://gems.github.com/", 
           :lib =&amp;gt; "log_buddy"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Finally, initialize LogBuddy.
In Rails apps, we usually put this in &lt;code&gt;config/initializers/logging.rb&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;LogBuddy.init
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;(You can pass some options to &lt;code&gt;LogBuddy.init&lt;/code&gt;; we’ll get back to that in a bit.)&lt;/p&gt;

&lt;p&gt;LogBuddy creates and initializes a logger for the app to use.
In Rails apps, it simply uses &lt;code&gt;RAILS_DEFAULT_LOGGER&lt;/code&gt; unless you tell it differently.&lt;/p&gt;

&lt;h2&gt;Using LogBuddy&lt;/h2&gt;

&lt;p&gt;LogBuddy mixes a couple of methods into every object in the system: &lt;code&gt;logger&lt;/code&gt; and &lt;code&gt;d&lt;/code&gt;.
Here’s how they work.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;logger&lt;/code&gt; method is no surprise at all.
It simply returns the Logger instance, and you can log by calling &lt;code&gt;debug&lt;/code&gt;, &lt;code&gt;info&lt;/code&gt;, &lt;code&gt;warn&lt;/code&gt;, &lt;code&gt;error&lt;/code&gt;, or &lt;code&gt;log&lt;/code&gt; methods on it.
LogBuddy’s logger doesn’t usually do anything special;
the benefit is that, since it’s mixed into Object, it’s available everywhere,
automatically.
(In a typical Rails app, there are numerous contexts where &lt;code&gt;logger&lt;/code&gt; doesn’t work, and you have to explicitly use &lt;code&gt;RAILS_DEFAULT_LOGGER&lt;/code&gt;.)&lt;/p&gt;

&lt;p&gt;My personal favorite LogBuddy feature is the &lt;code&gt;d&lt;/code&gt; method.
Like &lt;code&gt;logger&lt;/code&gt;, it’s available everywhere.
But the &lt;code&gt;d&lt;/code&gt; method is designed just for debugging messages.
You can call it with an explicit string, or with some object you want to see the value of:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;d "FINISHED PARSING"
d some_exception
d result
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Strings are logged the same way &lt;code&gt;logger.debug&lt;/code&gt; would do it.
Exceptions are logged with all of the information you might want:
the message, exception class name, and backtrace.
Finally, if you pass any other object, &lt;code&gt;d&lt;/code&gt; calls that object’s &lt;code&gt;inspect&lt;/code&gt; method and logs the resulting string.&lt;/p&gt;

&lt;p&gt;Where &lt;code&gt;d&lt;/code&gt; really shines is when you want to log several values at once, with annotations to distinguish them.
Just pass a single-line block to &lt;code&gt;d&lt;/code&gt;, like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;d { first; current; last}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That produces these three log lines:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;first = "foo"
current = "bar"
last = "baz"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The values you log can be any Ruby expression:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;d { 3; name; @model; RAILS_ENV; options[:limit] }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and you’ll get just what you want out of that:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;3 = "3"
name = "primary"
@model = #&amp;lt;Contact id: 14, name: "Joe"&amp;gt;
RAILS_ENV = "development"
options[:limit] = 5
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There are some restrictions if you use this feature.
The entire call to &lt;code&gt;d&lt;/code&gt; must fit on one line, and you must use the curly-brace style of block, rather than the do/end style.
Finally, if you want to log multiple values, separate them with semicolons, not commas.&lt;/p&gt;

&lt;p&gt;(You may be wondering how LogBuddy accomplishes that trick.
The answer is left as an exercise for the reader … especially since there are some hints in the restrictions just mentioned.
Of course, you can always read the source.)&lt;/p&gt;

&lt;h2&gt;LogBuddy Initialization Options&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;LogBuddy.init&lt;/code&gt; method takes an options hash.
Here are the permissible options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;:logger&lt;/code&gt; – you can supply a logger instance for LogBuddy to use.  If you don’t supply one, LogBuddy uses &lt;code&gt;RAILS_DEFAULT_LOGGER&lt;/code&gt; if it’s defined; otherwise, it creates a new logger that writes to standard output.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;:log_to_stdout&lt;/code&gt; – by default, messages from the &lt;code&gt;d&lt;/code&gt; method are logged (using &lt;code&gt;logger.debug&lt;/code&gt;) and also written to standard output.  Set this option to &lt;code&gt;false&lt;/code&gt; to only use the logger.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;:disabled&lt;/code&gt; – set this option to &lt;code&gt;true&lt;/code&gt; to turn off the output from the &lt;code&gt;d&lt;/code&gt; method.  It’s common to set it this way:&lt;br /&gt;
&lt;code&gt;LogBuddy.init :disabled =&amp;gt; Rails.env.production?&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;:log_gems&lt;/code&gt; – if you set this option to &lt;code&gt;true&lt;/code&gt;, LogBuddy watches gem activation and logs information about each gem.  This can be useful for tracking down gem activation errors&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Try It Out!&lt;/h2&gt;

&lt;p&gt;LogBuddy is really easy to set up, and then it’s there when you need it most: when you’re focused on a problem and just need to get the details quickly.
Please try it and let us know what you think!&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/relevance-llc/~4/NAIGBwmGO9o" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://blog.thinkrelevance.com/2009/9/23/quick-and-easy-logging-with-logbuddy</feedburner:origLink></entry>
  <entry xml:base="http://blog.thinkrelevance.com/">
    <author>
      <name>glenn</name>
    </author>
    <id>tag:blog.thinkrelevance.com,2009-09-16:11381</id>
    <published>2009-09-16T12:14:00Z</published>
    <updated>2009-10-16T14:40:20Z</updated>
    <category term="capistrano" />
    <category term="deployment" />
    <category term="rails" />
    <category term="ruby" />
    <link href="http://feedproxy.google.com/~r/relevance-llc/~3/_SGNFt6uTJ4/easy-build-notifications-with-capgun" rel="alternate" type="text/html" />
    <title>Easy Build Notifications with CapGun</title>
<content type="html">
            &lt;p&gt;Most of us get notified about lots of little events on our projects:
Commits, build failures (and fixed builds), and runtime exceptions, for example.
But deployment is where the rubber meets the road on web development projects.
Deployment to staging means new functionality to try out and test,
and of course deployment to production is even more important.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://github.com/relevance/cap_gun"&gt;CapGun&lt;/a&gt; is a gem we use to send email notifications whenever we deploy one of our projects.
It works with &lt;a href="http://www.capify.org/"&gt;Capistrano&lt;/a&gt; and uses ActionMailer to let every interested party know when a deployment happens.&lt;/p&gt;

&lt;p&gt;Here’s how to work with CapGun in a Rails project.
Add this to &lt;code&gt;config/environment.rb&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;config.gem 'relevance-cap_gun', 
           :source =&amp;gt; "http://gems.github.com/", 
           :lib =&amp;gt; "cap_gun"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then install and unpack the gem:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ rake gems:install
$ rake gems:unpack
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Finally, edit your deployment script (usually &lt;code&gt;config/deploy.rb&lt;/code&gt;) and add this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require File.join(RAILS_ROOT,
                  Dir["vendor/gems/relevance-cap_gun-*/lib"].last,
                  'cap_gun')

set :cap_gun_action_mailer_config, {
  :address =&amp;gt; "smtp.gmail.com",
  :port =&amp;gt; 587,
  :user_name =&amp;gt; "grey-goo@example.com", # deploy bot email address
  :password =&amp;gt; "outtacontrol",  # deploy bot email password
  :authentication =&amp;gt; :plain 
}

set :cap_gun_email_envelope, {
  :recipients =&amp;gt; %w[fooproj-devs@example.com fooproj-mgr@example.com], 
  :from =&amp;gt; "Foo Project Deployment Bot &amp;lt;grey-goo@example.com&amp;gt;"
}

after "deploy:restart", "cap_gun:email"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We usually use &lt;a href="http://gmail.com/"&gt;GMail&lt;/a&gt; as our MTA for this purpose, and CapGun includes support for secure, authenticated email connections so that you can do the same.
It’s best to create a special-purpose, throwaway email account just for things like this;
that way there’s little risk in putting the email password in the project deployment script.
(But there’s also nothing stopping you from reading it from another file that’s not checked into source control, just like you would do with your production database passwords.
The &lt;code&gt;deploy.rb&lt;/code&gt; file is just Ruby code, after all.
And if the source is going to be in a public repository, you should definitely do that.)&lt;/p&gt;

&lt;p&gt;The deployment email has a brief summary at the top
(in fact, the subject often tells you all you need to know).
But there are useful details in the body.
Here’s an example of what you might see from the configuration above:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;From: Foo Project Deployment Bot &amp;lt;grey-goo@example.com&amp;gt;
To: fooproj-devs@example.com, fooproj-mgr@example.com
Date: Tue, 15 Sep 2009 17:27:57 -0400
Subject: [DEPLOY] fooproj deployed to production

fooproj was deployed to production by george at September 15th, 2009 5:27 PM EDT.

Nerd details
============
Release: /var/apps/fooproj/releases/20090915212721
Release Time: September 15th, 2009 5:27 PM EDT
Release Revision: 69246739f2a1cbcef5ca76f1842c21849db7778a

Previous Release: /var/apps/fooproj/releases/20090915194707
Previous Release Time: September 15th, 2009 3:47 PM EDT
Previous Release Revision: 9ceb19b1777470d1d5133f433fdd5d1873c7a4c0

Repository: git@github.com:foocorp/fooproj.git
Deploy path: /var/apps/fooproj
Domain: fooproj.example.com
Branch: main

Commits since last release
====================
d37a15c:who put a blink tag in here?
f1b603e:Added favicon
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Setting up CapGun only takes a few minutes, and you’ll love the increased visibility into your team’s deployments.
(And even if you’re a team of one, you’ll appreciate having the emails as a record of your deployments.)
Try it out, and &lt;a href="mailto:opensource@thinkrelevance.com?subject=CapGun"&gt;let us know&lt;/a&gt; what you think!&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/relevance-llc/~4/_SGNFt6uTJ4" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://blog.thinkrelevance.com/2009/9/16/easy-build-notifications-with-capgun</feedburner:origLink></entry>
  <entry xml:base="http://blog.thinkrelevance.com/">
    <author>
      <name>glenn</name>
    </author>
    <id>tag:blog.thinkrelevance.com,2009-09-09:11319</id>
    <published>2009-09-09T14:03:00Z</published>
    <updated>2009-10-16T14:40:10Z</updated>
    <category term="i18n" />
    <category term="mvc" />
    <category term="rails" />
    <category term="validations" />
    <link href="http://feedproxy.google.com/~r/relevance-llc/~3/gAVaIIWIPsY/keep-models-out-of-your-views-business-2" rel="alternate" type="text/html" />
    <title>Keep Models out of Your Views' Business! (Part 2)</title>
<content type="html">
            &lt;p&gt;Last week, I wrote about &lt;a href="http://blog.thinkrelevance.com/2009/9/2/keep-models-out-of-your-views-business"&gt;using Rails’ I18N facilities&lt;/a&gt; to break dependencies between your models and views, by changing how model and attribute names are displayed. But there’s another place where the implementation of models sometimes peeks through into views: validation error messages.&lt;/p&gt;

&lt;p&gt;Depending on how you use them, Rails’ error message helpers may insert attribute names into messages, and the changes from last week will take care of that automatically.  But it goes farther than that. Often, validation error messages express things in a way that is not appropriate for end users. The usual solution is to override the default messages with &lt;code&gt;:message =&amp;gt; '...'&lt;/code&gt; options on the validation declarations. But again, that means the model is actively involved in presentation issues, and we’d like to avoid that if possible.&lt;/p&gt;

&lt;p&gt;Whole plugins have been written to try to solve this problem, but Rails internationalization support has made it much easier. When validation error messages have to refer to the name of a model class or attribute, they will use the locale definitions we’ve already supplied. And it turns out that they look in the locale for error message text, too.&lt;/p&gt;

&lt;h2&gt;Overriding Validation Error Messages&lt;/h2&gt;

&lt;p&gt;Last week, we used a typical Rails example: a blogging app with a model called &lt;code&gt;Post&lt;/code&gt; with attributes &lt;code&gt;title&lt;/code&gt; and &lt;code&gt;body&lt;/code&gt;. (And we used I18N to relabel &lt;code&gt;Post&lt;/code&gt; as &lt;code&gt;Article&lt;/code&gt;, and &lt;code&gt;title&lt;/code&gt; as &lt;code&gt;headline&lt;/code&gt;.) Let’s continue with that example, assuming this declaration in &lt;code&gt;Post&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;validates_presence_of :title&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The default error message (with the re-labeling we’ve already done) is “Headline can’t be blank.” How would we change that to something friendlier, like “Headline should not be empty; please supply one”?&lt;/p&gt;

&lt;p&gt;Let’s add a little more to &lt;code&gt;en.yml&lt;/code&gt;—an “errors” section that includes customized validation error messages:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;en:
  activerecord:
    # models and attributes sections carried over from
    # previous article
    models:
      post: &amp;quot;Article&amp;quot;
    attributes:
      post:
        title: &amp;quot;Headline&amp;quot;
    # errors section is new
    errors:
      models:
        post:
          attributes:
            title:
              blank: &amp;quot;should not be empty; please supply one&amp;quot;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We’re now several levels deep in this &lt;a href="http://www.yaml.org/" title="YAML Ain't Markup Language"&gt;YAML&lt;/a&gt; structure, but it should be fairly easy to follow. Under &lt;code&gt;activerecord.errors&lt;/code&gt; there’s a section for &lt;code&gt;models&lt;/code&gt;, within which we find our model (&lt;code&gt;post&lt;/code&gt;). Of its &lt;code&gt;attributes&lt;/code&gt; we’ve supplied a custom error message for the &lt;code&gt;title&lt;/code&gt; attribute; in particular, we’ve customized the &lt;code&gt;blank&lt;/code&gt; message.&lt;/p&gt;

&lt;p&gt;With that change in place, the error messages will read as we’d like them to, with no change to the model or the views.&lt;/p&gt;

&lt;p&gt;Note that we restricted this change to just the &lt;code&gt;title&lt;/code&gt; attribute of &lt;code&gt;Post&lt;/code&gt;. If we wanted to change all “can’t be blank” messages for all attributes of &lt;code&gt;Post&lt;/code&gt;, we could do that as well:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;en:
  activerecord:
    errors:
      models:
        post:
          blank: &amp;quot;should not be empty; please supply one&amp;quot;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Finally, if we wanted to make the change across all the models, here’s how:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;en:
  activerecord:
    messages:
      blank: &amp;quot;should not be empty; please supply one&amp;quot;&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Which Messages Can I Override?&lt;/h2&gt;

&lt;p&gt;You can see the current default messages in the source code for the activerecord gem; just consult the file &lt;code&gt;lib/active_record/locale/en.yml&lt;/code&gt;. But here’s the entire list, mapped to the validation methods that use them. (Some validations use different messages depending on the circumstances.)&lt;/p&gt;

&amp;lt;dl&gt;
&lt;dt&gt;&lt;strong&gt;validates_acceptance_of&lt;/strong&gt;&lt;/dt&gt;

&lt;dd&gt;&lt;code&gt;:accepted&lt;/code&gt; (“must be accepted”)&lt;/dd&gt;

&lt;dt&gt;&lt;strong&gt;validates_associated&lt;/strong&gt;&lt;/dt&gt;

&lt;dd&gt;&lt;code&gt;:invalid&lt;/code&gt; (“is invalid”)&lt;/dd&gt;

&lt;dt&gt;&lt;strong&gt;validates_confirmation_of&lt;/strong&gt;&lt;/dt&gt;

&lt;dd&gt;&lt;code&gt;:confirmation&lt;/code&gt; (“doesn’t match confirmation”)&lt;/dd&gt;

&lt;dt&gt;&lt;strong&gt;validates_exclusion_of&lt;/strong&gt;&lt;/dt&gt;

&lt;dd&gt;&lt;code&gt;:exclusion&lt;/code&gt; (“is reserved”)&lt;/dd&gt;

&lt;dt&gt;&lt;strong&gt;validates_format_of&lt;/strong&gt;&lt;/dt&gt;

&lt;dd&gt;&lt;code&gt;:invalid&lt;/code&gt; (“is invalid”)&lt;/dd&gt;

&lt;dt&gt;&lt;strong&gt;validates_inclusion_of&lt;/strong&gt;&lt;/dt&gt;

&lt;dd&gt;&lt;code&gt;:inclusion&lt;/code&gt;(“is not included in the list”)&lt;/dd&gt;

&lt;dt&gt;&lt;strong&gt;validates_length_of&lt;/strong&gt;&lt;/dt&gt;

&lt;dd&gt;&lt;code&gt;:too_short&lt;/code&gt; (“is too short (minimum is {{count}} characters)”)&lt;br /&gt; &lt;code&gt;:too_long&lt;/code&gt; (“is too long (maximum is {{count}} characters)”)&lt;/dd&gt;

&lt;dt&gt;&lt;strong&gt;validates_length_of (with :is option)&lt;/strong&gt;&lt;/dt&gt;

&lt;dd&gt;&lt;code&gt;:wrong_length&lt;/code&gt; (“is the wrong length (should be {{count}} characters)”)&lt;/dd&gt;

&lt;dt&gt;&lt;strong&gt;validates_numericality_of&lt;/strong&gt;&lt;/dt&gt;

&lt;dd&gt;&lt;code&gt;:not_a_number&lt;/code&gt; (“is not a number”)&lt;/dd&gt;

&lt;dt&gt;&lt;strong&gt;validates_numericality_of (with :odd option)&lt;/strong&gt;&lt;/dt&gt;

&lt;dd&gt;&lt;code&gt;:odd&lt;/code&gt; (“must be odd”)&lt;/dd&gt;

&lt;dt&gt;&lt;strong&gt;validates_numericality_of (with :even option)&lt;/strong&gt;&lt;/dt&gt;

&lt;dd&gt;&lt;code&gt;:even&lt;/code&gt; (“must be even”)&lt;/dd&gt;

&lt;dt&gt;&lt;strong&gt;validates_numericality_of (with :greater_than option)&lt;/strong&gt;&lt;/dt&gt;

&lt;dd&gt;&lt;code&gt;:greater_than&lt;/code&gt; (“must be greater than {{count}}”)&lt;/dd&gt;

&lt;dt&gt;&lt;strong&gt;validates_numericality_of (with :greater_than_or_equal_to option)&lt;/strong&gt;&lt;/dt&gt;

&lt;dd&gt;&lt;code&gt;:greater_than_or_equal_to&lt;/code&gt; (“must be greater than or equal to {{count}}”)&lt;/dd&gt;

&lt;dt&gt;&lt;strong&gt;validates_numericality_of (with :equal_to option)&lt;/strong&gt;&lt;/dt&gt;

&lt;dd&gt;&lt;code&gt;:equal_to&lt;/code&gt; (“must be equal to {{count}}”)&lt;/dd&gt;

&lt;dt&gt;&lt;strong&gt;validates_numericality_of (with :less_than option)&lt;/strong&gt;&lt;/dt&gt;

&lt;dd&gt;&lt;code&gt;:less_than&lt;/code&gt; (“must be less than {{count}}”)&lt;/dd&gt;

&lt;dt&gt;&lt;strong&gt;validates_numericality_of (with :less_than_or_equal_to option)&lt;/strong&gt;&lt;/dt&gt;

&lt;dd&gt;&lt;code&gt;:less_than_or_equal_to&lt;/code&gt; (“must be less than or equal to {{count}}”)&lt;/dd&gt;

&lt;dt&gt;&lt;strong&gt;validates_presence_of&lt;/strong&gt;&lt;/dt&gt;

&lt;dd&gt;&lt;code&gt;:blank&lt;/code&gt; (“can’t be blank”)&lt;/dd&gt;

&lt;dt&gt;&lt;strong&gt;validates_uniqueness_of&lt;/strong&gt;&lt;/dt&gt;

&lt;dd&gt;&lt;code&gt;:taken&lt;/code&gt; (“has already been taken”)&lt;/dd&gt;
&amp;lt;/dl&gt;

&lt;h2&gt;Interpolating values&lt;/h2&gt;

&lt;p&gt;You probably noticed that some of the default messages contain the string &lt;code&gt;{{count}}&lt;/code&gt;. Validations that use some threshold value pass that value into the I18n library as the option &lt;code&gt;count&lt;/code&gt;, and I18n interpolates the count value into the message string.&lt;/p&gt;

&lt;p&gt;In addition to &lt;code&gt;count&lt;/code&gt;, all of the validations supply three other values that can be interpolated: &lt;code&gt;model&lt;/code&gt; and &lt;code&gt;attribute&lt;/code&gt; (the model and attribute names, already humanized as discussed in &lt;a href="http://blog.thinkrelevance.com/2009/9/2/keep-models-out-of-your-views-business"&gt;part 1&lt;/a&gt;) and &lt;code&gt;value&lt;/code&gt; (the erronenous value of the attribute). You can write your error messages to make use of any of those values, using the same double-curly-brace syntax.&lt;/p&gt;

&lt;h2&gt;Writing custom validations&lt;/h2&gt;

&lt;p&gt;If you write your own validation methods, whether just for your project or in a plugin, you should make use of the same mechanisms.&lt;/p&gt;

&lt;p&gt;When a validation detects an error, it reports that error by calling the &lt;code&gt;#add&lt;/code&gt; method on the &lt;code&gt;errors&lt;/code&gt; object. Here’s an example (taken from &lt;code&gt;validates_inclusion_of&lt;/code&gt;, and slightly modified to make more sense out of context):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;record.errors.add(attr_name, :inclusion, 
                             :value =&amp;gt; value, 
                             :default =&amp;gt; options[:message]) &lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The first parameter is the name of the attribute being validated. Second is the symbol that’s used to look up the default message text from the I18n message repositories. Finally there’s an options hash, which includes the current attribute value (for possible interpolation into messages) and any new message text that may have been supplied directly on the call to &lt;code&gt;validates_inclusion_of&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;(That last bit is somewhat confusing; the option to &lt;code&gt;add&lt;/code&gt; is called &lt;code&gt;default&lt;/code&gt;, but it’s actually a specific override. That bit of weirdness is there to maintain some internal compatibility for the benefit of plugins that were written for older versions of Rails. I wouldn’t be surprised to see that cleaned up in Rails 3, although for now it still works the same way.)&lt;/p&gt;

&lt;p&gt;All you need to do in your custom validation is to use the &lt;code&gt;#add&lt;/code&gt; method in the same way, and supply default error message text in a message repository, under the &lt;code&gt;en.activerecord.messages&lt;/code&gt; key. You can do it directly in &lt;code&gt;config/locales/en.yml&lt;/code&gt;, like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;en:
  activerecord:
    messages:
      bozo: &amp;quot;can't be ridiculous&amp;quot;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Plugins and gems can supply their own YAML file. They just need to tell Rails about it by pushing the file path onto &lt;code&gt;I18n.load_path&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;As I said last week, the fact that Rails uses model and attribute names in views isn’t a bad thing; it’s a useful convention that helps developers move quickly. The test of a framework like Rails is how easy it is to break those links when you need to. Rails’ internationalization support makes it easy to solve this particular problem, with the added benefit that it makes your application easier to localize, should you need to go down that path.&lt;/p&gt;

&lt;p&gt;I’ve completely stopped overriding validation error messages directly in the model code. You should, too!&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/relevance-llc/~4/gAVaIIWIPsY" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://blog.thinkrelevance.com/2009/9/9/keep-models-out-of-your-views-business-2</feedburner:origLink></entry>
  <entry xml:base="http://blog.thinkrelevance.com/">
    <author>
      <name>glenn</name>
    </author>
    <id>tag:blog.thinkrelevance.com,2009-09-02:11270</id>
    <published>2009-09-02T12:09:00Z</published>
    <updated>2009-09-09T14:06:29Z</updated>
    <category term="i18n" />
    <category term="mvc" />
    <category term="rails" />
    <link href="http://feedproxy.google.com/~r/relevance-llc/~3/WBfM_AA6A_0/keep-models-out-of-your-views-business" rel="alternate" type="text/html" />
    <title>Keep Models out of Your Views' Business!</title>
<content type="html">
            &lt;p&gt;One of the core goals of the MVC architecture is to separate the &lt;em&gt;presentation&lt;/em&gt; of a model from its implementation and semantics.
And yet Rails, out of the box, takes the representation of models—even the names of tables and columns in the database—right through to the user.
The default behavior, for form labels and other places where models and attributes are referred to, is simply to use the name of the model or attribute.&lt;/p&gt;

&lt;p&gt;Does this mean Rails’ implementation of MVC is broken?
Not at all!
My favorite definition of “architecture” in software is “the set of decisions that will be hard to change later.”
And the best architectures are &lt;a href="http://martinfowler.com/ieeeSoftware/whoNeedsArchitect.pdf" title="Who Needs an Architect? by Martin Fowler"&gt;the ones that keep that set small&lt;/a&gt;,
allowing developers to move quickly without fear of being boxed-in later in the project.
Rails uses its default behavior to let you move quickly, but leaves your options open for changing that behavior later.&lt;/p&gt;

&lt;p&gt;I think Rails’ defaults work really well in most cases.
After all, we should be working with a &lt;a href="http://books.google.com/books?id=7dlaMs0SECsC&amp;amp;amp;printsec=frontcover" title="Domain-Driven Design: Tackling Complexity in the Heart of Software, by Eric Evans"&gt;domain language&lt;/a&gt; that we share with customers and domain experts,
so it’s likely that our schema and models will use names that are appropriate for presentation.
Nevertheless, it’s common to reach a point where the user interface needs to use different terms for some of the domain concepts.&lt;/p&gt;

&lt;p&gt;So let’s see how Rails can help.
Assume we’ve developed the “canonical” Rails application, a blogging engine.
The primary model is called &lt;code&gt;Post&lt;/code&gt;, and each post has a &lt;code&gt;title&lt;/code&gt; and &lt;code&gt;body&lt;/code&gt;.
And then, the customer decides that the users will prefer writing “articles” rather than “posts”, and “headlines” instead of “titles”.&lt;/p&gt;

&lt;p&gt;What can we do?&lt;/p&gt;

&lt;h2&gt;Breaking the Link: The Obvious Ways&lt;/h2&gt;

&lt;p&gt;The most obvious, brute-force solution is to avoid the defaults, instead supplying literal names in all of our views.
While there are places where it will be appropriate to supply literal labels, this option should be reserved for specific places where the &lt;em&gt;context&lt;/em&gt; requires a different label.
Using this approach to change labels throughout the application would be way too much work, and create a maintenance nightmare.&lt;/p&gt;

&lt;p&gt;You could actually change your model—rename the table, or column, along with every place that name appears in your Ruby code.
But that approach would be tedious and error-prone if the name were central to your model.
More importantly, it would be a mistake to change the domain model understood by those involved in the project just to satisfy presentation constraints.
It’s at this point that the MVC architecture needs to pull its weight by helping you deal with this problem.&lt;/p&gt;

&lt;p&gt;Digging a little deeper, you realize that the places in ActionView that use model and attribute names (e.g., the &lt;code&gt;label&lt;/code&gt; helper) transform them to “human” form first, removing underscores, adding spaces, and capitalizing appropriately.
They do that by calling the &lt;code&gt;human_name&lt;/code&gt; method (for model names) and &lt;code&gt;human_attribute_name&lt;/code&gt; (for attributes).
Every ActiveRecord model inherits those methods from &lt;code&gt;ActiveRecord::Base&lt;/code&gt;.
So one answer is to override those methods.
That’s much better than either of the other options,
but it’s still not very good.
If you solve your problem this way, the model will be &lt;em&gt;actively&lt;/em&gt; involved in presentation issues.
We want to work &lt;em&gt;with&lt;/em&gt; the MVC architecture, not against it.&lt;/p&gt;

&lt;h2&gt;Breaking the Link: The Right Way&lt;/h2&gt;

&lt;p&gt;The answer to our problem can be found in the documentation for &lt;a href="http://apidock.com/rails/v2.3.2/ActiveRecord/Base/human_attribute_name/class"&gt;&lt;code&gt;ActiveRecord::Base#human_attribute_name&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;This used to be depricated in favor of humanize, but is now preferred,
    because it automatically uses the I18n module now.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We can use Rails’ internationalization support to supply the new names we want to present to users.
Think about your current problem as specifying the English localization for your application.&lt;/p&gt;

&lt;p&gt;If it’s not already there, create the file &lt;code&gt;config/locales/en.yml&lt;/code&gt;, with the following contents:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;en:
  activerecord:
    models:
      post: "Article"
    attributes:
      post:
        title: "Headline"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Under the &lt;code&gt;en.activerecord&lt;/code&gt; key there are two sections that define presentation names for the locale: 
&lt;code&gt;models&lt;/code&gt; contains names for models, and &lt;code&gt;attributes&lt;/code&gt; contains names for … well, I think you get the idea.
So in our example, the new name for a post is “Article”, and the new name for a post’s title is “Headline”.
Note that you specify attribute names in the context of a model class,
so if there were another &lt;code&gt;title&lt;/code&gt; attribute in your system on a different model class, it would not be affected.&lt;/p&gt;

&lt;p&gt;Suddenly, throughout your application, those changes will take effect.
You can still supply different labels in particular contexts as needed, 
but the default is to use the names in the locale file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; As commenter Tim Watson pointed out, it’s not currently automatic everywhere.
It does automatically happen in error messages, but not in labels
(making labels handle this automatically is planned for an upcoming Rails point release).
You can supply the proper label text on your own (using the &lt;code&gt;human_attribute_name&lt;/code&gt; method).
If you’re using custom FormBuilders, you can easily encapsulate this change;
otherwise, see commenter Priit Tamboom’s solution for doing a quick monkeypatch of the label helper until Rails handles it properly.&lt;/p&gt;

&lt;p&gt;As you may have gathered from the documentation excerpt above, you should use &lt;code&gt;Post.human_attribute_name('title')&lt;/code&gt; instead of calling &lt;code&gt;humanize&lt;/code&gt; on an attribute name when writing views.
Likewise, you should use &lt;code&gt;post.class.human_name&lt;/code&gt; rather than &lt;code&gt;post.class.name.humanize&lt;/code&gt; or the literal &lt;code&gt;'Post'&lt;/code&gt; for model class names.&lt;/p&gt;

&lt;p&gt;Also, associations are treated as attributes, rather than inheriting the new name of their target model.
So if some model had an association to multiple posts, you would need to define an attribute renaming in the appropriate model;
it would not automatically be called “Articles”.&lt;/p&gt;

&lt;p&gt;Finally, this approach doesn’t deal with controller names in URLs;
for that, you should modify the routes in &lt;code&gt;config/routes.rb&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;More To Come&lt;/h2&gt;

&lt;p&gt;There’s more to this story, because there’s another place where your models peek through into the user interface in undesirable ways.
I’ll address that in &lt;a href="http://blog.thinkrelevance.com/2009/9/9/keep-models-out-of-your-views-business-2"&gt;a follow-up post&lt;/a&gt;.&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/relevance-llc/~4/WBfM_AA6A_0" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://blog.thinkrelevance.com/2009/9/2/keep-models-out-of-your-views-business</feedburner:origLink></entry>
  <entry xml:base="http://blog.thinkrelevance.com/">
    <author>
      <name>don</name>
    </author>
    <id>tag:blog.thinkrelevance.com,2009-09-01:11264</id>
    <published>2009-09-01T07:00:00Z</published>
    <updated>2009-09-01T12:17:13Z</updated>
    <link href="http://feedproxy.google.com/~r/relevance-llc/~3/t0jQ-DPVf1A/ahhh-this-porridge-is-just-right" rel="alternate" type="text/html" />
    <title>RunCodeRun Basic Plan Now Available</title>
<content type="html">
            &lt;p&gt;We've been building your &lt;a href="http://runcoderun.com/browse/"&gt;open source
projects&lt;/a&gt; for about a year now.  Thanks
to the experience we've gained from our wonderful commercial beta
users you too can let us take care of your continuous integration
needs, &lt;a href="http://runcoderun.com/plans"&gt;no matter what they are&lt;/a&gt; -- as
long as you use &lt;a href="http://github.com"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Premium&lt;/strong&gt; and &lt;strong&gt;Walk Among the Gods&lt;/strong&gt; plans, &lt;a href="http://blog.thinkrelevance.com/2009/8/4/runcoderun-now-supports-private-builds"&gt;announced earlier
this month&lt;/a&gt;
provide a dedicated server for each account.  We're pleased to
announce that the &lt;a href="http://runcoderun.com"&gt;RunCodeRun&lt;/a&gt; &lt;strong&gt;Basic Plan&lt;/strong&gt;
is also available.  Targeted at solo developers, the Basic Plan costs
$19 per month and supports up to three private projects.  Unlike our
other plans, the Basic Plan private builds run on shared RunCodeRun
build resources.&lt;/p&gt;

&lt;p&gt;With three plans to choose from, we know that one of them is just right for you.  &lt;a href="http://runcoderun.com/plans"&gt;Sign up&lt;/a&gt; and focus on delivering valuable software instead of on maintaining CI servers.&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/relevance-llc/~4/t0jQ-DPVf1A" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://blog.thinkrelevance.com/2009/9/1/ahhh-this-porridge-is-just-right</feedburner:origLink></entry>
  <entry xml:base="http://blog.thinkrelevance.com/">
    <author>
      <name>glenn</name>
    </author>
    <id>tag:blog.thinkrelevance.com,2009-08-25:11228</id>
    <published>2009-08-25T12:12:00Z</published>
    <updated>2009-10-16T14:40:04Z</updated>
    <category term="fuzz testing" />
    <category term="open-source" />
    <category term="rails" />
    <category term="ruby 1.9" />
    <link href="http://feedproxy.google.com/~r/relevance-llc/~3/q-8SsaUueFk/tarantula-supports-ruby-1-9" rel="alternate" type="text/html" />
    <title>Tarantula Supports Ruby 1.9 </title>
<content type="html">
            &lt;p&gt;We’re excited about Ruby 1.9.
It’s fast and stable, and brings nice improvements for programmers.
But there are obstacles to adoption—mostly gems, plugins, and tools that don’t support 1.9 yet.&lt;/p&gt;

&lt;p&gt;So we’re working on the things Relevance maintains, to get them on board.
We’re doing it by dog-fooding: 
We’ve got one customer project that we’re actively testing on both 1.8 and 1.9 (although deployment is still on 1.8 for the moment).
That’s helping us see where the holes are, so we can fix them.
We’re already working on Ruby 1.9 support for &lt;a href="http://runcoderun.com/"&gt;RunCodeRun&lt;/a&gt;, and investigating the best way to interface &lt;a href="http://github.com/relevance/rcov/tree/master"&gt;rcov&lt;/a&gt; with 1.9.&lt;/p&gt;

&lt;p&gt;Now one more piece of the puzzle is in place: on our last &lt;a href="http://howwework.thinkrelevance.com/developer_narrative.html#open_source_fridays"&gt;open-source Friday&lt;/a&gt;, &lt;a href="http://thinkrelevance.com/team/chad-humphries"&gt;Chad&lt;/a&gt; upgraded &lt;a href="http://github.com/relevance/tarantula"&gt;Tarantula&lt;/a&gt; to support Ruby 1.9.
If you’re trying out Rails on 1.9 (or even if you aren’t), get the latest version (0.2.1) of tarantula from github:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;gem install --source http://gems.github.com relevance-tarantula
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then add the plugin to your app and add some fuzz-testing goodness to it!&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/relevance-llc/~4/q-8SsaUueFk" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://blog.thinkrelevance.com/2009/8/25/tarantula-supports-ruby-1-9</feedburner:origLink></entry>
  <entry xml:base="http://blog.thinkrelevance.com/">
    <author>
      <name>glenn</name>
    </author>
    <id>tag:blog.thinkrelevance.com,2009-08-19:11199</id>
    <published>2009-08-19T13:15:00Z</published>
    <updated>2009-10-16T14:40:15Z</updated>
    <category term="agile" />
    <category term="enterprise" />
    <category term="tools" />
    <link href="http://feedproxy.google.com/~r/relevance-llc/~3/nteJj_NZ6TM/the-longevity-of-enterprise-tools" rel="alternate" type="text/html" />
    <title>The Longevity of "Enterprise" Tools</title>
<content type="html">
            &lt;p&gt;During the recent &lt;a href="http://erubycon.com/"&gt;erubycon&lt;/a&gt; conference, there was a lot of twitter traffic from attendees about how great the conference was.
One who did not attend wondered if a conference discussing “Ruby in the enterprise” was &lt;a href="http://twitter.com/matzeller/status/3202494390"&gt;wishful thinking or reality?&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Sorry if this disappoints anyone, but there was almost no wishful thinking, and a lot of reality.
But there’s a third option: planning next moves.
There was a lot of discussion about how to promote Ruby effectively in enterprises that aren’t already using it—not because Ruby is the be-all, end-all of programming (it’s not) but because we have all found it helpful across a wide variety of programming tasks, and we think it is a good antidote for the more common, “enterprisey” tools that often bring more bad than good to a project.&lt;/p&gt;

&lt;p&gt;During a panel discussion right after my keynote (&lt;a href="http://blog.thinkrelevance.com/2009/8/8/why-enterprise-tools-are-bad-for-the-enterprise"&gt;Why “Enterprise Tools” are Bad for the Enterprise&lt;/a&gt;), someone asked “What do we say to a manager who doesn’t trust open-source tools to still be around in a few years?”&lt;/p&gt;

&lt;p&gt;Something snapped in me—I’d heard that same question one too many times.
Commercial tools are available solely based on their customers.
If the tool gets enough customers, the tool continues.
Otherwise, it will all disappear.
And it &lt;em&gt;must&lt;/em&gt; disappear, given the nature of the software business.&lt;/p&gt;

&lt;p&gt;There are three scenarios (with variations) for new software development tools, and all are common:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;get enough customers to be profitable, and continue for many years.&lt;/li&gt;
&lt;li&gt;get enough customers to look viable, get purchased and see the tool squashed or sidelined by the new owners.&lt;/li&gt;
&lt;li&gt;get just a few customers, and have your board shut you down.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When you choose a commercial tool, you’re making a bet that enough other people will purchase it to make it viable, &lt;em&gt;and&lt;/em&gt; that it won’t be purchased and shut down by a competitor.&lt;/p&gt;

&lt;p&gt;When you choose open-source tools, there is no monetary pressure on the toolmaker to continue; only community pressure.
It’s much easier (and cheaper) to bring community pressure.
Additionally, even if the toolmaker chooses not to continue, the community can keep the tool alive.
Many open-source development tools that have long since dropped from most people’s radar (think &lt;a href="http://www.tcl.tk/"&gt;Tcl&lt;/a&gt;, for example) still have thriving communities that actively support the tools and help each other with difficulties.
With a proprietary tool, the legal structures surrounding it virtually guarantee that the tool will die if the vendor loses interest.&lt;/p&gt;

&lt;p&gt;In every respect, open source tools have a better chance of surviving than their commercial cousins.  Sure, some of those commercial tools will be viable for a long time, but most won’t.  Whereas most open source tools will be around for a long time.  Open source tools actually &lt;em&gt;diminish&lt;/em&gt; risk, not enhance it.&lt;/p&gt;

&lt;p&gt;Anyway, getting back to the panel question at erubycon:
I decided it was time for action, because this is such an &lt;em&gt;easy&lt;/em&gt; point to refute with just a little preparation.&lt;/p&gt;

&lt;p&gt;So I volunteered to play scribe during the party that evening, and I spent much of the party sitting in a chair with a pad and pen, while attendees helped me remember “enterprise tools” that have come and gone.
We built a list of commercial, “enterprise” software development tools of one sort or another that were commercially viable no longer ago than 1995 (when Java first hit the scene) but which are now “dead”.
(“Dead”, for purposes of this list, means either that there is no longer commercial support for the tool, or that there has been no significant new development on the tool in the past five years.)&lt;/p&gt;

&lt;p&gt;It’s a &lt;a href="https://sites.google.com/a/thinkrelevance.com/enterprise-tools-gone-by/"&gt;long list&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The point of this is not to prove that open-source tools are better than proprietary tools (obviously I think they are in most cases, but this list won’t prove it either way).
The point is to show clearly that there is no guarantee that a tool will still be around and supported after a few years, proprietary or not.&lt;/p&gt;

&lt;p&gt;I’m sure there are other tools that we didn’t think of.
I’m equally sure that some of the tools currently on the list are actually alive; the fact that attendees at erubycon haven’t heard of a tool for a while doesn’t mean it isn’t still being maintained and supported somewhere.
(Here’s a good example.
I thought of a tool that seemed like an open-and-shut case for this:
NetDynamics, the original Java application server.
A little research shows that it was purchased by Sun,
and some of its code formed the basis for the iPlanet application server,
which was later called Sun ONE, and then the Sun Java Enterprise System,
and is now called GlassFish.
Nevertheless, I strongly doubt that old apps written for NetDynamics would run on GlassFish, and I’d be interested to know whether there was ever a clear migration path for NetDynamics customers.)&lt;/p&gt;

&lt;p&gt;So I’m starting the task of double-checking &lt;a href="https://sites.google.com/a/thinkrelevance.com/enterprise-tools-gone-by/"&gt;that list&lt;/a&gt;.
If you’re interested in helping, &lt;a href="mailto:glenn@thinkrelevance.com?subject=Enterprise%20Tool%20Longevity"&gt;send me email&lt;/a&gt;!
I’ll blog about the results here.&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/relevance-llc/~4/nteJj_NZ6TM" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://blog.thinkrelevance.com/2009/8/19/the-longevity-of-enterprise-tools</feedburner:origLink></entry>
  <entry xml:base="http://blog.thinkrelevance.com/">
    <author>
      <name>stu</name>
    </author>
    <id>tag:blog.thinkrelevance.com,2009-08-12:11155</id>
    <published>2009-08-12T23:58:00Z</published>
    <updated>2009-08-13T01:04:04Z</updated>
    <category term="Clojure" />
    <category term="clojure" />
    <link href="http://feedproxy.google.com/~r/relevance-llc/~3/CMfN5PcJY3U/rifle-oriented-programming-with-clojure-2" rel="alternate" type="text/html" />
    <title>Rifle-Oriented Programming with Clojure</title>
<content type="html">
            &lt;p&gt;Any comparison of hot JVM languages is likely to note that “Clojure is not object-oriented.” This is true, but it may lead you to the wrong conclusions. It’s a little like saying that a rifle is not arrow-oriented. In this article, you will see some of the ways that Clojure addresses the key concerns of OO: encapsulation, polymorphism, and inheritance.&lt;/p&gt;

&lt;p&gt;This is a whirlwind tour, and we won't have time to cover the full details of all the Clojure code you will see. When we are done, I hope you will decide to explore for yourself. You can download and start using Clojure by following the instructions on the &lt;a href="http://clojure.org/getting_started"&gt;getting started&lt;/a&gt; page.&lt;/p&gt;

&lt;h2&gt;Just Enough Clojure Syntax&lt;/h2&gt;

&lt;p&gt;Clojure has &amp;lt;emph&gt;vectors&amp;lt;/emph&gt;, which are accessed by integer indexes:&lt;/p&gt;

&lt;pre&gt;&lt;code class="clojure"&gt;[1 2 3 4]
-&gt; [1 2 3 4]

(get [:a :b :c :d :e] 2)
-&gt; :c
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In the preceding example, the initial &lt;code&gt;[1 2 3 4]&lt;/code&gt; is input that you enter at the Read-Eval-Print Loop (REPL). The &lt;code&gt;-&gt;&lt;/code&gt; indicates the response from the REPL.&lt;/p&gt;

&lt;p&gt;Clojure has &amp;lt;emph&gt;maps&amp;lt;/emph&gt;, which are key/value collections:&lt;/p&gt;

&lt;pre&gt;&lt;code class="clojure"&gt;{:fname "Stu", :lname "Halloway"}
-&gt; {:fname "Stu", :lname "Halloway"}
&lt;/code&gt;&lt;/pre&gt;
 
&lt;p&gt;&amp;lt;emph&gt;Sets&amp;lt;/emph&gt; contain a set of values, and their literal form is preceded with a hash. Here is the set of English vowels, using backslash to introduce a character literal:&lt;/p&gt;

&lt;pre&gt;&lt;code class="clojure"&gt;#{\a \e \i \o \u}
-&gt; #{\a \e \i \o \u}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Lists are singly-linked lists, and are enclosed with parentheses. Lists are special: Not only are they data, they also act as the syntax for invoking functions. The list below invokes the plus (&lt;code&gt;+&lt;/code&gt;) function:&lt;/p&gt;

&lt;pre&gt;&lt;code class="clojure"&gt;(+ 1 2 3 4 5)
-&gt; 15
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Collections themselves act as functions. They take an argument which is the key/index to look up:&lt;/p&gt;

&lt;pre&gt;&lt;code class="clojure"&gt;([:a :b :c :d :e] 2)
-&gt; :c

({:name "Stu" :ext 101} :name)
-&gt; "Stu"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Enough syntax, let's get started.&lt;/p&gt;

&lt;h2&gt;Encapsulation&lt;/h2&gt;
&lt;p&gt;Encapsulation is the hiding of implementation details so that clients of your code do not accidentally become dependent on them. In object-oriented languages, this is ususally done at the class level. A class has &lt;em&gt;public&lt;/em&gt; methods, &lt;em&gt;private&lt;/em&gt; implementation details, and various other scopes in between.&lt;/p&gt;

&lt;p&gt;Clojure accomplishes the purposes of encapsulation in three ways: closures, namespaces, and immutability.&lt;/p&gt;

&lt;h3&gt;Closures&lt;/h3&gt;

&lt;p&gt;A &lt;em&gt;closure&lt;/em&gt; closes over (remembers) the environment at the time it was created. For example, the function &lt;code&gt;make-counter&lt;/code&gt; below closes over the initial value passed via &lt;code&gt;init-val&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class="clojure"&gt;(defn make-counter [init-val] 
  (let [c (atom init-val)] #(swap! c inc)))
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Let’s break this down:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;defn&lt;/code&gt; defines a new function, named &lt;code&gt;make-counter&lt;/code&gt;, that takes a single argument &lt;code&gt;init-val&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;let&lt;/code&gt; binds the name &lt;code&gt;c&lt;/code&gt; to a new &lt;code&gt;atom&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;atom&lt;/code&gt; creates a threadsafe, deadlock-proof mutable reference to a value.&lt;/li&gt;
&lt;li&gt;The octothorpe (&lt;code&gt;#&lt;/code&gt;) prefix introduces an anonymous function&lt;/li&gt;
&lt;li&gt;The call to &lt;code&gt;swap!&lt;/code&gt; updates the value referenced by &lt;code&gt;c&lt;/code&gt; by calling &lt;code&gt;inc&lt;/code&gt; on it.&lt;/li&gt;
&lt;li&gt;The value of the let is the value of its last expression. This &lt;code&gt;let&lt;/code&gt; returns a function that increments a counter, which is then the return value of &lt;code&gt;make-counter&lt;/code&gt;.
&lt;/ul&gt;

&lt;p&gt;The atom &lt;code&gt;c&lt;/code&gt; is private to the function returned by &lt;code&gt;make-counter&lt;/code&gt;. The only &lt;em&gt;public&lt;/em&gt; thing you can do is increment it by one:&lt;/p&gt;

&lt;pre&gt;&lt;code class="clojure"&gt;(def c (make-counter))
-&gt; #'user/c

(c)
-&gt; 1

(c)
-&gt; 2

(c)
-&gt; 3
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The counter example returned a single function, but nothing stops you from returning multiple functions. These multiple functions can then share private state. The new version of &lt;code&gt;make-counter&lt;/code&gt; below returns two functions: one to increment the counter, and one to reset it.&lt;/p&gt;

&lt;pre&gt;&lt;code class="clojure"&gt;(defn make-counter [init-val] 
  (let [c (atom init-val)] 
    {:next #(swap! c inc)
     :reset #(reset! c init-val)}))
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This new &lt;code&gt;make-counter&lt;/code&gt; returns a map whose &lt;code&gt;:next&lt;/code&gt; value increments the counter, and whose &lt;code&gt;:reset&lt;/code&gt; value resets it:&lt;/p&gt;

&lt;pre&gt;&lt;code class="clojure"&gt;(def c (make-counter 10))
-&gt; #'user/c

((c :next))
-&gt; 11

((c :next))
-&gt; 12

((c :reset))
-&gt; 10
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Why the double parentheses above? Two functions calls: The inner function call looks up the appropriate function, and the outer one calls it.&lt;/p&gt;

&lt;p&gt;Closing over data is far more general than the simplistic model offered by private, protected, public, friend, et al. in OO languages. By combining multiple lets and multiple return values from a function, you can create arbitrary encapsulation strategies.&lt;/p&gt;

&lt;p&gt;Similar encapsulation possibilities are available in any language that supports closures. Douglas Crockford describes a &lt;a href="http://www.crockford.com/javascript/private.html"&gt;similar idiom&lt;/a&gt; in JavaScript.&lt;/p&gt;

&lt;h3&gt;Namespaces&lt;/h3&gt;

&lt;p&gt;A Clojure namespace groups a set of related data and functions. Inside a namespace, a Clojure &lt;em&gt;var&lt;/em&gt; can refer to a function or to data, and can be public or private.&lt;/p&gt;

&lt;p&gt;For example, Chris Houser’s error-kit library implements a condition/restart system for Clojure.&lt;/p&gt;

&lt;pre&gt;&lt;code class="clojure"&gt;(with-handler
  (vec (map int-half [2 4 5 8]))
    (handle *number-error* [n]
      (continue-with 0))) 
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In the code above, &lt;code&gt;with-handler&lt;/code&gt;, &lt;code&gt;handle&lt;/code&gt;, and &lt;code&gt;continue-with&lt;/code&gt; are public vars of the &lt;code&gt;clojure.contrib.error-kit&lt;/code&gt; namespace. The &lt;code&gt;int-half&lt;/code&gt; is a demo function that blows up on odd inputs. When a &lt;code&gt;*number-error*&lt;/code&gt; occurs, the handler causes execution to continue with the value 0. (Note how this is more flexible than try/catch exception handling, which cannot recover back into the middle of some operation.)&lt;/p&gt;

&lt;p&gt;Internally, error-kit keeps track of available handlers and continues using these private vars:&lt;/p&gt;

&lt;pre&gt;&lt;code class="clojure"&gt;(defvar- *handler-stack* () 
  "Stack of bound handler symbols")
(defvar- *continues* {} 
  "Map of currently available continue forms")
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The trailing minus sign on the end of &lt;code&gt;defvar-&lt;/code&gt; marks the vars as private. These vars are implementation details, and are invisible to code outside the &lt;code&gt;clojure.contrib.error-kit&lt;/code&gt; namespace.&lt;/p&gt;

&lt;h3&gt;Immutability&lt;/h3&gt;

&lt;p&gt;In OO languages, another purpose of encapsulation is to prevent object A from modifying or corrupting the private data used by object B.&lt;/p&gt;

&lt;p&gt;In Clojure, this problem does not exist. Data structures are immutable. They cannot possibly be corrupted, or changed in any way, period. You can write query functions that return “private” state, without any fear of data corruption. &lt;/p&gt;

&lt;h2&gt;Polymorphism&lt;/h2&gt;

&lt;p&gt;For our purposes here, polymorphism is the ability to choose a different method implementation based on the type of the caller. So for example:&lt;/p&gt;

&lt;pre&gt;&lt;code class="clojure"&gt;Flyer a = new Airplane();
Flyer b = new Bird();
a.fly();
b.fly();
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;a.fly()&lt;/code&gt; and &lt;code&gt;b.fly()&lt;/code&gt; do different things because they are called on different concrete types.&lt;/p&gt;

&lt;p&gt;Clojure provides a generalization of polymorphism called multimethods. A multimethod definition begins with &lt;code&gt;defmulti&lt;/code&gt;, and then has a name, plus a &lt;em&gt;dispatch function&lt;/em&gt; that is used to select the actual implementation: To mimic polymorphism, simply dispatch on the &lt;code&gt;class&lt;/code&gt; of the argument:&lt;/p&gt;

&lt;pre&gt;&lt;code class="clojure"&gt;(defmulti fly class)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Individual methods of a multimethod begin with &lt;code&gt;defmethod&lt;/code&gt;, then the multimethod name, then the object that must match the dispatch function.  Finally, you get the argument list in a vector, followed by the implementation of the method. For example:&lt;/p&gt;

&lt;pre&gt;&lt;code class="clojure"&gt;(defmethod fly Bird [b] (flap-wings b))
(defmethod fly Airplane [a] (turn-propeller a))
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Unlike polymorphism, multimethods do not limit you to dispatching on class. You can dispatch based on any arbitrary function of the method arguments. So for example, a bank account might have a &lt;code&gt;:type&lt;/code&gt; entry that is used to determine the interest rate:&lt;/p&gt;

&lt;pre&gt;&lt;code class="clojure"&gt;(defmulti interest :type)
(defmethod interest :checking [a] 0)
(defmethod interest :savings [a] 0.05M)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;:type&lt;/code&gt; attribute is a convention, but nothing prevents you from dispatching on a different attribute, or even dispatching on more than one at the same time! For example, the &lt;code&gt;service-charge&lt;/code&gt; multimethod below dispatches on two different facets of the same object: the object’s &lt;code&gt;account-level&lt;/code&gt; (&lt;code&gt;::Basic&lt;/code&gt; or &lt;code&gt;::Premium&lt;/code&gt;) and its &lt;code&gt;:tag:&lt;/code&gt; (&lt;code&gt;::Checking&lt;/code&gt; or &lt;code&gt;::Savings&lt;/code&gt;)&lt;/p&gt;

&lt;pre&gt;&lt;code class="clojure"&gt;(defmulti service-charge 
  (fn [acct] [(account-level acct) (:tag acct)]))
(defmethod service-charge [::Basic ::Checking]   [_] 25)
(defmethod service-charge [::Basic ::Savings]    [_] 10)
(defmethod service-charge [::Premium ::Checking] [_] 0)
(defmethod service-charge [::Premium ::Savings]  [_] 0)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;_&lt;/code&gt; is a legal name, and is used idiomatically to indicate that an argument will be ignored. (There is no need to even look at the argument, since all the work has been done in choosing which method to dispatch to!) This example also demonstrates two other concepts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The double-colon prefix resolves a keyword in a namespace. This prevents name collisions among &lt;em&gt;keywords&lt;/em&gt;, just as object-oriented langauges use namespaces to prevent name collisions between &lt;em&gt;type names&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;account-level&lt;/code&gt; is a function (not shown here), not a simple key lookup. It returns &lt;code&gt;::Premium&lt;/code&gt; or &lt;code&gt;::Basic&lt;/code&gt; based on the the account type and the current balance. Thus an account can dynamically change its account level as its balance changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As you can see, multimethods are far more general than polymorphism. Instead of being limited to type-based dispatch, multimethods can dispatch on any arbitrary function of an argument list. This allows programming models that more closely resemble reality: after all, what real-world entities are limited to a single type hierarchy, and forbidden to change types over time?&lt;/p&gt;

&lt;h3&gt;Inheritance&lt;/h3&gt;

&lt;p&gt;In OO languages, inheritance allows you to create a &lt;em&gt;derived&lt;/em&gt; type that reuses the behavior of a &lt;em&gt;base&lt;/em&gt; type. For example:&lt;/p&gt;

&lt;pre&gt;&lt;code class="clojure"&gt;class Person {
  String fullName() { /* impl details */ }
}
class Employee extends Person {
  AddressBookItem companyDirectoryEntry() { /* impl details */ }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This kind of reuse is so natural in Clojure that it doesn’t even have a name. For example, here is a function that returns the full name of a person, based on first and last names:&lt;/p&gt;

&lt;pre&gt;&lt;code class="clojure"&gt;(defn full-name [p]
  (str (:first-name p) " " (:last-name p)))
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Employees are like people, but have other properties and behaviors, such as a telephone extension. The &lt;code&gt;company-directory-entry&lt;/code&gt; returns a vector of an employee's full name and telephone extension, like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class="clojure"&gt;(defn company-directory-entry [p]
  [(full-name p) (:extension p)])
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Notice that &lt;code&gt;company-directory-entry&lt;/code&gt; “reuses” the person-ness of its argument &lt;code&gt;p&lt;/code&gt; by calling &lt;code&gt;full-name&lt;/code&gt; on it. There is no special inheritance ceremony required to set this up, you just call functions when you need them.&lt;/p&gt;

&lt;p&gt;You can pass either a person or an employee to &lt;code&gt;full-name&lt;/code&gt;. For &lt;code&gt;company-directory-entry&lt;/code&gt;, though, you must have an employee. Or, more accurately, you must have something that &lt;em&gt;resembles&lt;/em&gt; an employee, to the extent of having a &lt;code&gt;:first-name&lt;/code&gt;, &lt;code&gt;:last-name&lt;/code&gt;, and &lt;code&gt;:extension&lt;/code&gt;. This is an example of &lt;em&gt;duck typing&lt;/em&gt;: if it walks like a duck and quacks like a duck, we assume it &lt;em&gt;is&lt;/em&gt; a duck, without asking it to present its &lt;code&gt;IDuck&lt;/code&gt; papers.&lt;/p&gt;

&lt;h3&gt;Many Functions, Few Types&lt;/h3&gt;

&lt;p&gt;The example above demonstrates another negative consequence of idiomatic OO style: the over-specification of data types. The return value of &lt;code&gt;companyDirectoryEntry&lt;/code&gt; is given its own unique type, &lt;code&gt;AddressBookItem&lt;/code&gt;. Each new data type like &lt;code&gt;AddressBookItem&lt;/code&gt; requires its own life-support system: constructors, accessors, &lt;code&gt;equals&lt;/code&gt;, &lt;code&gt;hashCode&lt;/code&gt;, and so on.&lt;/p&gt;

&lt;p&gt;In Clojure, an address book item would simply be a vector or a map. No new types, and no life support system required. Moreover, an address book item can be manipulated with any of the large arsenal of functions in Clojure's &lt;em&gt;sequence library&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;To see the problem with overspecifying types, consider this method from the Apache Commons:&lt;/p&gt;

&lt;pre&gt;&lt;code class="clojure"&gt;// From Apache Commons Lang, http://commons.apache.org/lang/
public static int indexOfAny(String str, char[] searchChars) {
    if (isEmpty(str) || ArrayUtils.isEmpty(searchChars)) {
	return -1;
    }
    for (int i = 0; i &amp;lt; str.length(); i++) {
	char ch = str.charAt(i);
	for (int j = 0; j &amp;lt; searchChars.length; j++) {
	    if (searchChars[j] == ch) {
		return i;
	    }
	}
    }
    return -1;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The purpose of &lt;code&gt;indexOfAny&lt;/code&gt; is to find the index of the first occurrence of one of the &lt;code&gt;searchChars&lt;/code&gt; that appears in &lt;code&gt;str&lt;/code&gt;. Note the unnecessary specificity of types: it works only with strings and character arrays.&lt;/p&gt;

&lt;p&gt;Here's the Clojure version, using the sequence library's &lt;code&gt;map&lt;/code&gt;, &lt;code&gt;iterate&lt;/code&gt;, and &lt;code&gt;for&lt;/code&gt; forms:&lt;/p&gt;

&lt;pre&gt;&lt;code class="clojure"&gt;(defn indexed [coll] (map vector (iterate inc 0) coll))
(defn index-filter [pred coll]
  (when pred 
    (for [[idx elt] (indexed coll) :when (pred elt)] idx)))
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Here is an example calling &lt;code&gt;index-filter&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class="clojure"&gt;(index-filter #{\a \e \i \o \u} "Lts f cnsnts nd n vwel")
-&gt; (20)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The expression above finds the index of the first vowel in the string "Lts f cnsnts nd n vwel", that is, 20. But &lt;code&gt;index-filter&lt;/code&gt; is more general than the Commons version in several ways:&lt;/p&gt;

&lt;p&gt;1. &lt;code&gt;index-filter&lt;/code&gt; returns all the matches, not just one.&lt;/p&gt;

&lt;pre&gt;&lt;code class="clojure"&gt;(index-filter #{\a \e \i \o \o} "The quick brown fox")
-&gt; (2 6 12 17)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;2. &lt;code&gt;index-filter&lt;/code&gt; works with any sequence, not just a string of characters. For example, the call below works against a range of integers:&lt;/p&gt;

&lt;pre&gt;&lt;code class="clojure"&gt;(index-filter #{2 3 5 7} (range 6))
-&gt; (2 3 5)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;3. &lt;code&gt;index-filter&lt;/code&gt; works with any predicate, not just a test against a character array. In the example below, the predicate is an anonymous function that tests for strings longer than three characters:&lt;/p&gt;

&lt;pre&gt;&lt;code class="clojure"&gt;(index-filter #(&gt; (.length %) 3) ["The" "quick" "brown" "fox"])
-&gt; (1 2)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That is a lot of extra power, especially given that the function is shorter, easier to write, and easier to read (given some Clojure experience, of course) than the Commons version.&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Clojure solves the same problems that OO solves, but it solves them in different ways. Instead of encapsulation, polymorphism, and inheritance, you have closures, namespaces, pure functions, immutable data, and multimethods. Idiomatic OO gives you a bloated type system with duplicated code hidden away behind encapsulation boundaries and little hope for thread safety. Clojure offers a radical alternative: a lean type system, a rich function library, and language-level concurrency support that is usable by mere mortals.&lt;/p&gt;

&lt;p&gt;There is a lot more to Clojure than we have covered here: lazy and infinite sequences, destructuring, macros, software transactional memory, agents, seamless Java interop, and more. But those are topics for another day.&lt;/p&gt;

&lt;p&gt;[This article was originally published in the May 2009 issue of &lt;a href="http://www.nofluffjuststuff.com/home/magazine_subscribe"&gt;NFJS, the Magazine&lt;/a&gt;. I will be speaking about Clojure at several upcoming NFJS events, &lt;a href="http://www.nofluffjuststuff.com"&gt;come join the fun&lt;/a&gt;.]&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/relevance-llc/~4/CMfN5PcJY3U" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://blog.thinkrelevance.com/2009/8/12/rifle-oriented-programming-with-clojure-2</feedburner:origLink></entry>
  <entry xml:base="http://blog.thinkrelevance.com/">
    <author>
      <name>jgehtland</name>
    </author>
    <id>tag:blog.thinkrelevance.com,2009-08-04:11116</id>
    <published>2009-08-04T17:26:00Z</published>
    <updated>2009-08-04T17:43:53Z</updated>
    <link href="http://feedproxy.google.com/~r/relevance-llc/~3/1aoLfO0JIik/runcoderun-now-supports-private-builds" rel="alternate" type="text/html" />
    <title>RunCodeRun now supports private builds</title>
<content type="html">
            &lt;p&gt;We are pleased to announce that &lt;a href="http://runcoderun.com"&gt;RunCodeRun&lt;/a&gt; is now accepting private builds. This means that you can now connect your private repositories on &lt;a href="http://github.com"&gt;GitHub&lt;/a&gt; to RunCodeRun for your continuous integration needs.  You can drop by our &lt;a href="http://runcoderun.com/plans"&gt;list of plans&lt;/a&gt; to see which best suits your situation.&lt;/p&gt;

&lt;p&gt;We feel it important to note that RunCodeRun remains, as always, free for open source developers.  If you are already an open source customer and want to upgrade, just sign in and head to the plans page and pick the option that works for you.   You can keep all your open source projects active, now and forever, regardless of which plan you are on.  And if you are just interested in getting started with an open source project? That’s easy: just sign up for an open source account. You can always upgrade later if you want to add private builds.&lt;/p&gt;

&lt;p&gt;We look forward to seeing your projects clean and green!&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/relevance-llc/~4/1aoLfO0JIik" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://blog.thinkrelevance.com/2009/8/4/runcoderun-now-supports-private-builds</feedburner:origLink></entry>
  <entry xml:base="http://blog.thinkrelevance.com/">
    <author>
      <name>glenn</name>
    </author>
    <id>tag:blog.thinkrelevance.com,2009-08-04:11114</id>
    <published>2009-08-04T12:28:00Z</published>
    <updated>2009-08-04T12:40:10Z</updated>
    <category term="corey haines" />
    <category term="journeyman" />
    <category term="pair programming" />
    <category term="videos" />
    <link href="http://feedproxy.google.com/~r/relevance-llc/~3/eocZMi18ZxU/pairing-and-conversations-with-corey-haines" rel="alternate" type="text/html" />
    <title>Pairing and Conversations with Corey Haines</title>
<content type="html">
            &lt;p&gt;&lt;a href="http://www.coreyhaines.com/"&gt;Corey Haines&lt;/a&gt; was in our neck of the woods recently, and we were delighted to host him for three days of pairing and great conversations.
We’re very fond of the &lt;a href="http://en.wikipedia.org/wiki/Software_Craftsmanship"&gt;craftsmanship&lt;/a&gt; model of software development, especially as a method of training.
Although we haven’t gone about it as explicitly as Corey has in his &lt;a href="http://programmingtour.blogspot.com/"&gt;journeyman tours&lt;/a&gt;,
we all feel that we learned our skills largely through working with great programmers.
(And if we had it to do over again, we’d seriously consider following Corey’s example and &lt;em&gt;really&lt;/em&gt; being journeymen for a while.)
Our interview process here involves a full day on-site, pair programming with members of our team,
and we often learn cool things from even that amount of cross-pollination.
So we felt especially fortunate having &lt;em&gt;three&lt;/em&gt; days with Corey.&lt;/p&gt;

&lt;p&gt;Corey arrived with an interest in &lt;a href="http://clojure.org/"&gt;Clojure&lt;/a&gt;, so he spent most of his time pairing with &lt;a href="http://thinkrelevance.com/team/stuart-halloway"&gt;Stuart&lt;/a&gt; on one of our Clojure projects.
And he stayed with &lt;a href="http://thinkrelevance.com/team/muness-alrubaie"&gt;Muness&lt;/a&gt;, in his apartment right upstairs from our office.
The result?
Two cool video interviews:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://programmingtour.blogspot.com/2009/07/conversation-with-stuart-halloway.html"&gt;with Stuart&lt;/a&gt; discussing his &lt;a href="http://www.pragprog.com/titles/shcloj/programming-clojure"&gt;Clojure book&lt;/a&gt;, and &lt;a href="http://howwework.thinkrelevance.com/"&gt;the way we do things at Relevance&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://programmingtour.blogspot.com/2009/07/conversation-with-muness-alrubaie.html"&gt;with Muness&lt;/a&gt; about Muness’ interest in the human side of software development: group dynamics, management, effective meetings, and retrospectives.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We couldn’t be happier with how these turned out.
They highlight Stuart and Muness and their passions, but they show a lot about the rest of us here at Relevance as well.
Thanks, Corey!&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/relevance-llc/~4/eocZMi18ZxU" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://blog.thinkrelevance.com/2009/8/4/pairing-and-conversations-with-corey-haines</feedburner:origLink></entry>
</feed>
