<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Jayway Team Blog &#187; review</title>
	<atom:link href="http://blog.jayway.com/tag/review/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.jayway.com</link>
	<description>Sharing Experience</description>
	<lastBuildDate>Sat, 28 Jan 2012 15:53:55 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Review of Crafting Rails Applications, by Jos&#233; Valim</title>
		<link>http://blog.jayway.com/2010/12/30/review-of-crafting-rails-applications-by-jos-valim/</link>
		<comments>http://blog.jayway.com/2010/12/30/review-of-crafting-rails-applications-by-jos-valim/#comments</comments>
		<pubDate>Thu, 30 Dec 2010 11:16:37 +0000</pubDate>
		<dc:creator>Anders Janmyr</dc:creator>
				<category><![CDATA[Dynamic languages]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[review]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://blog.jayway.com/?p=6934</guid>
		<description><![CDATA[Jos&#233; Valim is one of the newest members of the Rails core team. Apart from this he has also developed some good gems, Devise, Responders, and SimpleForm, that I use for almost every project. And now he has written a book, a really good book, about advanced Rails programming techniques, called Crafting Rails Applications. The [...]]]></description>
			<content:encoded><![CDATA[<p>Jos&eacute; Valim is one of the newest members of the Rails core team. Apart from this he has also developed some good gems, <a href="https://github.com/plataformatec/devise">Devise</a>, <a href="https://github.com/plataformatec/responders">Responders</a>, and <a href="https://github.com/plataformatec/simple_form">SimpleForm</a>, that I use for almost every project.</p>
<p>And now he has written a book, a <strong>really</strong> good book, about advanced Rails programming techniques, called <a href="http://pragprog.com/titles/jvrails/crafting-rails-applications">Crafting Rails Applications</a>.</p>
<p>The book is only 180 pages long, and contains 7 chapters. I wish more books was this thin. The books is written in a clear concise way. Jos&eacute;'s lightweight test-driven approach clearly introduces every problem it intends to solve, and then solves the problem by introducing a new concept in the Rails framework. Most of the solutions are only a few lines of code, showing the power of Rails and also showing the power of having intimate knowledge of the framework. By hooking into the framework at appropriate places, Jos&eacute; is able to provide elegant solutions to a range of problems.</p>
<p>I highly recommend the book to anyone interested in Rails.</p>
<p>If this was an ordinary book, this review could have ended here, but since the book is full of things I really wanted to know but didn't take the time to learn I decided to internalize them by describing parts of the book in my own words.</p>
<h2>Chapter 1, Creating our own renderer</h2>
<p>In this chapter we learn how to add a new renderer Rails. We add a renderer that handles generating PDF files with <a href="http://prawn.majesticseacreature.com/">Prawn</a>, allowing us to write code that looks like this.</p>
<p><!-- Generator: GNU source-highlight 3.1.4<br />
by Lorenzo Bettini</p>
<p>http://www.lorenzobettini.it</p>
<p>http://www.gnu.org/software/src-highlite --></p>
<pre><tt><b><font color="#0000FF">class</font></b> HomeController <font color="#990000">&lt;</font> ApplicationController
  <b><font color="#0000FF">def</font></b> index
    respond_to <b><font color="#0000FF">do</font></b> <font color="#990000">|</font>format<font color="#990000">|</font>
      format<font color="#990000">.</font>html
      <i><font color="#9A1900"># This is the new capability, pdf rendering.</font></i>
      format<font color="#990000">.</font>pdf <font color="#FF0000">{</font> render <font color="#990000">:</font>pdf <font color="#990000">=&gt;</font> <font color="#FF0000">"contents"</font> <font color="#FF0000">}</font>
    <b><font color="#0000FF">end</font></b>
  <b><font color="#0000FF">end</font></b>
<b><font color="#0000FF">end</font></b>
</tt></pre>
<p>To allow the following we first have to register pdf as a mime type. We can do this with:</p>
<p><!-- Generator: GNU source-highlight 3.1.4<br />
by Lorenzo Bettini</p>
<p>http://www.lorenzobettini.it</p>
<p>http://www.gnu.org/software/src-highlite --></p>
<pre><tt><b><font color="#000080">require</font></b> <font color="#FF0000">"action_controller"</font>
<i><font color="#9A1900"># Register a new mime type</font></i>
Mime<font color="#990000">::</font>Type<font color="#990000">.</font>register <font color="#FF0000">"application/pdf"</font><font color="#990000">,</font> <font color="#990000">:</font>pdf

<i><font color="#9A1900"># Registering the type allows us to write</font></i>
respond_to <b><font color="#0000FF">do</font></b> <font color="#990000">|</font>format<font color="#990000">|</font>
  format<font color="#990000">.</font>pdf
<b><font color="#0000FF">end</font></b>
</tt></pre>
<p>With that out of the way all we have to do is to register a renderer, that will handle the actual rendering of the registered mime type. This is done with:</p>
<p><!-- Generator: GNU source-highlight 3.1.4<br />
by Lorenzo Bettini</p>
<p>http://www.lorenzobettini.it</p>
<p>http://www.gnu.org/software/src-highlite --></p>
<pre><tt><b><font color="#000080">require</font></b> <font color="#FF0000">"prawn"</font> 

<i><font color="#9A1900"># Adds a new renderer to ActionController.Renderers</font></i>
ActionController<font color="#990000">::</font>Renderers<font color="#990000">.</font>add <font color="#990000">:</font>pdf <b><font color="#0000FF">do</font></b> <font color="#990000">|</font>filename<font color="#990000">,</font> options<font color="#990000">|</font>
  pdf <font color="#990000">=</font> Prawn<font color="#990000">::</font>Document<font color="#990000">.</font>new pdf<font color="#990000">.</font>text render_to_string<font color="#990000">(</font>options<font color="#990000">)</font>
  send_data<font color="#990000">(</font>pdf<font color="#990000">.</font>render<font color="#990000">,</font> <font color="#990000">:</font>filename <font color="#990000">=&gt;</font> <font color="#FF0000">"#{filename}.pdf"</font><font color="#990000">,</font>
      <font color="#990000">:</font>type <font color="#990000">=&gt;</font> <font color="#FF0000">"application/pdf"</font><font color="#990000">,</font> <font color="#990000">:</font>disposition <font color="#990000">=&gt;</font> <font color="#FF0000">"attachment"</font><font color="#990000">)</font>
<b><font color="#0000FF">end</font></b>
</tt></pre>
<p>This is all that is needed to add a rendering of a new type to Rails. Jos&eacute; also goes into details about other points of interest where the rendering stack can be customized.</p>
<h2>Chapter 2, Easy models with Active Model</h2>
<p>Active Model is a Rails module that abstracts common behavior needed by different kinds om models such as Active Record, Active Resource and third party modules like Mongoid. Apart from giving developers of new models utility functionality. Active Model also provides tests for being Active Model compliant. To be compliant means to play well with the Rails view and controllers.</p>
<p>Jos&eacute; implements a model for creating sending mail. In doing so he introduces us to a bunch of Active Model modules that will do our work for us.</p>
<p>Here are the modules in alphabetical order:</p>
<h3>ActiveModel::AttributeMethods</h3>
<p>When you include <code>ActiveModel::AttributeMethods</code> in your model, you get access to helper methods that will help you define additional methods for dealing with the attributes of your model. An example</p>
<p><!-- Generator: GNU source-highlight 3.1.4<br />
by Lorenzo Bettini</p>
<p>http://www.lorenzobettini.it</p>
<p>http://www.gnu.org/software/src-highlite --></p>
<pre><tt><b><font color="#0000FF">class</font></b> Tapir
  <b><font color="#0000FF">include</font></b> ActiveModel<font color="#990000">::</font>AttributeMethods

  <i><font color="#9A1900"># Define the attributes </font></i>
  attr_accessor <font color="#FF0000">'name'</font><font color="#990000">,</font> <font color="#FF0000">'color'</font>

  <i><font color="#9A1900"># We want to create clear methods for every attribute</font></i>
  attribute_method_prefix <font color="#FF0000">'clear_'</font>

  <i><font color="#9A1900"># We also want to have query methods for every attribute</font></i>
  attribute_method_suffix <font color="#FF0000">'?'</font>

  <i><font color="#9A1900"># Define the attribute methods that will call the protected methods below</font></i>
  define_attribute_methods <font color="#990000">[</font><font color="#FF0000">'name'</font><font color="#990000">,</font> <font color="#FF0000">'color'</font><font color="#990000">]</font>

protected
  <i><font color="#9A1900"># The name of this method corresponds to the prefix above</font></i>
  <b><font color="#0000FF">def</font></b> clear_attribute<font color="#990000">(</font>attribute<font color="#990000">)</font>
    send<font color="#990000">(</font><font color="#FF0000">"#{attribute}="</font><font color="#990000">,</font> <b><font color="#0000FF">nil</font></b><font color="#990000">)</font>
  <b><font color="#0000FF">end</font></b>

  <i><font color="#9A1900"># The name of this method corresponds to the suffix above</font></i>
  <b><font color="#0000FF">def</font></b> attribute?<font color="#990000">(</font>attribute<font color="#990000">)</font>
    send<font color="#990000">(</font>attribute<font color="#990000">).</font>present?
  <b><font color="#0000FF">end</font></b>
<b><font color="#0000FF">end</font></b>

</tt></pre>
<p><!-- Generator: GNU source-highlight 3.1.4<br />
by Lorenzo Bettini</p>
<p>http://www.lorenzobettini.it</p>
<p>http://www.gnu.org/software/src-highlite --></p>
<pre><tt>   t <font color="#990000">=</font> Tapir<font color="#990000">.</font>new
 <font color="#990000">=&gt;</font> <i><font color="#9A1900">#&lt;Tapir:0x00000102769b90&gt; </font></i>
<font color="#990000">&gt;</font> t<font color="#990000">.</font>name<font color="#990000">?</font>
 <font color="#990000">=&gt;</font> <b><font color="#0000FF">false</font></b>
<font color="#990000">&gt;</font> t<font color="#990000">.</font><font color="#009900">name</font><font color="#990000">=</font> <font color="#FF0000">'kalle'</font>
 <font color="#990000">=&gt;</font> <font color="#FF0000">"kalle"</font>
<font color="#990000">&gt;</font> t<font color="#990000">.</font>name<font color="#990000">?</font>
 <font color="#990000">=&gt;</font> <b><font color="#0000FF">true</font></b>
<font color="#990000">&gt;</font> t<font color="#990000">.</font>clear_name
 <font color="#990000">=&gt;</font> nil
<font color="#990000">&gt;</font> t<font color="#990000">.</font>name<font color="#990000">?</font>
 <font color="#990000">=&gt;</font> <b><font color="#0000FF">false</font></b>
<font color="#990000">&gt;</font> t<font color="#990000">.</font>name
</tt></pre>
<p>This is the gist of attribute methods, there is also an affix method that will allow you to add both a suffix and a prefix to your attributes. It is also worth taking a look inside the implmentation of this module, since the methods are defined on first usage through method_missing.</p>
<h3>ActiveModel::Callbacks</h3>
<p><code>ActiveModel::Callbacks</code> provides methods for creating <code>before_</code>, <code>after_</code>, and `around_' callbacks to your model methods. An example:</p>
<p><!-- Generator: GNU source-highlight 3.1.4<br />
by Lorenzo Bettini</p>
<p>http://www.lorenzobettini.it</p>
<p>http://www.gnu.org/software/src-highlite --></p>
<pre><tt><b><font color="#0000FF">class</font></b> Tapir
  extend ActiveModel<font color="#990000">::</font>Callbacks

  define_model_callbacks <font color="#990000">:</font>snort

  <b><font color="#0000FF">def</font></b> snort
    _run_snort_callbacks <b><font color="#0000FF">do</font></b>
      snort_snort_snort
    <b><font color="#0000FF">end</font></b>
  <b><font color="#0000FF">end</font></b>

<b><font color="#0000FF">end</font></b>

</tt></pre>
<p>Then in inheriting classes I can use the callbacks as such:</p>
<p><!-- Generator: GNU source-highlight 3.1.4<br />
by Lorenzo Bettini</p>
<p>http://www.lorenzobettini.it</p>
<p>http://www.gnu.org/software/src-highlite --></p>
<pre><tt><b><font color="#0000FF">class</font></b> MountainTapir <font color="#990000">&lt;</font> Tapir
  before_snort <font color="#990000">:</font>do_before_snort

  <b><font color="#0000FF">def</font></b> before_snort
    i_am_so_cold
  <b><font color="#0000FF">end</font></b>
<b><font color="#0000FF">end</font></b>

</tt></pre>
<h3>ActiveModel::Conversion</h3>
<p>This module assists with converting to, and representing a specific model instance. It contains three methods.</p>
<ul>
<li><code>to_model</code>, used for converting to an active model compliant model, in the default case it just returns <code>self</code>.</li>
<li><code>to_param</code>, used for representing a model in routing.</li>
<li><code>to_key</code>, used for representing a model from in a dom page.</li>
</ul>
<h3>ActiveModel::Naming and ActiveModel::Translation</h3>
<p><code>ActiveModel::Naming</code> contains one method <code>model_name</code>, that returns a subclass of String, that handles pluralization, etc. It has methods such as <code>plural</code>, <code>human</code>.</p>
<p><code>ActiveModel::Translation</code> deals with I18N by adding functionality to <code>human</code> that handles the name lookup by keys using the preferred <code>I18n.backend</code>.</p>
<h3>ActiveModel::Validations</h3>
<p>The last, but not least of the models, <code>ActiveModel::Validations</code>, deals with validations. Jos&eacute; demostrates how naming convetions and Rails constant lookup allow us to add new validators to Rails with ease. An example:</p>
<p><!-- Generator: GNU source-highlight 3.1.4<br />
by Lorenzo Bettini</p>
<p>http://www.lorenzobettini.it</p>
<p>http://www.gnu.org/software/src-highlite --></p>
<pre><tt><b><font color="#0000FF">module</font></b> Validators
  <b><font color="#0000FF">class</font></b> TapirKindValidator <font color="#990000">&lt;</font> ActiveModel<font color="#990000">::</font>EachValidator
    <b><font color="#0000FF">def</font></b> validate_each<font color="#990000">(</font>record<font color="#990000">,</font> attribute<font color="#990000">,</font> value<font color="#990000">)</font>
      <b><font color="#0000FF">unless</font></b> <font color="#990000">[:</font>baird<font color="#990000">,</font> <font color="#990000">:</font>mountain<font color="#990000">,</font> <font color="#990000">:</font>malayan<font color="#990000">,</font> <font color="#990000">:</font>lowland<font color="#990000">].</font><b><font color="#0000FF">include</font></b><font color="#990000">?</font> value
        record<font color="#990000">.</font>errors<font color="#990000">.</font>add<font color="#990000">(</font>attribute<font color="#990000">,</font> <font color="#990000">:</font>invalid<font color="#990000">,</font> options<font color="#990000">)</font>
      <b><font color="#0000FF">end</font></b>
    <b><font color="#0000FF">end</font></b>
  <b><font color="#0000FF">end</font></b>
<b><font color="#0000FF">end</font></b>

</tt></pre>
<p>If I now include my new validator wherever I want to use it. I can write code like:</p>
<p><!-- Generator: GNU source-highlight 3.1.4<br />
by Lorenzo Bettini</p>
<p>http://www.lorenzobettini.it</p>
<p>http://www.gnu.org/software/src-highlite --></p>
<pre><tt><b><font color="#0000FF">class</font></b> Tapir
  <b><font color="#0000FF">include</font></b> Validators

  attr_accessor <font color="#990000">:</font>kind
  validates <font color="#990000">:</font>kind<font color="#990000">,</font> <font color="#990000">:</font>tapir_kind <font color="#990000">=&gt;</font> <b><font color="#0000FF">true</font></b>
<b><font color="#0000FF">end</font></b>

t <font color="#990000">=</font> Tapir<font color="#990000">.</font>new <font color="#990000">:</font>kind <font color="#990000">=&gt;</font> <font color="#990000">:</font>mexican
t<font color="#990000">.</font>valid?
<i><font color="#9A1900"># =&gt; false</font></i>
t<font color="#990000">.</font>errors<font color="#990000">[:</font>kind<font color="#990000">]</font>
<i><font color="#9A1900"># ["is invalid"]</font></i>

</tt></pre>
<p>This example is unnecessarily complicated, since the validation could be fixed with:</p>
<p><!-- Generator: GNU source-highlight 3.1.4<br />
by Lorenzo Bettini</p>
<p>http://www.lorenzobettini.it</p>
<p>http://www.gnu.org/software/src-highlite --></p>
<pre><tt><b><font color="#0000FF">class</font></b> Tapir
    attr_accessor <font color="#990000">:</font>kind
    validates_inclusion_of <font color="#990000">:</font>kind<font color="#990000">,</font> <font color="#990000">:</font><b><font color="#0000FF">in</font></b> <font color="#990000">=&gt;</font>  <font color="#990000">[:</font>baird<font color="#990000">,</font> <font color="#990000">:</font>mountain<font color="#990000">,</font> <font color="#990000">:</font>malayan<font color="#990000">,</font> <font color="#990000">:</font>lowland<font color="#990000">]</font>
<b><font color="#0000FF">end</font></b>

</tt></pre>
<h3>append_view_path</h3>
<p>There is one more interesting thing in this chapter, <code>append_view_path</code>. It can be used to add a directory inside a gem to the view lookup path. This is essential to be able to deliver custom Rails components, Railties, with default views.</p>
<h2>Chapter 3, Building a template management system</h2>
<p>In the third chapter of the book,Jos&eacute; takes on view resolvers. A resolver is responsible for looking up the appropriate template for a given request. The traditional resolver looks up the templates by path in the file system, but Jos&eacute; guides us through creating a resolver that looks up the template in a database. Perfect for the core of a CMS system. I'm going to alter Jos&eacute;'s resolver to do the lookup in MongoDB instead.</p>
<p><!-- Generator: GNU source-highlight 3.1.4<br />
by Lorenzo Bettini</p>
<p>http://www.lorenzobettini.it</p>
<p>http://www.gnu.org/software/src-highlite --></p>
<pre><tt><i><font color="#9A1900"># Most of this code is borrowed directly from Jos&amp;eacute; Valim</font></i>
<i><font color="#9A1900"># Only the Mongoid Part is written by me <img src='http://blog.jayway.com/wordpress/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </font></i>
<b><font color="#000080">require</font></b> <font color="#FF0000">'mongoid'</font>
<b><font color="#000080">require</font></b> <font color="#FF0000">'singleton'</font>

<b><font color="#0000FF">class</font></b> MongoTemplate
  <b><font color="#0000FF">include</font></b> Mongoid<font color="#990000">::</font>Document
  field <font color="#990000">:</font>body
  field <font color="#990000">:</font>path
  field <font color="#990000">:</font>locale
  field <font color="#990000">:</font>format
  field <font color="#990000">:</font>handler
  field <font color="#990000">:</font>partial<font color="#990000">,</font> <font color="#990000">:</font>type <font color="#990000">=&gt;</font> Boolean
  field <font color="#990000">:</font>updated_at<font color="#990000">,</font> <font color="#990000">:</font>type <font color="#990000">=&gt;</font> Date

  validates <font color="#990000">:</font>body<font color="#990000">,</font> <font color="#990000">:</font>path<font color="#990000">,</font> <font color="#990000">:</font>presence <font color="#990000">=&gt;</font> <b><font color="#0000FF">true</font></b>
  validates <font color="#990000">:</font>format<font color="#990000">,</font> <font color="#990000">:</font>inclusion <font color="#990000">=&gt;</font> Mime<font color="#990000">::</font>SET<font color="#990000">.</font>symbols<font color="#990000">.</font>map<font color="#990000">(&amp;:</font>to_s<font color="#990000">)</font>
  validates <font color="#990000">:</font>locale<font color="#990000">,</font> <font color="#990000">:</font>inclusion <font color="#990000">=&gt;</font> I18n<font color="#990000">.</font>available_locales<font color="#990000">.</font>map<font color="#990000">(&amp;:</font>to_s<font color="#990000">)</font>
  validates <font color="#990000">:</font>handler<font color="#990000">,</font> <font color="#990000">:</font>inclusion <font color="#990000">=&gt;</font>
    ActionView<font color="#990000">::</font>Template<font color="#990000">::</font>Handlers<font color="#990000">.</font>extensions<font color="#990000">.</font>map<font color="#990000">(&amp;:</font>to_s<font color="#990000">)</font>

  <b><font color="#0000FF">class</font></b> Resolver <font color="#990000">&lt;</font> ActionView<font color="#990000">::</font>Resolver
    <b><font color="#0000FF">include</font></b> Singleton
  protected
    <b><font color="#0000FF">def</font></b> find_templates<font color="#990000">(</font>name<font color="#990000">,</font> prefix<font color="#990000">,</font> partial<font color="#990000">,</font> details<font color="#990000">)</font>
      conditions <font color="#990000">=</font> <font color="#FF0000">{</font>
        <font color="#990000">:</font>path <font color="#990000">=&gt;</font> normalize_path<font color="#990000">(</font>name<font color="#990000">,</font> prefix<font color="#990000">),</font>
        <font color="#990000">:</font>locale <font color="#990000">=&gt;</font> normalize_array<font color="#990000">(</font>details<font color="#990000">[:</font>locale<font color="#990000">]).</font>first<font color="#990000">,</font>
        <font color="#990000">:</font>format <font color="#990000">=&gt;</font> normalize_array<font color="#990000">(</font>details<font color="#990000">[:</font>formats<font color="#990000">]).</font>first<font color="#990000">,</font>
        <font color="#990000">:</font>handler<font color="#990000">.</font><b><font color="#0000FF">in</font></b> <font color="#990000">=&gt;</font> normalize_array<font color="#990000">(</font>details<font color="#990000">[:</font>handlers<font color="#990000">]),</font>
        <font color="#990000">:</font>partial <font color="#990000">=&gt;</font> partial <font color="#990000">||</font> <b><font color="#0000FF">false</font></b>
      <font color="#FF0000">}</font>

      MongoTemplate<font color="#990000">.</font>where<font color="#990000">(</font>conditions<font color="#990000">).</font>map <b><font color="#0000FF">do</font></b> <font color="#990000">|</font>record<font color="#990000">|</font>
        initialize_template<font color="#990000">(</font>record<font color="#990000">)</font>
      <b><font color="#0000FF">end</font></b>
    <b><font color="#0000FF">end</font></b>

    <i><font color="#9A1900"># Normalize name and prefix, so the tuple ["index", "users"] becomes </font></i>
    <i><font color="#9A1900"># "users/index" and the tuple ["template", nil] becomes "template". </font></i>
    <b><font color="#0000FF">def</font></b> normalize_path<font color="#990000">(</font>name<font color="#990000">,</font> prefix<font color="#990000">)</font>
      prefix<font color="#990000">.</font>present? <font color="#990000">?</font> <font color="#FF0000">"#{prefix}/#{name}"</font> <font color="#990000">:</font> name
    <b><font color="#0000FF">end</font></b>

    <i><font color="#9A1900"># Normalize arrays by converting all symbols to strings.</font></i>
    <b><font color="#0000FF">def</font></b> normalize_array<font color="#990000">(</font>array<font color="#990000">)</font>
      array<font color="#990000">.</font>map<font color="#990000">(&amp;:</font>to_s<font color="#990000">)</font>
    <b><font color="#0000FF">end</font></b>

    <i><font color="#9A1900"># Initialize an ActionView::Template object based on the record found.</font></i>
    <b><font color="#0000FF">def</font></b> initialize_template<font color="#990000">(</font>record<font color="#990000">)</font>
      source <font color="#990000">=</font> record<font color="#990000">.</font>body
      identifier <font color="#990000">=</font> <font color="#FF0000">"MongoTemplate - #{record.id} - #{record.path.inspect}"</font>
      handler <font color="#990000">=</font> ActionView<font color="#990000">::</font>Template<font color="#990000">.</font>registered_template_handler<font color="#990000">(</font>record<font color="#990000">.</font>handler<font color="#990000">)</font>
      details <font color="#990000">=</font> <font color="#FF0000">{</font>
        <font color="#990000">:</font>format <font color="#990000">=&gt;</font> Mime<font color="#990000">[</font>record<font color="#990000">.</font>format<font color="#990000">],</font>
        <font color="#990000">:</font>updated_at <font color="#990000">=&gt;</font> record<font color="#990000">.</font>updated_at<font color="#990000">,</font>
        <font color="#990000">:</font>virtual_path <font color="#990000">=&gt;</font> virtual_path<font color="#990000">(</font>record<font color="#990000">.</font>path<font color="#990000">,</font> record<font color="#990000">.</font>partial<font color="#990000">)</font>
      <font color="#FF0000">}</font>
      ActionView<font color="#990000">::</font>Template<font color="#990000">.</font>new<font color="#990000">(</font>source<font color="#990000">,</font> identifier<font color="#990000">,</font> handler<font color="#990000">,</font> details<font color="#990000">)</font>
    <b><font color="#0000FF">end</font></b>

    <i><font color="#9A1900"># Make paths as "users/user" become "users/_user" for partials.</font></i>
    <b><font color="#0000FF">def</font></b> virtual_path<font color="#990000">(</font>path<font color="#990000">,</font> partial<font color="#990000">)</font>
      <b><font color="#0000FF">return</font></b> path <b><font color="#0000FF">unless</font></b> partial
      <b><font color="#0000FF">if</font></b> index <font color="#990000">=</font> path<font color="#990000">.</font>rindex<font color="#990000">(</font><font color="#FF0000">"/"</font><font color="#990000">)</font>
        path<font color="#990000">.</font>insert<font color="#990000">(</font>index <font color="#990000">+</font> <font color="#993399">1</font><font color="#990000">,</font> <font color="#FF0000">"_"</font><font color="#990000">)</font>
      <b><font color="#0000FF">else</font></b>
        <font color="#FF0000">"_#{path}"</font>
      <b><font color="#0000FF">end</font></b>
    <b><font color="#0000FF">end</font></b>
  <b><font color="#0000FF">end</font></b>
<b><font color="#0000FF">end</font></b>

</tt></pre>
<p>A Resolver is implemented by extending <code>ActionView::Resolver</code> and implementing the method <code>find_templates(name, prefix, partial, details)</code> There are a lot of extra information in the book, about caching etc. Obviously Rails caches the templates since it would be too slow to create a template every time. That is why we have the template as a singleton and that is why we clear the cache in the <code>after_save</code> hook above. The hook in Mongoid works exactly the same as in Active Record. Thank you Active Model!</p>
<h2>Chapter 4, Multipart Emails with Markdown and Erb</h2>
<p>In this chapter Jos&eacute; walks us through three topics. The template handler API, Rails generators and Railties. I'm going to skip over the last two in this chapter. Generators are a large topic and they deserve a blog post of their own. Jos&eacute; does a great job desribing how they work. The same goes for Railties and Rails Engines, they are definitely worthy of a blog post of their own.</p>
<p><!-- Generator: GNU source-highlight 3.1.4<br />
by Lorenzo Bettini</p>
<p>http://www.lorenzobettini.it</p>
<p>http://www.gnu.org/software/src-highlite --></p>
<pre><tt>
<i><font color="#9A1900"># </font></i>
<i><font color="#9A1900"># Again most of the code is stolen from Jos&amp;eacute; <img src='http://blog.jayway.com/wordpress/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </font></i>
<i><font color="#9A1900">#</font></i>
<b><font color="#0000FF">module</font></b> ScrambleHandler

  <i><font color="#9A1900"># Lookup the ERb handler</font></i>
  <b><font color="#0000FF">def</font></b> <b><font color="#0000FF">self</font></b><font color="#990000">.</font>erb_handler
    <font color="#009900">@@erb_handler</font> <font color="#990000">||=</font> ActionView<font color="#990000">::</font>Template<font color="#990000">.</font>registered_template_handler<font color="#990000">(:</font>erb<font color="#990000">)</font>
  <b><font color="#0000FF">end</font></b>

  <b><font color="#0000FF">def</font></b> <b><font color="#0000FF">self</font></b><font color="#990000">.</font>call<font color="#990000">(</font>template<font color="#990000">)</font>
    <i><font color="#9A1900"># Call the erb handler, then call the new scrambler method.</font></i>
    source <font color="#990000">=</font> erb_handler<font color="#990000">.</font>call<font color="#990000">(</font>template<font color="#990000">)</font>
    <b><font color="#0000FF">if</font></b> template<font color="#990000">.</font>formats<font color="#990000">.</font><b><font color="#0000FF">include</font></b><font color="#990000">?(:</font>html<font color="#990000">)</font>
      <font color="#FF0000">"Scrambler.from_html(begin;#{source};end).to_s"</font>
    <b><font color="#0000FF">else</font></b>
      <font color="#FF0000">"Scrambler.from_text(begin;#{source};end).to_s"</font>
    <b><font color="#0000FF">end</font></b>
  <b><font color="#0000FF">end</font></b>

<b><font color="#0000FF">end</font></b>

<i><font color="#9A1900"># Register our new handler, it handles index.html.scramble, show.html.scramble, ...</font></i>
ActionView<font color="#990000">::</font>Template<font color="#990000">.</font>register_template_handler <font color="#990000">:</font>scramble<font color="#990000">,</font> ScrambleHandler

<i><font color="#9A1900"># This module scrambles text.</font></i>
<i><font color="#9A1900"># Scrambler.from_text('Once upon a time a beautiful tapir came.')</font></i>
<i><font color="#9A1900"># -&gt; Ocne upon a time a baeuuitfl tpiar came.</font></i>
<b><font color="#0000FF">module</font></b> Scrambler
  <b><font color="#0000FF">def</font></b> <b><font color="#0000FF">self</font></b><font color="#990000">.</font>from_html html
    doc <font color="#990000">=</font> Nokogiri<font color="#990000">::</font>HTML<font color="#990000">(</font>html<font color="#990000">)</font>
    doc<font color="#990000">.</font>xpath<font color="#990000">(</font><font color="#FF0000">'//text()'</font><font color="#990000">).</font>each <b><font color="#0000FF">do</font></b> <font color="#990000">|</font>node<font color="#990000">|</font>
      node<font color="#990000">.</font>content <font color="#990000">=</font> from_text<font color="#990000">(</font>node<font color="#990000">.</font>content<font color="#990000">)</font>
    <b><font color="#0000FF">end</font></b>
    doc<font color="#990000">.</font>to_html
  <b><font color="#0000FF">end</font></b>

  <b><font color="#0000FF">def</font></b> <b><font color="#0000FF">self</font></b><font color="#990000">.</font>from_text text
    tokenize<font color="#990000">(</font>text<font color="#990000">).</font>map<font color="#FF0000">{</font><font color="#990000">|</font>token<font color="#990000">|</font> scramble<font color="#990000">(</font>token<font color="#990000">)</font><font color="#FF0000">}</font><font color="#990000">.</font>join<font color="#990000">(</font><font color="#FF0000">''</font><font color="#990000">)</font>
  <b><font color="#0000FF">end</font></b>

  <b><font color="#0000FF">def</font></b> <b><font color="#0000FF">self</font></b><font color="#990000">.</font>tokenize text
    <b><font color="#0000FF">return</font></b> <b><font color="#0000FF">nil</font></b> <b><font color="#0000FF">unless</font></b> text
    text<font color="#990000">.</font>scan<font color="#990000">(</font><font color="#FF6600">/(\p{Word}+|\W+|)/</font>um<font color="#990000">).</font>flatten
  <b><font color="#0000FF">end</font></b>

  <b><font color="#0000FF">def</font></b> <b><font color="#0000FF">self</font></b><font color="#990000">.</font>scramble word
    <b><font color="#0000FF">return</font></b> word <b><font color="#0000FF">if</font></b> word <font color="#990000">=~</font> <font color="#FF6600">/\W/</font>
    <b><font color="#0000FF">return</font></b> word <b><font color="#0000FF">if</font></b> word<font color="#990000">.</font>size <font color="#990000">&lt;</font> <font color="#993399">4</font>
    arr <font color="#990000">=</font> word<font color="#990000">.</font>split<font color="#990000">(</font><font color="#FF6600">//</font><font color="#990000">)</font>
    arr<font color="#990000">[</font><font color="#993399">0</font><font color="#990000">]</font> <font color="#990000">+</font> arr<font color="#990000">[</font><font color="#993399">1</font><font color="#990000">...-</font><font color="#993399">1</font><font color="#990000">].</font>shuffle<font color="#990000">.</font>join<font color="#990000">(</font><font color="#FF0000">''</font><font color="#990000">)</font> <font color="#990000">+</font> arr<font color="#990000">[-</font><font color="#993399">1</font><font color="#990000">]</font>
  <b><font color="#0000FF">end</font></b>
<b><font color="#0000FF">end</font></b>
</tt></pre>
<h2>Chapter 5, Publishing and subscribing to your applications events</h2>
<p>In this chapter Jos&eacute; uses the Notifications API to store notifcations in a MongoDB. He also shows how to use Rack middleware to configure what request to log. In order to configure the middleware he uses a Rails Engine. I'm just going to show how the Notifications API works here, and I'll let you read the rest in the book.</p>
<p><!-- Generator: GNU source-highlight 3.1.4<br />
by Lorenzo Bettini</p>
<p>http://www.lorenzobettini.it</p>
<p>http://www.gnu.org/software/src-highlite --></p>
<pre><tt><i><font color="#9A1900"># Subscribe to all events and print them to the console</font></i>
ActiveSupport<font color="#990000">::</font>Notifications<font color="#990000">.</font>subscribe <b><font color="#0000FF">do</font></b> <font color="#990000">|*</font>args<font color="#990000">|</font>
  p ActiveSupport<font color="#990000">::</font>Notifications<font color="#990000">::</font>Event<font color="#990000">.</font>new<font color="#990000">(*</font>args<font color="#990000">)</font>
<b><font color="#0000FF">end</font></b>

<i><font color="#9A1900"># Instrument the rendering of Foo</font></i>
ActiveSupport<font color="#990000">::</font>Notifications<font color="#990000">.</font>instrument<font color="#990000">(:</font>render<font color="#990000">,</font> <font color="#990000">:</font>extra <font color="#990000">=&gt;</font> <font color="#990000">:</font>information<font color="#990000">)</font> <b><font color="#0000FF">do</font></b>
  render <font color="#990000">:</font>text <font color="#990000">=&gt;</font> <font color="#FF0000">"Foo"</font>
<b><font color="#0000FF">end</font></b>

</tt></pre>
<h2>Chapter 6, DRY controllers with Responders</h2>
<p>In this chapter Jos&eacute; goes through the implementation of responders. This implementation allows you to DRY up your controllers by factoring out common behavior.</p>
<p><!-- Generator: GNU source-highlight 3.1.4<br />
by Lorenzo Bettini</p>
<p>http://www.lorenzobettini.it</p>
<p>http://www.gnu.org/software/src-highlite --></p>
<pre><tt><b><font color="#0000FF">def</font></b> index
  <font color="#009900">@users</font> <font color="#990000">=</font> User<font color="#990000">.</font>all
  respond_to <b><font color="#0000FF">do</font></b> <font color="#990000">|</font>format<font color="#990000">|</font>
    format<font color="#990000">.</font>html <i><font color="#9A1900"># index.html.erb </font></i>
    format<font color="#990000">.</font>xml <font color="#FF0000">{</font> render <font color="#990000">:</font>xml <font color="#990000">=&gt;</font> <font color="#009900">@users</font> <font color="#FF0000">}</font>
  <b><font color="#0000FF">end</font></b>
<b><font color="#0000FF">end</font></b>

<i><font color="#9A1900"># becomes</font></i>

<b><font color="#0000FF">def</font></b> index
  <font color="#009900">@users</font> <font color="#990000">=</font> User<font color="#990000">.</font>all
  respond_with<font color="#990000">(</font><font color="#009900">@users</font><font color="#990000">)</font>
<b><font color="#0000FF">end</font></b>

<i><font color="#9A1900"># and</font></i>
<b><font color="#0000FF">def</font></b> create
  <font color="#009900">@user</font> <font color="#990000">=</font> User<font color="#990000">.</font>new<font color="#990000">(</font>params<font color="#990000">[:</font>user<font color="#990000">])</font>
  respond_to <b><font color="#0000FF">do</font></b> <font color="#990000">|</font>format<font color="#990000">|</font>
  <b><font color="#0000FF">if</font></b> <font color="#009900">@user</font><font color="#990000">.</font>save
    format<font color="#990000">.</font>html <font color="#FF0000">{</font> redirect_to<font color="#990000">(</font><font color="#009900">@user</font><font color="#990000">,</font> <font color="#990000">:</font>notice <font color="#990000">=&gt;</font> <font color="#FF0000">'User was successfully created.'</font><font color="#990000">)</font> <font color="#FF0000">}</font>
    format<font color="#990000">.</font>xml <font color="#FF0000">{</font> render <font color="#990000">:</font>xml <font color="#990000">=&gt;</font> <font color="#009900">@user</font><font color="#990000">,</font> <font color="#990000">:</font>status <font color="#990000">=&gt;</font> <font color="#990000">:</font>created<font color="#990000">,</font> <font color="#990000">:</font>location <font color="#990000">=&gt;</font> <font color="#009900">@user</font> <font color="#FF0000">}</font>
  <b><font color="#0000FF">else</font></b>
    format<font color="#990000">.</font>html <font color="#FF0000">{</font> render <font color="#990000">:</font>action <font color="#990000">=&gt;</font> <font color="#FF0000">"new"</font> <font color="#FF0000">}</font>
    format<font color="#990000">.</font>xml <font color="#FF0000">{</font> render <font color="#990000">:</font>xml <font color="#990000">=&gt;</font> <font color="#009900">@user</font><font color="#990000">.</font>errors<font color="#990000">,</font> <font color="#990000">:</font>status <font color="#990000">=&gt;</font> <font color="#990000">:</font>unprocessable_entity <font color="#FF0000">}</font>
  <b><font color="#0000FF">end</font></b>
<b><font color="#0000FF">end</font></b>

<i><font color="#9A1900"># becomes</font></i>
<b><font color="#0000FF">def</font></b> create
  <font color="#009900">@user</font> <font color="#990000">=</font> User<font color="#990000">.</font>new<font color="#990000">(</font>params<font color="#990000">[:</font>user<font color="#990000">])</font>
  flash<font color="#990000">[:</font>notice<font color="#990000">]</font> <font color="#990000">=</font> <font color="#FF0000">'User was successfully created.'</font> <b><font color="#0000FF">if</font></b> <font color="#009900">@user</font><font color="#990000">.</font>save
  respond_with<font color="#990000">(</font><font color="#009900">@user</font><font color="#990000">)</font>
<b><font color="#0000FF">end</font></b>

</tt></pre>
<p>In this chapter we also learn how to replace the default generators with our own customized generators.</p>
<h2>Chapter 7, Translatable app with I18n and Redis</h2>
<p>In the final chapter Jos&eacute; shows us how the I18N backed system works. He does this by creating a backend the uses Redis instead of the default YAML files. He also developes a simple Sinatra application that he hooks into the Rails routing with the <code>mount</code> method.</p>
<p><!-- Generator: GNU source-highlight 3.1.4<br />
by Lorenzo Bettini</p>
<p>http://www.lorenzobettini.it</p>
<p>http://www.gnu.org/software/src-highlite --></p>
<pre><tt><i><font color="#9A1900"># Mount the Sinatra Translator::App at the /translator path.</font></i>
mount Translator<font color="#990000">::</font>App<font color="#990000">,</font> <font color="#990000">:</font>at <font color="#990000">=&gt;</font> <font color="#FF0000">"/translator"</font>
</tt></pre>
<p>Rack applications normally get the full path inside <code>ENV['PATH_INFO']</code>, but when Rails mounts an application it removes the prefix before it sends it on <code>/translator/en/pt/</code> becomes <code>/en/pt/</code>. The additional path is sent on in <code>ENV['SCRIPT_NAME'] = '/translator'</code>.</p>
<p>We also get a brief overview of Devise, the state-of-the-art authentication solution written by Jos&eacute; himself.</p>
<h2>Conclusion</h2>
<p>One last thing, the book I have reviewed is a beta book, but the quality of it is higher than most published books I have seen. Congratulations to Jos&eacute; and to the pragmatic bookshelf! There is not much more to say, get the book.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jayway.com/2010/12/30/review-of-crafting-rails-applications-by-jos-valim/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Adrenaline Junkies and Template Zombies</title>
		<link>http://blog.jayway.com/2009/11/10/adrenaline-junkies-and-template-zombies/</link>
		<comments>http://blog.jayway.com/2009/11/10/adrenaline-junkies-and-template-zombies/#comments</comments>
		<pubDate>Tue, 10 Nov 2009 04:41:32 +0000</pubDate>
		<dc:creator>Anders Janmyr</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[review]]></category>

		<guid isPermaLink="false">http://blog.jayway.com/?p=2223</guid>
		<description><![CDATA[Since I had plenty of time to read on my flights back and forth to OOPSLA, I managed to read through a few books. One of them was Adrenaline Junkies and Template Zombies by Tom DeMarco et al. Being the sceptic that I am, my attitude when starting to read this book was: "Yeah, I [...]]]></description>
			<content:encoded><![CDATA[<p>Since I had plenty of time to read on my flights back and forth to OOPSLA, I managed to read through a few books. One of them was <a href="http://www.amazon.com/Adrenaline-Junkies-Template-Zombies-Understanding/dp/0932633676?tag=thtasta-20">Adrenaline Junkies and Template Zombies</a> by Tom DeMarco et al. Being the sceptic that I am, my attitude when starting to read this book was: "Yeah, I know a lot of people has praised this book and I know that Tom DeMarco has written <a href="http://www.amazon.com/Peopleware-Productive-Projects-Teams-Second/dp/0932633439?tag=thtasta-20">Peopleware</a>, but what the hell do <a href="http://www.systemsguild.com/">these bozos</a> know anyway!" <img src='http://blog.jayway.com/wordpress/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>I figured that the six of them could probably scrape together a few decent people patterns, but I am a bit fed up with the whole pattern template style, so my expectations were not as high as they should have been.</p>
<p>Anyway, the book is amazing, the pattern template is really lightweight, basically, a name, an image, a statement, and a story. And the stories, are <strong>good</strong>. The authors have a remarkable ability to observe human nature and also the ability to write about what they see.</p>
<h3>Some Patterns</h3>
<p>The book contains 86 patterns, most of them are negative since they are funnier, as one of the authors said on a podcast.</p>
<h4>Dead Fish</h4>
<p>A dead fish is a project, that every one knows is impossible to start out with, but nobody says anything since the culture in the company is that way.<br />
If you say something you may get responses like,</p>
<blockquote><p>Prove it! Prove that it is not feasible that this project will succeed!</p>
</blockquote>
<p>Or,</p>
<blockquote><p>Are you a weenie or a layabout?</p>
</blockquote>
<p>Projects like this are usually worked on until it is inevitable that they will be late, and then everybody acts surprised.</p>
<h4>Nanny</h4>
<p>A nanny is a project manager that is aware of the capabilities of her staff and nurtures them and lets them at their peek. The nanny is responsible for improving her staff and make responsible project citizen of them. A nanny enables workers to do their job.</p>
<h4>Eye Contact</h4>
<p>If your life depended on a project, would you want them working close together or in different corners of the world? Human communication goes way beyond words, and it is foolish to think that it is possible to work at full speed with people who don't know each other and live in different places.</p>
<h4>Dashboards</h4>
<p>A dashboard is a highly visible board, that enable the project members and others to get an instant view of the status of the project. It can be a web page or a board on the wall. What is significant with a dashboard is that it is updated as soon as anything important happens in the project. All project members care for the dashboard since that is the place where they can find out how they are doing. Dashboards contain just the right amount of data.</p>
<h4>Film Critics</h4>
<p>A film critic is a project member or someone related to the project who thinks that they can succeed even if the project is a failure. They may often have good points, but usually when it is too late to do something about it. It is no use to have a person like this on the team, since they are not really on the team if they don't go down with the ship.</p>
<h4>Natural Authority</h4>
<p>The word authority have several meanings. The meaning of <em>an authority</em> is a person who knows a great deal about something. Another meaning, <em>in authority</em>, is a person who is in charge. A person who is an authority and in authority is a natural authority. This is the healthy pattern.</p>
<h4>The White Line</h4>
<p>The white line is the line on a tennis court. The line is a clear signal if the ball is in or out. Occasional dispute may arise over a questionable judgment call, but the line is respected by everyone. Most projects don't have this line. Create a white line for your project so that you know what is inside the project scope and what is not.</p>
<h4>Silence Gives Consent</h4>
<p>If someone don't oppose an idea, it is, usually, taken as consent. Especially from people who come from different working areas, like management and programmers. Silent consent is not good for anyone, because nobody is sure what has been decided and what has not. A way to remedy this problem is to keep a list of commitments where it is written down who has promised who what. The Scrum sprint backlog is similar to such a list.</p>
<h4>Time Removes Cards from Your Hand</h4>
<p>The earlier a decision can be made, the better. If you know that a project will not make a deadline, the decision to change the scope should be made as early as possible, since that will allow the team to work on the most important features first. If a decision is delayed until it is too late, the decision is made implicitly by time.</p>
<h4>Rhythm</h4>
<p>Instead of being daunted by overwhelming tasks, projects with rhythm take small, regular steps thus establishing a regular beat that carries them toward their goal.</p>
<blockquote><p>This journey of a thousand miles begins with a single step --Lao Tzu</p>
</blockquote>
<h4>False Quality Gates</h4>
<p>False quality gates are quality checks that don't do anything to promote the quality of the project. It is a sign that more attention is concentrated on format, rather than content. It can be a glossary of terms with the wrong content or a word template where most of the sections are filled in with the words "This section must contain text to fulfill company guidelines".</p>
<h4>Testing Before Testing</h4>
<p>Testing before testing refers to the practice of thinking about <em>how</em> to test a feature at the same time you think about how to implement it. If it cannot be tested how can you know that it does what you say?</p>
<h4>Cider House Rules</h4>
<p>Cider house rules are rules written by someone unconnected to the project. Rules like this, that give no apparent value, are a burden to the project and therefore often ignored.</p>
<blockquote><p>Nobody pays attention to them rules. Every year Olive writes them up and every year nobody pays any attention to them. -- John Irving, The Cider House Rules</p>
</blockquote>
<h4>Talk Then Write</h4>
<p>The team makes decisions during conversation, and then immediately communicates the decisions in writing. <strong>This is a really important pattern that it is easy to forget!</strong>. A common place where this kind of decisions are written down is very helpful.</p>
<h4>Practicing the End Game</h4>
<p>A team that does not release often and regularly will often take a long time to make a release. The act of releasing a product should be practiced often so that is becomes a natural part of the project.</p>
<h4>Data Quality</h4>
<p>Data quality often sucks! A common solution is often to attack the problem with technology instead of putting in the manpower that is actually needed to improve the quality of the data. Company web-sites are the prime example of this. They are often full of completely useless information.</p>
<h4>Undivided Attention</h4>
<p>Complex work is hard and it requires undivided attention to be performed properly. Splitting people's attention over multiple project will severely hinder their performance.</p>
<blockquote><p>By doing two things at once, you've cut your IQ in half, and believe me, those 40 points can really make a difference. -- Dale Dauden, The New York Times</p>
</blockquote>
<h4>Orphaned Deliverables</h4>
<p>Orphaned deliverables are deliverables that no-one values enough to pay for. Always make sure that there is a sponsor for every artifact that you are developing.</p>
<h4>Hidden Beauty</h4>
<p>Hidden beauty inside a program, that little extra thing, that may seem unnecessary, is what shows that the creator cares about his work. <em>It is not unnecessary!</em> This caring is what separates a quality product from garbage.</p>
<h4>I Don't Know</h4>
<p>If you are afraid of saying the words, "I don't know!", you are probably working in an organization where saying it means that you will be taken for a fool. In a healthy organization, "I don't know!", means that you don't know, but you will in a while, if it is important enough.</p>
<h4>Loud and Clear</h4>
<p>Having a clear goal, that everyone agrees to, is vital to a project. Clear goals allows you to focus the project activity if it starts to move away from its purpose. A PAM statement, that contains the Purpose, Advantage, and Measurements of a project is very helpful.</p>
<h3>Conclusion</h3>
<p>The patterns described above are just my short summaries, and I don't do them justice, but hopefully I have awoken your interest in this wonderful book.</p>
<p>It made my top-ten list and I recommend it to everyone from programmer to president. I like that the authors don't always provide a solution, but instead just describe the way they see it, it is up to you to figure out a solution to the problem yourself.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jayway.com/2009/11/10/adrenaline-junkies-and-template-zombies/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

