<?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>Mike Naberezny &#187; Ruby</title>
	<atom:link href="http://mikenaberezny.com/category/ruby/feed/" rel="self" type="application/rss+xml" />
	<link>http://mikenaberezny.com</link>
	<description></description>
	<lastBuildDate>Sat, 04 Feb 2012 17:35:25 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<item>
		<title>Horde/Routes 0.3 Released</title>
		<link>http://mikenaberezny.com/2008/06/15/horderoutes-03-released/</link>
		<comments>http://mikenaberezny.com/2008/06/15/horderoutes-03-released/#comments</comments>
		<pubDate>Sun, 15 Jun 2008 21:23:44 +0000</pubDate>
		<dc:creator>Mike Naberezny</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[horde]]></category>

		<guid isPermaLink="false">http://mikenaberezny.com/?p=160</guid>
		<description><![CDATA[Horde/Routes is a URL mapping system for PHP 5. It is a direct port of the Routes, a Python library that is part of the Pylons project. Horde/Routes is a standalone library designed to be integrated into any MVC framework. This release brings in some changes from Routes 1.8. The most noticeable change is that [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://dev.horde.org/routes">Horde/Routes</a> is a URL mapping system for PHP 5.  It is a direct port of the <a href="http://routes.groovie.org">Routes</a>, a Python library that is part of the Pylons project.  Horde/Routes is a standalone library designed to be integrated into any MVC framework.  </p>
<p>This release brings in some changes from Routes 1.8.  The most noticeable change is that custom actions on <a href="http://dev.horde.org/routes/manual/restful-services.html">RESTful routes</a> are now delimited with the forward slash (<code>/</code>) instead of the semicolon (<code>;</code>).  This was done for <a href="http://dev.rubyonrails.org/changeset/6485">parity</a> with Ruby on Rails.  </p>
<p>I have also fixed some bugs, notably that the resource route generator failed to generate routes that recognized <code>PUT</code> and <code>DELETE</code> requests on &#8220;formatted&#8221; resources (<code>/messages/1.xml</code>).  This fix will be merged upstream to the Python version.  </p>
<p>I am also using the Python version and I met with <a href="http://groovie.org/">Ben Bangert</a>, the author of the Python version, at <a href="http://mikenaberezny.com/2008/03/20/pycon-2008-wrap-up/">PyCon 2008</a>.  Each release of Horde/Routes has resulted in patches to the Python version.  It&#8217;s nice how this small ecosystem has developed around the routes concept between these projects (Ruby on Rails, Pylons, and our work in Horde).</p>
<p>Since Horde/Routes 0.3, the default RESTful routes generated by Horde/Routes are fully compatible with the latest version of <a href="http://api.rubyonrails.org/classes/ActiveResource/Base.html">ActiveResource</a>.  We have a new project at <a href="http://maintainable.com">work</a> that is using Horde/Routes and ActiveResource together and it works well.</p>
]]></content:encoded>
			<wfw:commentRss>http://mikenaberezny.com/2008/06/15/horderoutes-03-released/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Parsing Quoted Strings in Ruby</title>
		<link>http://mikenaberezny.com/2008/04/28/parsing-quoted-strings-in-ruby/</link>
		<comments>http://mikenaberezny.com/2008/04/28/parsing-quoted-strings-in-ruby/#comments</comments>
		<pubDate>Mon, 28 Apr 2008 12:40:37 +0000</pubDate>
		<dc:creator>Mike Naberezny</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://mikenaberezny.com/?p=155</guid>
		<description><![CDATA[Python has a nice module in the standard library called shlex that parses strings as a Unix shell would. Here&#8217;s a Python interpreter session demonstrating its usage: &#62;&#62;&#62; import shlex &#62;&#62;&#62; shlex.split&#40;'foo &#34;bar baz&#34; qux'&#41; &#91;'foo', 'bar baz', 'qux'&#93; It&#8217;s useful for creating your own mini-languages or external DSLs that need to parse quoted strings [...]]]></description>
			<content:encoded><![CDATA[<p>Python has a nice module in the standard library called <a href="http://docs.python.org/lib/module-shlex.html">shlex</a> that parses strings as a Unix shell would.  Here&#8217;s a Python interpreter session demonstrating its usage:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">shlex</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #dc143c;">shlex</span>.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'foo &quot;bar baz&quot; qux'</span><span style="color: black;">&#41;</span>
<span style="color: black;">&#91;</span><span style="color: #483d8b;">'foo'</span>, <span style="color: #483d8b;">'bar baz'</span>, <span style="color: #483d8b;">'qux'</span><span style="color: black;">&#93;</span></pre></div></div>

<p>It&#8217;s useful for creating your own mini-languages or <a href="http://www.martinfowler.com/bliki/DomainSpecificLanguage.html">external DSLs</a> that need to parse quoted strings like the one shown above.</p>
<p>We recently built an <a href="http://maintainable.com/case_studies/asset_tracker">inventory tracking</a> application in Ruby that has a user interface for selecting search filters.  To expose the same search capabilities as a web service, we created a simple query language.  I was looking for an <code>shlex</code> equivalent in Ruby.</p>
<p>It turns out that the Ruby Standard Library has a module called <a href="http://ruby-doc.org/core/classes/Shellwords.html">Shellwords</a>:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#006600; font-weight:bold;">&gt;&gt;</span> <span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'shellwords'</span>
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span>
<span style="color:#006600; font-weight:bold;">&gt;&gt;</span> <span style="color:#CC00FF; font-weight:bold;">Shellwords</span>::shellwords<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'foo &quot;bar baz&quot; qux'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;foo&quot;</span>, <span style="color:#996600;">&quot;bar baz&quot;</span>, <span style="color:#996600;">&quot;qux&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span></pre></div></div>

<p><code>Shellwords</code> is a little less capable than <code>shlex</code> but handles the most common use case just fine.  It&#8217;s a convenient solution for a problem that comes up too often.</p>
<p><i><b>Update</b>: Ruby 1.8.7 has <a href="http://svn.ruby-lang.org/repos/ruby/tags/v1_8_7_preview1/NEWS">added</a> the shortcut methods <code>Shellwords.split</code> and <code>String#shellsplit</code>.  Very nice.</i></p>
]]></content:encoded>
			<wfw:commentRss>http://mikenaberezny.com/2008/04/28/parsing-quoted-strings-in-ruby/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Fail Early</title>
		<link>http://mikenaberezny.com/2008/03/25/fail-early/</link>
		<comments>http://mikenaberezny.com/2008/03/25/fail-early/#comments</comments>
		<pubDate>Wed, 26 Mar 2008 02:16:09 +0000</pubDate>
		<dc:creator>Mike Naberezny</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://mikenaberezny.com/2008/03/25/fail-early/</guid>
		<description><![CDATA[I&#8217;m pleased to have been able to contribute a recipe to Mike Clark&#8217;s new book, Advanced Rails Recipes. The concept presented in my recipe, &#8220;Fail Early&#8221;, is that you can use initializers to prevent your application from starting up under certain conditions. Rails applications typically run under persistent application server processes, like mongrel or thin. [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://pragprog.com/titles/fr_arr"><img src="http://mikenaberezny.com/wp-content/uploads/2008/03/advanced_rails_recipes.gif" style="float: right; margin: 5px 5px 5px 10px; padding: 0; border: #dddddd 2px solid;" title="Advanced Rails Recipes" /></a></p>
<p>I&#8217;m pleased to have been able to contribute a recipe to Mike Clark&#8217;s new book, <a href="http://pragprog.com/titles/fr_arr">Advanced Rails Recipes</a>.  The concept presented in my recipe, &#8220;Fail Early&#8221;, is that you can use initializers to prevent your application from starting up under certain conditions.  </p>
<p>Rails applications typically run under persistent application server processes, like <code>mongrel</code> or <code>thin</code>.  When a Rails application starts, it goes through a startup procedure that is performed only once.  The startup includes reading the environment configuration files and running any initializers that have been set up.  This can also be used as an opportunity to detect potentially dangerous situations and bail out.</p>
<p>&#8220;Fail Early&#8221; uses the case of pending migrations to demonstrate.  If the application is started while there are pending migrations for the production database, the results can wreck production data.  Instead, an initializer detects this condition and exits by calling Ruby&#8217;s <code>Kernel.abort</code>.</p>
<p>Here&#8217;s another case where this idea is useful.  It&#8217;s well-known that the Ruby-based MySQL driver included with Rails isn&#8217;t suitable for use in production.  In fact, Rails will produce this warning in the log if it is in use:</p>
<blockquote><p>
WARNING: You&#8217;re using the Ruby-based MySQL library that ships with Rails. This library is not suited for production. Please install the C-based MySQL library instead (gem install mysql).
</p></blockquote>
<p>This can go unnoticed in the log.  Instead, we can write a short initializer that detects this condition and aborts the application start if the production server is misconfigured.</p>
<p><i>config/initializers/check_mysql_driver.rb</i>:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">if</span> RAILS_ENV == <span style="color:#996600;">'production'</span>
  config = <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>.<span style="color:#9900CC;">configurations</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'production'</span><span style="color:#006600; font-weight:bold;">&#93;</span>
  <span style="color:#9966CC; font-weight:bold;">if</span> config<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'adapter'</span><span style="color:#006600; font-weight:bold;">&#93;</span> == <span style="color:#996600;">'mysql'</span> 
    <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>.<span style="color:#9900CC;">require_mysql</span>
    <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#6666ff; font-weight:bold;">Mysql::VERSION</span>.<span style="color:#9900CC;">to_s</span>.<span style="color:#9966CC; font-weight:bold;">include</span>?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'-ruby'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      abort <span style="color:#996600;">&quot;Ruby-based MySQL driver is not suitable for production&quot;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>When the initializer above is run in a production environment that has the Ruby-based MySQL driver instead of the C-based one, startup will be aborted.</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">$ mongrel_rails start -e production
** Starting Mongrel listening at 0.0.0.0:3000
** Starting Rails with production environment...
Ruby-based MySQL driver is not suitable for production
$</pre></div></div>

<p>You can run many other safety checks like this at startup.  Since they will be run only once and not per-request, your application incurs no performance penalty by doing so.</p>
]]></content:encoded>
			<wfw:commentRss>http://mikenaberezny.com/2008/03/25/fail-early/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>New Rails for PHP Developers Website</title>
		<link>http://mikenaberezny.com/2008/02/18/new-rails-for-php-developers-website/</link>
		<comments>http://mikenaberezny.com/2008/02/18/new-rails-for-php-developers-website/#comments</comments>
		<pubDate>Mon, 18 Feb 2008 20:05:34 +0000</pubDate>
		<dc:creator>Mike Naberezny</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://mikenaberezny.com/2008/02/18/new-rails-for-php-developers-website/</guid>
		<description><![CDATA[Rails for PHP Developers is a new website that&#8217;s a companion to the new book by the same name. Like the book, it&#8217;s aimed towards PHP developers who have an interest in Rails and Ruby. The website features articles that alternate between Ruby and PHP focus, so PHP developers that aren&#8217;t interested in Ruby should [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://railsforphp.com"><img src="http://mikenaberezny.com/wp-content/uploads/2008/02/rails_for_php_developers.gif" alt="" title="Rails for PHP Developers" width="470" height="388" class="alignnone size-full wp-image-91" style="border: #000000 1px solid;" /></a><br clear=all></p>
<p><a href="http://railsforphp.com">Rails for PHP Developers</a> is a new website that&#8217;s a companion to the <a href="http://pragprog.com/titles/ndphpr">new book</a> by the same name.  Like the book, it&#8217;s aimed towards PHP developers who have an interest in Rails and Ruby.  The website features articles that alternate between Ruby and PHP focus, so PHP developers that aren&#8217;t interested in Ruby should still find it useful.</p>
]]></content:encoded>
			<wfw:commentRss>http://mikenaberezny.com/2008/02/18/new-rails-for-php-developers-website/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rails Hackfest Winner</title>
		<link>http://mikenaberezny.com/2007/12/05/rails-hackfest-winner/</link>
		<comments>http://mikenaberezny.com/2007/12/05/rails-hackfest-winner/#comments</comments>
		<pubDate>Thu, 06 Dec 2007 04:50:43 +0000</pubDate>
		<dc:creator>Mike Naberezny</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://mikenaberezny.com/archives/85</guid>
		<description><![CDATA[I was pleased to learn today that I am a winner in the Rails Hackfest. The Hackfest is a contest where your ranking is primarily determined by how many of your patches get accepted into Rails core during the contest month.]]></description>
			<content:encoded><![CDATA[<p><img src="/images/novhackfestres.gif" /></p>
<p>I was pleased to learn today that I am a winner in the <a href="http://www.workingwithrails.com/hackfest/17-monthly-november-2-7">Rails Hackfest</a>. </p>
<p>The Hackfest is a contest where your ranking is primarily <a href="http://www.workingwithrails.com/hackfest/scoring">determined</a> by how many of your patches get accepted into Rails core during the contest month.  </p>
]]></content:encoded>
			<wfw:commentRss>http://mikenaberezny.com/2007/12/05/rails-hackfest-winner/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Keep the Flash and Test it, too.</title>
		<link>http://mikenaberezny.com/2007/09/08/keep-the-flash-and-test-it-too/</link>
		<comments>http://mikenaberezny.com/2007/09/08/keep-the-flash-and-test-it-too/#comments</comments>
		<pubDate>Sun, 09 Sep 2007 01:45:56 +0000</pubDate>
		<dc:creator>Mike Naberezny</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[maintainable]]></category>

		<guid isPermaLink="false">http://mikenaberezny.com/archives/81</guid>
		<description><![CDATA[The flash in Ruby on Rails is a special hash that is stored in the session. Its contents are available to the next request and cleared out immediately after. This makes is very useful one-time events, such as an item being added to a shopping cart: flash&#91;:success&#93; = &#34;#{cart.items.size} items added to your cart.&#34; The [...]]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://api.rubyonrails.org/classes/ActionController/Flash.html"><code>flash</code></a> in Ruby on Rails is a special hash that is stored in the session.  Its contents are available to the next request and cleared out immediately after.  </p>
<p>This makes is very useful one-time events, such as an item being added to a shopping cart:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">flash<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:success</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#996600;">&quot;#{cart.items.size} items added to your cart.&quot;</span></pre></div></div>

<p>The <code>flash[:success]</code> will be available for the next request only.</p>
<p>However, Ajax requests will also clear the flash.  This can lead to the sometimes mysterious problem of the flash contents disappearing before their intended request because an intermediate Ajax request caused them to be cleared.</p>
<p>The solution is to explicitly preserve the flash contents in actions that could unintentionally clear it.  This is done using <a href="http://api.rubyonrails.org/classes/ActionController/Flash/FlashHash.html#M000169"><code>flash.keep</code></a>:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">flash.<span style="color:#9900CC;">keep</span></pre></div></div>

<p>The current contents of the flash will then be preserved for the next request.  You can also pass a specific key such as <code>flash.keep(:foo)</code>.</p>
<p>On one <a href="http://maintainable.com/case_studies/etp">application</a> I work on, we make Ajax requests periodically on a timer.  Putting <code>flash.keep</code> in these Ajax actions was a simple way to make sure they didn&#8217;t unexpectedly gobble the flash contents.</p>
<p>Of course, once adding <code>flash.keep</code>, we also want to add a functional test for it.  You might try doing this:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> test_something_keeps_flash
  <span style="color:#0066ff; font-weight:bold;">@request</span>.<span style="color:#9900CC;">flash</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:foo</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#996600;">'bar'</span>
  xhr <span style="color:#ff3333; font-weight:bold;">:get</span>, <span style="color:#ff3333; font-weight:bold;">:something</span>
  assert_response <span style="color:#ff3333; font-weight:bold;">:success</span>
  assert_equal <span style="color:#996600;">'bar'</span>, <span style="color:#0066ff; font-weight:bold;">@response</span>.<span style="color:#9900CC;">flash</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:foo</span><span style="color:#006600; font-weight:bold;">&#93;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>You&#8217;d be close but wrong.  That would seem like a natural way to do it but unfortunately, the flash can&#8217;t be populated that way due to how <code>TestRequest</code> was built.  It doesn&#8217;t have a <code>flash</code> attribute and the session doesn&#8217;t have a <code>FlashHash</code>.  However, that won&#8217;t stop us from writing our test.</p>
<p>We could try monkeypatching but I try to avoid clever things like that.  This problem is easily remedied with a helper in <code>test_helper.rb</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> make_flash_hash<span style="color:#006600; font-weight:bold;">&#40;</span>with_contents = <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  returning <span style="color:#6666ff; font-weight:bold;">ActionController::Flash::FlashHash</span>.<span style="color:#9900CC;">new</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>flash_hash<span style="color:#006600; font-weight:bold;">|</span>
    flash_hash.<span style="color:#9900CC;">update</span> with_contents
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Our test case now can now use the simple <code>make_flash_hash</code> helper to populate the request&#8217;s session with flash:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> test_something_keeps_flash
  <span style="color:#0066ff; font-weight:bold;">@request</span>.<span style="color:#9900CC;">session</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'flash'</span><span style="color:#006600; font-weight:bold;">&#93;</span> = make_flash_hash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:foo</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'bar'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  xhr <span style="color:#ff3333; font-weight:bold;">:get</span>, <span style="color:#ff3333; font-weight:bold;">:something</span>
  assert_response <span style="color:#ff3333; font-weight:bold;">:success</span>
  assert_equal <span style="color:#996600;">'bar'</span>, <span style="color:#0066ff; font-weight:bold;">@response</span>.<span style="color:#9900CC;">flash</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:foo</span><span style="color:#006600; font-weight:bold;">&#93;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>In addition to using <code>@request.session</code> as shown above, you could also populate the session in the <code>xhr</code> method directly.  I like the former for readability.</p>
<p>Whichever way you choose to do it, writing the functional test will ensure that you&#8217;ll continue to preserve the flash when the application changes later.</p>
]]></content:encoded>
			<wfw:commentRss>http://mikenaberezny.com/2007/09/08/keep-the-flash-and-test-it-too/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Faster TDD with Stakeout.rb</title>
		<link>http://mikenaberezny.com/2007/09/04/faster-tdd-with-stakeout-rb/</link>
		<comments>http://mikenaberezny.com/2007/09/04/faster-tdd-with-stakeout-rb/#comments</comments>
		<pubDate>Tue, 04 Sep 2007 16:45:04 +0000</pubDate>
		<dc:creator>Mike Naberezny</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[phpunit]]></category>

		<guid isPermaLink="false">http://mikenaberezny.com/archives/78</guid>
		<description><![CDATA[I&#8217;m a big fan of Autotest and it runs almost constantly on my machine. Autotest automatically reruns your tests whenever your files change. Instead of constantly flipping to another shell to rerun your tests, just let Autotest cheerfully do it for you in the background. It&#8217;s highly addictive. The only problem with Autotest is that [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m a big fan of <a href="http://maintainable.com/articles/dry_up_testing_with_autotest">Autotest</a> and it runs almost constantly on my machine.  Autotest automatically reruns your tests whenever your files change.  Instead of constantly flipping to another shell to rerun your tests, just let Autotest cheerfully do it for you in the background.  It&#8217;s highly addictive.</p>
<p>The only problem with Autotest is that it is specific to Ruby.  At <a href="http://maintainable.com">work</a>, I do a mix of different kinds of programming including Ruby, PHP, Python, and C.  I&#8217;d like my TDD to be accelerated for all of these languages.</p>
<p>Thanks to <a href="http://nubyonrails.com/articles/automation-with-rstakeout">Geoffrey Grossenbach</a>, last week I came across <a href="http://www.pragmaticautomation.com/cgi-bin/pragauto.cgi/Monitor/StakingOutFileChanges.rdoc">stakeout.rb</a> from <a href="http://clarkware.com/cgi/blosxom">Mike Clark</a>.  This is a tiny, dead simple Ruby script that runs an arbitrary command when certain files change.  This is a stripped-down Autotest for everybody else.  I&#8217;m sure it has all kinds of other uses as well.</p>
<p>To get started testing with <code>stakeout.rb</code>, you&#8217;ll need <a href"http://www.ruby-lang.org/">Ruby</a> installed.  Any recent version is fine and you might already have it installed.  Next, grab the <a href="http://www.pragmaticautomation.com/cgi-bin/pragauto.cgi/Monitor/StakingOutFileChanges.rdoc">stakeout.rb</a> script and add the <a href="http://en.wikipedia.org/wiki/Shebang_%28Unix%29">shebang</a> line to the top (Unix-like OS assumed):</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;">#!/usr/bin/env ruby -w</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">if</span> ARGV.<span style="color:#9900CC;">size</span> <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#006666;">2</span>
  <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;Usage: stakeout.rb &lt;command&gt; [files to watch]+&quot;</span>
...</pre></div></div>

<p>Make the file executable and put it somewhere in your <code>PATH</code>.  You can test it out by typing <code>stakeout.rb</code> from an arbitrary directory and you should see the help message.</p>
<p>Next, change over to a project directory where you have some test files.  Most of the projects that I am involved with tend to use some directory structure similar to this:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">/project_name
  /lib
  /test
  ...</pre></div></div>

<p>To test such a project, run <code>stakeout.rb</code> from the <code>/project_name</code> directory.  Most PHP projects using PHPUnit tend to have an <code>AllTests.php</code> file or equivalent to run all the tests, so we&#8217;ll assume this for the example:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">project_name$ stakeout.rb &quot;php test/AllTests.php&quot; **/*</pre></div></div>

<p>The first argument is what command to run when the tests change.  The second argument, and any subsequent arguments, are the files to watch for changes.  These can use a Ruby <a href="http://www.ruby-doc.org/core/classes/Dir.html#M002347">globbing pattern</a>.  The pattern <code>**/*</code> will watch all files under <code>project_name</code> recursively, which includes <code>lib/</code> and <code>test/</code>.</p>
<p>Once <code>stakeout.rb</code> is run, it will show no output but will sit and wait for changes.  As soon as you change a watched file, <code>stakeout.rb</code> will automatically rerun you tests and will continue to do so until you exit with Control-C.</p>
]]></content:encoded>
			<wfw:commentRss>http://mikenaberezny.com/2007/09/04/faster-tdd-with-stakeout-rb/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>New RubyOSA Website</title>
		<link>http://mikenaberezny.com/2007/04/12/new-rubyosa-website/</link>
		<comments>http://mikenaberezny.com/2007/04/12/new-rubyosa-website/#comments</comments>
		<pubDate>Thu, 12 Apr 2007 16:19:44 +0000</pubDate>
		<dc:creator>Mike Naberezny</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://mikenaberezny.com/archives/72</guid>
		<description><![CDATA[RubyOSA now has a new website! It has a fresh look thanks to Derek DeVries and the Maintainable design team: The new site features updated information from Laurent and I, including a new guide. Over the coming weeks, we&#8217;ll continue to expand and improve its content. Please let us know what you think about it! [...]]]></description>
			<content:encoded><![CDATA[<p>RubyOSA now has a <a href="http://rubyosa.rubyforge.org">new website</a>!  It has a fresh look thanks to Derek DeVries and the <a href="http://maintainable.com">Maintainable</a> design team:    </p>
<p><a href="http://rubyosa.rubyforge.org/"><img src="http://mikenaberezny.com/wp-content/uploads/2008/12/rubyosa-website.jpg" alt="" title="RubyOSA Website" width="410" height="370" class="alignnone size-full wp-image-776" style="border: #000000 1px solid;" /></a></p>
<p>The new site features updated information from <a href="http://www.chopine.be/lrz/">Laurent</a> and I, including a new guide.  Over the coming weeks, we&#8217;ll continue to expand and improve its content.</p>
<p>Please let us know what you think about it!</p>
<p><b>Update</b>: <i>This post was featured on <a href="http://chopine.be/lrz/diary/2007-04-12_RubyOSA-0-4-0.html">Laurent Sansonetti&#8217;s diary</a>.</i></p>
]]></content:encoded>
			<wfw:commentRss>http://mikenaberezny.com/2007/04/12/new-rubyosa-website/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>OSA::ObjectSpecifierList#every</title>
		<link>http://mikenaberezny.com/2007/03/26/osaobjectspecifierlistevery/</link>
		<comments>http://mikenaberezny.com/2007/03/26/osaobjectspecifierlistevery/#comments</comments>
		<pubDate>Tue, 27 Mar 2007 05:22:25 +0000</pubDate>
		<dc:creator>Mike Naberezny</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://mikenaberezny.com/archives/71</guid>
		<description><![CDATA[For those of you who aren&#8217;t yet on the RubyOSA list (you should be), Laurent just committed a nice new feature to OSA::ObjectSpecifierList. It&#8217;s actually been there since last week, in the form of some method_missing hackery, but we finally decided to take that out and call it #every. Sometimes you need to collect an [...]]]></description>
			<content:encoded><![CDATA[<p>For those of you who aren&#8217;t yet on the <a href="http://rubyforge.org/mail/?group_id=1845">RubyOSA list</a> (you should be), <a href="http://www.chopine.be/lrz/diary/">Laurent</a> just committed a nice new feature to <code>OSA::ObjectSpecifierList</code>.  It&#8217;s actually been there since last week, in the form of some <code>method_missing</code> hackery, but we finally decided to take that out and call it <code>#every</code>.</p>
<p>Sometimes you need to collect an attribute from every object in the specifier list.  Normally, you&#8217;d do something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">names = OSA.<span style="color:#9900CC;">app</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'iCal'</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">calendars</span>.<span style="color:#9900CC;">collect</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>c<span style="color:#006600; font-weight:bold;">|</span> c.<span style="color:#9900CC;">name</span> <span style="color:#006600; font-weight:bold;">&#125;</span></pre></div></div>

<p><a href="http://pragdave.pragprog.com/pragdave/2005/11/symbolto_proc.html">Symbol#to_proc</a> <a href="http://redhanded.hobix.com/cult/symbolTo_procExonerated.html">fans</a> use the convenient form:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">names = OSA.<span style="color:#9900CC;">app</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'iCal'</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">calendars</span>.<span style="color:#9900CC;">collect</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&amp;</span>:name<span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>Now, <code>OSA::ObjectSpecifierList</code> also has the <code>#every</code> method:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">names = OSA.<span style="color:#9900CC;">app</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'iCal'</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">calendars</span>.<span style="color:#9900CC;">every</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:name</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>The difference is subtle but <code>#every</code> will fetch all of the attributes in a single Apple Event, something not possible when iterating over each item in the collection.  For most purposes this is not important but it is a nice feature that could make a difference on larger collections.</p>
<p>This feature is currently in the <a href="http://rubyforge.org/projects/rubyosa">RubyOSA</a> trunk and will appear in the next stable release (coming soon).</p>
<p><b>Update</b>: <i>RubyOSA 4.0 has been <a href="http://www.chopine.be/lrz/diary/2007-04-12_RubyOSA-0-4-0.html">released</a> and includes this feature!</i></p>
]]></content:encoded>
			<wfw:commentRss>http://mikenaberezny.com/2007/03/26/osaobjectspecifierlistevery/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DRY up testing in Rails with Autotest</title>
		<link>http://mikenaberezny.com/2007/03/23/dry-up-testing-in-rails-with-autotest/</link>
		<comments>http://mikenaberezny.com/2007/03/23/dry-up-testing-in-rails-with-autotest/#comments</comments>
		<pubDate>Sat, 24 Mar 2007 04:03:20 +0000</pubDate>
		<dc:creator>Mike Naberezny</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[maintainable]]></category>

		<guid isPermaLink="false">http://mikenaberezny.com/2007/03/02/dry-up-testing-in-rails-with-autotest-2/</guid>
		<description><![CDATA[Autotest will DRY up testing your Rails application by running your tests automatically whenever your files change. We'll explore installing, using, and extending the Autotest utility from ZenTest.]]></description>
			<content:encoded><![CDATA[<p>As Rails developers, we&#8217;ve been trained hard to test early and test often. We are also acutely aware of the DRY principle (Don&#8217;t Repeat Yourself). However, these ideas don&#8217;t quite agree in Rails because in our test-code-test cycle, we&#8217;re constantly typing <code>rake</code> every time we need to run our tests.</p>
<p>Autotest will DRY up your testing by running your tests automatically whenever your files change. In this article, we&#8217;ll explore Autotest: </p>
<ul>
<li><a href="#installation">Installation</a></li>
<li><a href="#starting-autotest">Starting Autotest</a></li>
<li><a href="#stopping-autotest">Stopping Autotest</a></li>
<li><a href="#autotest-plugins">Autotest Plugins</a></li>
<li><a href="#coloring-with-redgreen">Coloring with RedGreen</a></li>
<li><a href="#notifications">Notifications</a></li>
<li><a href="#next-steps">Next Steps</a></li>
</ul>
<h2 id="installation">Installation</h2>
<p>Autotest is a smart little program included in the ZenTest bundle of goodies. To install it, you&#8217;ll just need to install the gem for ZenTest.</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">gem install ZenTest</pre></div></div>

<p>Depending on how your system is set up, you might need to run this as the root user or through <code>sudo</code>. </p>
<h2 id="starting-autotest">Starting Autotest</h2>
<p>Running Autotest is as simple as running rake. First, change to the root directory of your Rails project. This is the directory that has <code>Rakefile</code>, <code>app/</code>, <code>config/</code>, etc. Next, run the <code>autotest</code> command:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">$ autotest</pre></div></div>

<p>Autotest will discover that it is running inside a Rails project and your tests will run just as they do with <code>rake</code> (or the wordier <code>rake test</code>).</p>
<p>After your tests run, Autotest will not exit back to the shell prompt. It will then sit and poll your files. When it notices files that change, it will run the tests for only the files that you&#8217;ve changed! It will do this continuously until you stop it. </p>
<h2 id="stopping-autotest">Stopping Autotest</h2>
<p>Pressing <code>Control-C</code> once will run your entire test suite again.</p>
<p>Pressing <code>Control-C</code> twice in quick succession will exit Autotest back to the shell prompt. </p>
<h2 id="autotest-plugins">Autotest Plugins</h2>
<p>Autotest includes a plugin mechanism that allows plugins to monitor different aspects of the testing lifecycle. Autotest includes a number of useful plugins out of the box.</p>
<p>In the next sections, we&#8217;ll see how to activate the plugins and what functionality they provide. </p>
<h2 id="coloring-with-redgreen">Coloring with RedGreen</h2>
<p>One of the problems of testing under <code>rake</code> and <code>autotest</code> is that a lot of output can be generated and when looking at the results, you sometimes have to filter out the normal output to see the failures.</p>
<p>RedGreen is a simple Autotest plugin that solves this problem by coloring the summary lines of the test output either red or green to indicate whether the tests passed or failed: </p>
<p><img src='http://mikenaberezny.com/wp-content/uploads/2008/02/redgreen.gif' alt='Red/Green for Autotest' /></p>
<p>Autotest automatically looks for a dotfile (<code>.autotest</code>) when it is started. This file may be in your Rails project directory or in your home directory where it will be used by all projects.</p>
<p>To install RedGreen or any other plugin, create the <code>.autotest</code> file with a simple <code>require</code> to load the plugin:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;"># .autotest</span>
&nbsp;
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'autotest/redgreen'</span></pre></div></div>

<p>That&#8217;s it! When you run autotest again, the plugin will be automatically loaded and your test output colored. </p>
<h2 id="notifications">Notifications</h2>
<p>Autotest also comes with the plugins <code>growl</code>, <code>snarl</code>, and <code>kdenotify</code>. Each are installed the same way as shown above, simply add the require line to your <code>.autotest</code> file. These allow Autotest to communicate each respective notification system. </p>
<p><img src='http://mikenaberezny.com/wp-content/uploads/2008/02/growl.gif' alt='Growl for Autotest' /></p>
<p>Using one of these can be useful when running autotest in the background or in a minimized window. The screenshot above shows a Growl pop-up notification from Autotest under Mac OS X.</p>
<p>Note that for Autotest to send notifications to Growl, the <code>growlnotify</code> utility must be installed. This comes in the <code>Extras/</code> directory of the Growl disk image. </p>
<h2 id="next-steps">Next Steps</h2>
<p>Autotest isn&#8217;t limited to plugins shown here. There are a number of other useful plugins you can explore and more are added all the time. The plugins can be found in <code>/path/to/your/gems/ZenTest-x.x.x/lib/autotest</code>.</p>
<p>While Autotest can be an invaluable tool when testing Rails applications, it isn&#8217;t limited to Rails at all. Autotest can be used with an Ruby project that follows some simple conventions.</p>
<p>Visit the Autotest section of the <a href="http://zentest.rubyforge.org/ZenTest/">ZenTest RDoc</a> to learn about this, writing plugins, and more. </p>
<p><b>Update</b>: <i>This article was featured on <a href="http://blog.zenspider.com/2007/04/maintainable-software-dry-up-t.html">Ryan Davis&#8217; blog</a></i>.</p>
]]></content:encoded>
			<wfw:commentRss>http://mikenaberezny.com/2007/03/23/dry-up-testing-in-rails-with-autotest/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

