<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Virtuous Code</title>
	
	<link>http://avdi.org/devblog</link>
	<description>"...the three great virtues of a programmer: laziness, impatience, and hubris." -- Larry Wall</description>
	<lastBuildDate>Wed, 18 Aug 2010 04:20:33 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/us/</creativeCommons:license>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/VirtuousCode" /><feedburner:info uri="virtuouscode" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>VirtuousCode</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><item>
		<title>ANN FireTower 0.0.4</title>
		<link>http://feedproxy.google.com/~r/VirtuousCode/~3/RYR_J3Evl6I/</link>
		<comments>http://avdi.org/devblog/2010/08/17/ann-firetower-0-0-4-2/#comments</comments>
		<pubDate>Tue, 17 Aug 2010 23:11:21 +0000</pubDate>
		<dc:creator>avdi</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://avdi.org/devblog/?p=790</guid>
		<description><![CDATA[For those of you using Campfire to communicate with your team, FireTower 0.0.4 is now out. New in this version is full Mac OSX support, courtesy of David T. Rogers. Install: gem install firetower Enjoy!]]></description>
			<content:encoded><![CDATA[<p>For those of you using Campfire to communicate with your team, FireTower 0.0.4 is now out. New in this version is full Mac OSX support, courtesy of <a href="http://github.com/davidtrogers">David T. Rogers</a>.</p>
<p>Install:</p>
<pre><code>gem install firetower
</code></pre>
<p>Enjoy!</p>

<p><a href="http://feedads.g.doubleclick.net/~a/Xq_5HXlnCH6fuBuq9I1q063tKhc/0/da"><img src="http://feedads.g.doubleclick.net/~a/Xq_5HXlnCH6fuBuq9I1q063tKhc/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/Xq_5HXlnCH6fuBuq9I1q063tKhc/1/da"><img src="http://feedads.g.doubleclick.net/~a/Xq_5HXlnCH6fuBuq9I1q063tKhc/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=RYR_J3Evl6I:V_-ASXgeaL0:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=RYR_J3Evl6I:V_-ASXgeaL0:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?i=RYR_J3Evl6I:V_-ASXgeaL0:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=RYR_J3Evl6I:V_-ASXgeaL0:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?i=RYR_J3Evl6I:V_-ASXgeaL0:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=RYR_J3Evl6I:V_-ASXgeaL0:cGdyc7Q-1BI"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?d=cGdyc7Q-1BI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=RYR_J3Evl6I:V_-ASXgeaL0:bcOpcFrp8Mo"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?d=bcOpcFrp8Mo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/VirtuousCode/~4/RYR_J3Evl6I" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://avdi.org/devblog/2010/08/17/ann-firetower-0-0-4-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/us/</creativeCommons:license>
	<feedburner:origLink>http://avdi.org/devblog/2010/08/17/ann-firetower-0-0-4-2/</feedburner:origLink></item>
		<item>
		<title>Treating Arrays as Sets</title>
		<link>http://feedproxy.google.com/~r/VirtuousCode/~3/CkRJWu-4I2M/</link>
		<comments>http://avdi.org/devblog/2010/08/17/treating-arrays-as-sets/#comments</comments>
		<pubDate>Tue, 17 Aug 2010 12:55:20 +0000</pubDate>
		<dc:creator>avdi</dc:creator>
				<category><![CDATA[Howto]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[arrays]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://avdi.org/devblog/?p=782</guid>
		<description><![CDATA[Reading through the Rake source code the other day (a pastime I highly recommend), I was reminded of a technique I don&#8217;t use often enough: my_array = [:foo, :bar, :baz] my_array &#124;= [:baz, :buz] => [:foo, :bar, :baz, :buz] Note that&#8217;s a single pipe before the equals sign. The code above adds only unique elements [...]]]></description>
			<content:encoded><![CDATA[<p>Reading through the Rake source code the other day (a pastime I highly recommend), I was reminded of a technique I don&#8217;t use often enough:</p>
<pre name="code" class="ruby">
my_array = [:foo, :bar, :baz]
my_array |= [:baz, :buz] => [:foo, :bar, :baz, :buz]
</pre>
<p>Note that&#8217;s a single pipe before the equals sign.</p>
<p>The code above adds only unique elements to the array; duplicates are ignored. Ruby Arrays actually implement a small collection of set operations with the <code>&#038;</code>, <code>|</code> operators. Of course, for serious set needs you can use Ruby&#8217;s <code>Set, but </code><code>|=</code> is handy for uniquely appending to an array.</p>
<p>Hey, do you enjoy Virtuous Code? Do you enjoy Netflix, internet video, radio, and podcasts? How would you like to help me out and get yourself a<a href="http://roku.tellapal.com/a/clk/sy3L5"> sweet deal on a Roku player</a> at the same time?</p>
<p>If you <a href="http://roku.tellapal.com/a/clk/sy3L5">click this link</a> you&#8217;ll get a 10% discount on a Roku player, and I&#8217;ll get a free month of Netflix. I&#8217;m being completely honest when I say our Roku box was the best $99 I&#8217;ve ever spent on an electronic device. Unlike so many devices that go obsolete after a Year, Roku has been steadily adding capabilities to it &#8211; first HD video, then a myriad of channels including Netflix, Amazon Unbox, Network news video, the NASA channel, university lectures, Pandora, podcasts, and much more. If you want a simple set-top box to put he internet in your TV, it doesn&#8217;t get much better than the <a href="http://roku.tellapal.com/a/clk/sy3L5">Roku</a>.</p>

<p><a href="http://feedads.g.doubleclick.net/~a/F8iosPGaooFzCPw6HwIEblX_cZA/0/da"><img src="http://feedads.g.doubleclick.net/~a/F8iosPGaooFzCPw6HwIEblX_cZA/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/F8iosPGaooFzCPw6HwIEblX_cZA/1/da"><img src="http://feedads.g.doubleclick.net/~a/F8iosPGaooFzCPw6HwIEblX_cZA/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=CkRJWu-4I2M:hgBIus5nDTw:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=CkRJWu-4I2M:hgBIus5nDTw:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?i=CkRJWu-4I2M:hgBIus5nDTw:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=CkRJWu-4I2M:hgBIus5nDTw:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?i=CkRJWu-4I2M:hgBIus5nDTw:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=CkRJWu-4I2M:hgBIus5nDTw:cGdyc7Q-1BI"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?d=cGdyc7Q-1BI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=CkRJWu-4I2M:hgBIus5nDTw:bcOpcFrp8Mo"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?d=bcOpcFrp8Mo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/VirtuousCode/~4/CkRJWu-4I2M" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://avdi.org/devblog/2010/08/17/treating-arrays-as-sets/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/us/</creativeCommons:license>
	<feedburner:origLink>http://avdi.org/devblog/2010/08/17/treating-arrays-as-sets/</feedburner:origLink></item>
		<item>
		<title>Using Hashes as Caches</title>
		<link>http://feedproxy.google.com/~r/VirtuousCode/~3/eO0SodtME1w/</link>
		<comments>http://avdi.org/devblog/2010/08/05/using-hashes-as-caches/#comments</comments>
		<pubDate>Thu, 05 Aug 2010 18:21:31 +0000</pubDate>
		<dc:creator>avdi</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[caching]]></category>
		<category><![CDATA[hash]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://avdi.org/devblog/?p=764</guid>
		<description><![CDATA[One of the coolest features of Ruby&#8217;s Hash class is that you can customize how it behaves when it can&#8217;t find a key. Stupid example: # Everybody knows that you can communicate with foreigners by # speaking loudly and slowly english_to_french = Hash.new{&#124;hash, key&#124; hash[key] = key.upcase.split(//).join(" ") + "?!" } english_to_french["restroom"] # => "R [...]]]></description>
			<content:encoded><![CDATA[<p>One of the coolest features of Ruby&#8217;s <a href="http://ruby-doc.org/core/classes/Hash.html">Hash</a> class is that you can customize how it behaves when it can&#8217;t find a key. Stupid example:</p>
<pre name="code" class="ruby">
# Everybody knows that you can communicate with foreigners by
# speaking loudly and slowly
english_to_french = Hash.new{|hash, key|
  hash[key] = key.upcase.split(//).join(" ") + "?!"
}
english_to_french["restroom"]   # => "R E S T R O O M?!"
</pre>
<p>One particularly useful application of this feature is to use a Hash as a cache for some slow operation. Here&#8217;s a snippet from <a href="http://avdi.org/devblog/2010/07/11/announcing-firetower-a-command-line-interface-to-campfire/">Firetower</a>, where a Hash is being used as a table of user accounts. If an unknown user ID is requested, the Hash makes a web service call to retrieve the requested data, stores it away, and returns it.</p>
<pre name="code" class="ruby">
      @users = Hash.new do |cache, user_id|
        data = session.get(subdomain, "/users/#{user_id}.json")
        cache[user_id] = data['user']
      end
</pre>

<p><a href="http://feedads.g.doubleclick.net/~a/z1RpHys2yZkkXI3sUFADEWyhKZA/0/da"><img src="http://feedads.g.doubleclick.net/~a/z1RpHys2yZkkXI3sUFADEWyhKZA/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/z1RpHys2yZkkXI3sUFADEWyhKZA/1/da"><img src="http://feedads.g.doubleclick.net/~a/z1RpHys2yZkkXI3sUFADEWyhKZA/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=eO0SodtME1w:d12exZSR5lI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=eO0SodtME1w:d12exZSR5lI:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?i=eO0SodtME1w:d12exZSR5lI:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=eO0SodtME1w:d12exZSR5lI:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?i=eO0SodtME1w:d12exZSR5lI:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=eO0SodtME1w:d12exZSR5lI:cGdyc7Q-1BI"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?d=cGdyc7Q-1BI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=eO0SodtME1w:d12exZSR5lI:bcOpcFrp8Mo"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?d=bcOpcFrp8Mo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/VirtuousCode/~4/eO0SodtME1w" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://avdi.org/devblog/2010/08/05/using-hashes-as-caches/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/us/</creativeCommons:license>
	<feedburner:origLink>http://avdi.org/devblog/2010/08/05/using-hashes-as-caches/</feedburner:origLink></item>
		<item>
		<title>“and” and “or” are like backwards statement modifiers</title>
		<link>http://feedproxy.google.com/~r/VirtuousCode/~3/-DYOIrMiViA/</link>
		<comments>http://avdi.org/devblog/2010/08/03/and-and-or-are-like-backwards-statement-modifiers/#comments</comments>
		<pubDate>Tue, 03 Aug 2010 14:42:27 +0000</pubDate>
		<dc:creator>avdi</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[operators]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://avdi.org/devblog/?p=773</guid>
		<description><![CDATA[It occurred to me after reviewing all the feedback to my last post that despite making the connection to statement modifiers, I never directly contrasted the two. And that this might be an even simpler way of explaining the usefulness of and/or in Ruby. I&#8217;ve added the following examples to the original post, but in [...]]]></description>
			<content:encoded><![CDATA[<p>It occurred to me after reviewing all the feedback to <a href="http://avdi.org/devblog/2010/08/02/using-and-and-or-in-ruby/">my last post</a> that despite making the connection to statement modifiers, I never directly contrasted the two. And that this might be an even simpler way of explaining the usefulness of <code>and</code>/<code>or</code> in Ruby. I&#8217;ve added the following examples to the original post, but in case you missed it:</p>
<h3><code>and</code></h3>
<p>You can think of <code>and</code> is as a reversed <code>if</code> statement modifier:</p>
<pre name="code" class="ruby">
  next if widget = widgets.pop
</pre>
<p>becomes:</p>
<pre name="code" class="ruby">
  widget = widgets.pop and next
</pre>
<p>Because of the low precedence of <code>and</code>, no extra parentheses are needed here as they would be for <code>&#038;&#038;</code>.</p>
<h3><code>or</code></h3>
<p>Likewise, <code>or</code> is a reversed <code>unless</code> statement modifier:</p>
<pre name="code" class="ruby">
  raise "Not ready!" unless ready_to_rock?
</pre>
<p>becomes:</p>
<pre name="code" class="ruby">
  ready_to_rock? or raise "Not ready!"
</pre>
<h3>Conclusion</h3>
<p>Which version to use &#8211; if/unless or and/or &#8211; depends on your taste and what reads well in a given case. But it&#8217;s nice to have the option.</p>
<p><br/><script type="text/javascript"><!--
google_ad_client = "pub-6820402738462489";
/* InlinePost */
google_ad_slot = "0165803319";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></p>

<p><a href="http://feedads.g.doubleclick.net/~a/_43R6JaZrJ-C70UrDLKGp4xl5Yk/0/da"><img src="http://feedads.g.doubleclick.net/~a/_43R6JaZrJ-C70UrDLKGp4xl5Yk/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/_43R6JaZrJ-C70UrDLKGp4xl5Yk/1/da"><img src="http://feedads.g.doubleclick.net/~a/_43R6JaZrJ-C70UrDLKGp4xl5Yk/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=-DYOIrMiViA:1pMvl-E4UK0:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=-DYOIrMiViA:1pMvl-E4UK0:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?i=-DYOIrMiViA:1pMvl-E4UK0:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=-DYOIrMiViA:1pMvl-E4UK0:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?i=-DYOIrMiViA:1pMvl-E4UK0:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=-DYOIrMiViA:1pMvl-E4UK0:cGdyc7Q-1BI"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?d=cGdyc7Q-1BI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=-DYOIrMiViA:1pMvl-E4UK0:bcOpcFrp8Mo"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?d=bcOpcFrp8Mo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/VirtuousCode/~4/-DYOIrMiViA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://avdi.org/devblog/2010/08/03/and-and-or-are-like-backwards-statement-modifiers/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/us/</creativeCommons:license>
	<feedburner:origLink>http://avdi.org/devblog/2010/08/03/and-and-or-are-like-backwards-statement-modifiers/</feedburner:origLink></item>
		<item>
		<title>Using “and” and “or” in Ruby</title>
		<link>http://feedproxy.google.com/~r/VirtuousCode/~3/dr4u7u_FMn0/</link>
		<comments>http://avdi.org/devblog/2010/08/02/using-and-and-or-in-ruby/#comments</comments>
		<pubDate>Mon, 02 Aug 2010 14:32:32 +0000</pubDate>
		<dc:creator>avdi</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[operators]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://avdi.org/devblog/?p=712</guid>
		<description><![CDATA[If you use Ruby long enough, you will discover the and and or operators. These appear at first glance to be synonyms for &#038;&#038; and &#124;&#124;. You will then be tempted to use these English oprators in place of &#038;&#038; and &#124;&#124;, for the sake of improved readability. Assuming you yield to that temptation, you [...]]]></description>
			<content:encoded><![CDATA[<p>If you use Ruby long enough, you will discover the <code>and</code> and <code>or</code> operators. These appear at first glance to be synonyms for <code>&#038;&#038;</code> and <code>||</code>. You will then be tempted to use these English oprators in place of <code>&#038;&#038;</code> and <code>||</code>, for the sake of improved readability.</p>
<p>Assuming you yield to that temptation, you will eventually find yourself rudely surprised that <code>and</code> and <code>or</code> don&#8217;t behave quite like their symbolic kin. Specifically, they have a much lower precedence. At this point, you may decide to swear off the use of <code>and</code> and <code>or</code> as too confusing.</p>
<p>But that would be doing your code a disservice. <code>and</code> and <code>or</code> are useful operators; you just need to understand their special place in Ruby programs.</p>
<p><code>and</code> and <code>or</code> originate (like so much of Ruby) in Perl. In Perl, they were largely used to modify control flow, similar to the <code>if</code> and <code>unless</code> statement modifiers. A common Perl idiom is:</p>
<pre name="code" class="perl">
do_something() or die "It didn't work!";
</pre>
<p>The <code>and</code> and <code>or</code> keywords serve the same purpose in Ruby. Properly understood, <code>and</code> and <code>or</code> are <strong>control flow operators</strong>, not boolean operators.</p>
<h3><code>and</code></h3>
<p><code>and</code>Is useful for chaining related operations together until one of them returns <code>nil</code> or <code>false</code>. For instance:</p>
<pre name="code" class="ruby">
post = Post.find_by_name(name) and post.publish!
</pre>
<p>Here, the post will only be published if it is found, due to the short-circuiting nature of <code>and</code>. How does this differ from <code>&#038;&#038;</code>? Let&#8217;s take a look at an even simpler example:</p>
<pre name="code" class="ruby">
foo = 42 &#038;&#038; foo / 2
</pre>
<p>The intent here is to assign a variable and then divide it by 2. Since we are just assigning a constant value on the left side, both sides of the <code>&#038;&#038;</code> will always be evaluated, right? Let&#8217;s give it a try:</p>
<pre>
NoMethodError: undefined method `/' for nil:NilClass
        from (irb):18
        from :0
</pre>
<p>Was that what you expected? As it turns out, with the relatively high operator precedence of <code>&#038;&#038;</code>, the way that code is actually parsed looks like this:</p>
<pre name="code" class="ruby">
foo = (42 &#038;&#038; foo) / 2
</pre>
<p>&#8230;which is clearly not what we want. Contrast that to the <code>and</code> version:</p>
<pre name="code" class="ruby">
foo = 42 and foo / 2 => 21
</pre>
<p>&#8230;and now we have the answer we were expecting.</p>
<p>Another way of thinking about <code>and</code> is as a reversed <code>if</code> statement modifier:</p>
<pre name="code" class="ruby">
  next if widget = widgets.pop
</pre>
<p>becomes:</p>
<pre name="code" class="ruby">
  widget = widgets.pop and next
</pre>
<h3><code>or</code></h3>
<p><code>or</code>, likewise, is useful for chaining expressions together. The best way to think about the chains constructed with <code>or</code> is as series of fallbacks: try <em>this</em>, if that fails try <em>this</em>, and so on. For instance:</p>
<pre name="code" class="ruby">
  foo = get_foo() or raise "Could not find foo!"
</pre>
<p>You can also look at <code>or</code> as a reversed <code>unless</code> statement modifier:</p>
<pre name="code" class="ruby">
  raise "Not ready!" unless ready_to_rock?
</pre>
<p>becomes:</p>
<pre name="code" class="ruby">
  ready_to_rock? or raise "Not ready!"
</pre>
<h3>Conclusion</h3>
<p><code>and</code> and <code>or</code>, despite an apparent similarity to <code>&#038;&#038;</code> and <code>||</code>, have very different roles. <code>and</code> and <code>or</code> are control-flow modifiers like <code>if</code> and <code>unless</code>. When used in this capacity their low precedence is a virtue rather than an annoyance.</p>
<p>UPDATE: Simplified and clarified some examples based on feedback; added comparisons to <code>if</code>/<code>unless</code> statement modifiers.</p>
<p>UPDATE 2: Preston Lee delivers a <a href="http://www.prestonlee.com/2010/08/04/ruby-on-the-perl-origins-of-and-versus-and-and-or/">much more thorough history lesson</a> on the Perl origins of these operators.</p>
<p><br/><script type="text/javascript"><!--
google_ad_client = "pub-6820402738462489";
/* InlinePost */
google_ad_slot = "0165803319";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></p>

<p><a href="http://feedads.g.doubleclick.net/~a/ilQmYcOGBQuuF_9PMq_V6eTyUQ8/0/da"><img src="http://feedads.g.doubleclick.net/~a/ilQmYcOGBQuuF_9PMq_V6eTyUQ8/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/ilQmYcOGBQuuF_9PMq_V6eTyUQ8/1/da"><img src="http://feedads.g.doubleclick.net/~a/ilQmYcOGBQuuF_9PMq_V6eTyUQ8/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=dr4u7u_FMn0:x0zGSWaXzAg:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=dr4u7u_FMn0:x0zGSWaXzAg:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?i=dr4u7u_FMn0:x0zGSWaXzAg:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=dr4u7u_FMn0:x0zGSWaXzAg:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?i=dr4u7u_FMn0:x0zGSWaXzAg:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=dr4u7u_FMn0:x0zGSWaXzAg:cGdyc7Q-1BI"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?d=cGdyc7Q-1BI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=dr4u7u_FMn0:x0zGSWaXzAg:bcOpcFrp8Mo"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?d=bcOpcFrp8Mo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/VirtuousCode/~4/dr4u7u_FMn0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://avdi.org/devblog/2010/08/02/using-and-and-or-in-ruby/feed/</wfw:commentRss>
		<slash:comments>58</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/us/</creativeCommons:license>
	<feedburner:origLink>http://avdi.org/devblog/2010/08/02/using-and-and-or-in-ruby/</feedburner:origLink></item>
		<item>
		<title>RPCFN Solution</title>
		<link>http://feedproxy.google.com/~r/VirtuousCode/~3/rtHd5V-ju-c/</link>
		<comments>http://avdi.org/devblog/2010/07/21/rpcfn-solution/#comments</comments>
		<pubDate>Wed, 21 Jul 2010 13:26:24 +0000</pubDate>
		<dc:creator>avdi</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://avdi.org/devblog/?p=733</guid>
		<description><![CDATA[For the curious, my personal reference solution to my Ruby Challenge is now online. More commentary to come later.]]></description>
			<content:encoded><![CDATA[<p>For the curious, my personal reference solution to <a href="http://rubylearning.com/blog/2010/04/29/rpcfn-interactive-fiction-9/">my Ruby Challenge</a> is now <a href="http://github.com/avdi/rpcfn-interactive-fiction/blob/solution/bin/play.rb">online</a>. More commentary to come later.</p>

<p><a href="http://feedads.g.doubleclick.net/~a/yQj0LHTFLJkaBZsa060bDRNvOuk/0/da"><img src="http://feedads.g.doubleclick.net/~a/yQj0LHTFLJkaBZsa060bDRNvOuk/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/yQj0LHTFLJkaBZsa060bDRNvOuk/1/da"><img src="http://feedads.g.doubleclick.net/~a/yQj0LHTFLJkaBZsa060bDRNvOuk/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=rtHd5V-ju-c:vH_xxFM9KzA:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=rtHd5V-ju-c:vH_xxFM9KzA:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?i=rtHd5V-ju-c:vH_xxFM9KzA:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=rtHd5V-ju-c:vH_xxFM9KzA:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?i=rtHd5V-ju-c:vH_xxFM9KzA:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=rtHd5V-ju-c:vH_xxFM9KzA:cGdyc7Q-1BI"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?d=cGdyc7Q-1BI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=rtHd5V-ju-c:vH_xxFM9KzA:bcOpcFrp8Mo"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?d=bcOpcFrp8Mo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/VirtuousCode/~4/rtHd5V-ju-c" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://avdi.org/devblog/2010/07/21/rpcfn-solution/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/us/</creativeCommons:license>
	<feedburner:origLink>http://avdi.org/devblog/2010/07/21/rpcfn-solution/</feedburner:origLink></item>
		<item>
		<title>Greenletters: Painless automation and testing for command-line applications</title>
		<link>http://feedproxy.google.com/~r/VirtuousCode/~3/d9Mth8fhyr8/</link>
		<comments>http://avdi.org/devblog/2010/07/19/greenletters-painless-automation-and-testing-for-command-line-applications/#comments</comments>
		<pubDate>Mon, 19 Jul 2010 15:25:46 +0000</pubDate>
		<dc:creator>avdi</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[automation]]></category>
		<category><![CDATA[cli]]></category>
		<category><![CDATA[console]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[process]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[unix]]></category>

		<guid isPermaLink="false">http://avdi.org/devblog/?p=727</guid>
		<description><![CDATA[Did you ever use Expect to automate a complex command-line procedure, like an FTP upload? Expect is handy &#8211; and very powerful &#8211; but for Ruby projects it sure would be nice to be able to automate console apps directly from Ruby. You may not have known it, but Ruby actually ships with a tiny [...]]]></description>
			<content:encoded><![CDATA[<p><img class="aligncenter size-full wp-image-728" title="539px-IBM-3279" src="http://avdi.org/devblog/wp-content/uploads/2010/07/539px-IBM-3279.jpg" alt="539px-IBM-3279" width="539" height="600" /></p>
<p>Did you ever use <a href="http://directory.fsf.org/project/expect/">Expect</a> to automate a complex command-line procedure, like an FTP upload? Expect is handy &#8211; and very powerful &#8211; but for Ruby projects it sure would be nice to be able to automate console apps directly from Ruby.</p>
<p>You may not have known it, but Ruby actually ships with a tiny Expect clone called <a href="http://koders.com/ruby/fid31E61088C10EBB90329CB14D4306D52041F1F54F.aspx?s=expect.rb#L2">expect.rb</a>. Unfortunately it&#8217;s more of a proof of concept than a fully functional automation tool.</p>
<p>Enter <a href="http://github.com/avdi/greenletters">Greenletters</a>. Greenletters begins to bring some of the power of Expect to Ruby, with a simple, straightforward API. For example, here&#8217;s a scripted interaction with the classic <a href="http://en.wikipedia.org/wiki/Colossal_Cave_Adventure">Colossal Cave Adventure</a>:</p>
<pre name="code" class="ruby">
  require 'greenletters'

  adv = Greenletters::Process.new("adventure", :transcript =&gt; $stdout)

  # Install a handler which may be triggered at any time
  adv.on(:output, /welcome to adventure/i) do |process, match_data|
    adv &lt; &lt; "no\n"
  end

  puts "Starting adventure..."
  adv.start!

  # Wait for the specified pattern before proceeding
  adv.wait_for(:output, /you are standing at the end of a road/i)
  adv &lt;&lt; "east\n"
  adv.wait_for(:output, /inside a building/i)
  adv &lt;&lt; "quit\n"
  adv.wait_for(:output, /really want to quit/i)
  adv &lt;&lt; "yes\n"
  adv.wait_for(:exit)
  puts "Adventure has exited."
</pre>
<p>Greenletters also ships with some simple Cucumber steps, so you can immediately start using it to specify the behavior of your command-line apps:</p>
<pre class="plain" name="code">    Given process activity is logged to "greenletters.log"
    Given a process "adventure" from command "adventure"
    Given I reply "no" to output "Would you like instructions?" from process "adventure"
    Given I reply "yes" to output "Do you really want to quit" from process "adventure"
    When I execute the process "adventure"
    Then I should see the following output from process "adventure":
    """
    You are standing at the end of a road before a small brick building.
    Around you is a forest.  A small stream flows out of the building and
    down a gully.
    """
    When I enter "east" into process "adventure"
    Then I should see the following output from process "adventure":
    """
    You are inside a building, a well house for a large spring.
    """</pre>
<p>Want to give it a try? Then:</p>
<pre>gem install greenletters</pre>
<p>And check out the examples/ directory for inspiration. Let me know what you think!</p>

<p><a href="http://feedads.g.doubleclick.net/~a/yspEo1YdhuWlDNO-L-8Q94bt3y4/0/da"><img src="http://feedads.g.doubleclick.net/~a/yspEo1YdhuWlDNO-L-8Q94bt3y4/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/yspEo1YdhuWlDNO-L-8Q94bt3y4/1/da"><img src="http://feedads.g.doubleclick.net/~a/yspEo1YdhuWlDNO-L-8Q94bt3y4/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=d9Mth8fhyr8:J9-sF9qE9rg:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=d9Mth8fhyr8:J9-sF9qE9rg:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?i=d9Mth8fhyr8:J9-sF9qE9rg:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=d9Mth8fhyr8:J9-sF9qE9rg:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?i=d9Mth8fhyr8:J9-sF9qE9rg:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=d9Mth8fhyr8:J9-sF9qE9rg:cGdyc7Q-1BI"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?d=cGdyc7Q-1BI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=d9Mth8fhyr8:J9-sF9qE9rg:bcOpcFrp8Mo"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?d=bcOpcFrp8Mo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/VirtuousCode/~4/d9Mth8fhyr8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://avdi.org/devblog/2010/07/19/greenletters-painless-automation-and-testing-for-command-line-applications/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/us/</creativeCommons:license>
	<feedburner:origLink>http://avdi.org/devblog/2010/07/19/greenletters-painless-automation-and-testing-for-command-line-applications/</feedburner:origLink></item>
		<item>
		<title>Announcing Firetower – A command-line interface to Campfire</title>
		<link>http://feedproxy.google.com/~r/VirtuousCode/~3/w-gvB8acS9Y/</link>
		<comments>http://avdi.org/devblog/2010/07/11/announcing-firetower-a-command-line-interface-to-campfire/#comments</comments>
		<pubDate>Mon, 12 Jul 2010 04:25:14 +0000</pubDate>
		<dc:creator>avdi</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[campfire]]></category>
		<category><![CDATA[chat]]></category>
		<category><![CDATA[cli]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://avdi.org/devblog/?p=713</guid>
		<description><![CDATA[OK, this is pretty early stuff but it&#8217;s already usable and I think it has a lot of potential. Firetower is a command-line interface to Campfire. It&#8217;s currently for Linux systems only, but there&#8217;s no reason it can&#8217;t be extended to work on OS X as well. I created it because I needed a command-line [...]]]></description>
			<content:encoded><![CDATA[<p>OK, this is pretty early stuff but it&#8217;s already usable and I think it has a lot of potential.</p>
<p style="text-align: left;"><a href="http://en.wikipedia.org/wiki/Firetower"><img class="size-full wp-image-714 aligncenter" title="BaldMountainLookout" src="http://avdi.org/devblog/wp-content/uploads/2010/07/BaldMountainLookout.jpg" alt="BaldMountainLookout" width="364" height="400" /></a><a href="http://github.com/avdi/firetower">Firetower is a command-line interface to Campfire</a>. It&#8217;s currently for Linux systems only, but there&#8217;s no reason it can&#8217;t be extended to work on OS X as well.</p>
<p>I created it because I needed a command-line interface to Campfire that supported the current <a href="http://developer.37signals.com/campfire/streaming">streaming Campfire API</a>. I also wanted a bit more flexibility than existing tools provided.</p>
<p>You can read all the details <a href="http://github.com/avdi/firetower">at the Github page</a>, but in a nutshell Firetower provides two services:</p>
<ol>
<li>A way to post messages and code snippets to Campfire from the command line; and</li>
<li>A daemon which will monitor any number of campfire rooms (in any number of accounts) and take user-configurable action when events (such as new messages) occur.</li>
</ol>
<p>The latter service is particularly flexible: it can be used to do anything from playing a sound when someone says something in a Campfire room, to implementing IRC-style bots which monitor rooms for keywords and respond accordingly.</p>
<p>For instance, here&#8217;s a simple (and HIGHLY UNSAFE!) Ruby eval-bot which you could drop into ~/.firetower/firetower.conf:</p>
<pre class="ruby">receive do |session, event|
  if event['type'] == 'TextMessage' &#038;&#038; event['body'] =~ /^!eval (.*)$/
    event.room.account.paste!(event.room.name, "Eval result:\n" + eval($1).to_s)
  end
end</pre>
<p>Which is triggered when anyone in the room prefaces a message with &#8220;!eval&#8221;:</p>
<p><img class="aligncenter size-full wp-image-723" title="campfire_eval2" src="http://avdi.org/devblog/wp-content/uploads/2010/07/campfire_eval2.png" alt="campfire_eval2" width="221" height="118" /></p>
<p>Patches, suggestions, and bug reports welcome!</p>

<p><a href="http://feedads.g.doubleclick.net/~a/JMBdQqdeEiOgkutHDIBY3CoqojE/0/da"><img src="http://feedads.g.doubleclick.net/~a/JMBdQqdeEiOgkutHDIBY3CoqojE/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/JMBdQqdeEiOgkutHDIBY3CoqojE/1/da"><img src="http://feedads.g.doubleclick.net/~a/JMBdQqdeEiOgkutHDIBY3CoqojE/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=w-gvB8acS9Y:XpDkp5KmITU:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=w-gvB8acS9Y:XpDkp5KmITU:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?i=w-gvB8acS9Y:XpDkp5KmITU:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=w-gvB8acS9Y:XpDkp5KmITU:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?i=w-gvB8acS9Y:XpDkp5KmITU:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=w-gvB8acS9Y:XpDkp5KmITU:cGdyc7Q-1BI"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?d=cGdyc7Q-1BI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=w-gvB8acS9Y:XpDkp5KmITU:bcOpcFrp8Mo"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?d=bcOpcFrp8Mo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/VirtuousCode/~4/w-gvB8acS9Y" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://avdi.org/devblog/2010/07/11/announcing-firetower-a-command-line-interface-to-campfire/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/us/</creativeCommons:license>
	<feedburner:origLink>http://avdi.org/devblog/2010/07/11/announcing-firetower-a-command-line-interface-to-campfire/</feedburner:origLink></item>
		<item>
		<title>Rack-Test and Capybara are uneasy bedfellows</title>
		<link>http://feedproxy.google.com/~r/VirtuousCode/~3/FFhGoStTMaE/</link>
		<comments>http://avdi.org/devblog/2010/06/18/rack-test-and-capybara-are-uneasy-bedfellows/#comments</comments>
		<pubDate>Fri, 18 Jun 2010 20:27:29 +0000</pubDate>
		<dc:creator>avdi</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[capybara]]></category>
		<category><![CDATA[cucumber]]></category>
		<category><![CDATA[rack-test]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[rails3]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://avdi.org/devblog/?p=700</guid>
		<description><![CDATA[I&#8217;m using Capybara on a new project because apparently it&#8217;s the new hotness. Today I found out that all is not peaceful in the Cucumber/Capybara/Rack-Test stack. There is a cold war going on, and both Capy and Rack-test are jealously guarding their own cookie jars. Why does this matter? Well, say you use post '/some_callback', [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m using Capybara on a new project because apparently it&#8217;s the new hotness. Today I found out that all is not peaceful in the Cucumber/Capybara/Rack-Test stack. There is a cold war going on, and both Capy and Rack-test are jealously guarding their own cookie jars.</p>
<p>Why does this matter? Well, say you use <code>post '/some_callback', :some => "data"</code> in your tests to simulate a callback from an external service like <a href="http://www.janrain.com/products/engage">Janrain</a>. Then you use  <code>visit '/'</code> to simulate the user loading a page after the callback.</p>
<p><em>Any</em> cookies set during the <code>post</code> will be ignored by the visit call, because like I said earlier, Capy and Rack-Test don&#8217;t share cookies. So if that callback action set up a user session, that session is now lost from the point of view of Capybara (and all the Cucumber steps that use Capybara).</p>
<p>Putting this out there in case anyone else runs into it and is as befuddled as I was.</p>

<p><a href="http://feedads.g.doubleclick.net/~a/Tcdg3PeLQPCoD5CQwWkTQnnuD4A/0/da"><img src="http://feedads.g.doubleclick.net/~a/Tcdg3PeLQPCoD5CQwWkTQnnuD4A/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/Tcdg3PeLQPCoD5CQwWkTQnnuD4A/1/da"><img src="http://feedads.g.doubleclick.net/~a/Tcdg3PeLQPCoD5CQwWkTQnnuD4A/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=FFhGoStTMaE:0NCFd6teuMQ:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=FFhGoStTMaE:0NCFd6teuMQ:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?i=FFhGoStTMaE:0NCFd6teuMQ:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=FFhGoStTMaE:0NCFd6teuMQ:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?i=FFhGoStTMaE:0NCFd6teuMQ:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=FFhGoStTMaE:0NCFd6teuMQ:cGdyc7Q-1BI"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?d=cGdyc7Q-1BI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=FFhGoStTMaE:0NCFd6teuMQ:bcOpcFrp8Mo"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?d=bcOpcFrp8Mo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/VirtuousCode/~4/FFhGoStTMaE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://avdi.org/devblog/2010/06/18/rack-test-and-capybara-are-uneasy-bedfellows/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/us/</creativeCommons:license>
	<feedburner:origLink>http://avdi.org/devblog/2010/06/18/rack-test-and-capybara-are-uneasy-bedfellows/</feedburner:origLink></item>
		<item>
		<title>Rails 3 resource routes with dots; or, how to make a Ruby developer go a little bit insane</title>
		<link>http://feedproxy.google.com/~r/VirtuousCode/~3/8DMZOynmZno/</link>
		<comments>http://avdi.org/devblog/2010/06/18/rails-3-resource-routes-with-dots-or-how-to-make-a-ruby-developer-go-a-little-bit-insane/#comments</comments>
		<pubDate>Fri, 18 Jun 2010 08:58:35 +0000</pubDate>
		<dc:creator>avdi</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[dot]]></category>
		<category><![CDATA[period]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[rails3]]></category>
		<category><![CDATA[routes]]></category>
		<category><![CDATA[routing]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://avdi.org/devblog/?p=697</guid>
		<description><![CDATA[This one cost me at least an hour of frustration. So apparently the Rails router has considered the dot (&#8220;.&#8221;) to be a &#8220;separator&#8221; character along with the slash (&#8220;/&#8221;) since version 1.2. I don&#8217;t know in what context this ever seemed like a good idea, but whatever. It&#8217;s not the sort of thing that&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p>This one cost me at least an hour of frustration.</p>
<p>So apparently the Rails router has considered the dot (&#8220;.&#8221;) to be a &#8220;separator&#8221; character along with the slash (&#8220;/&#8221;) since version 1.2. I don&#8217;t know in what context this ever seemed like a good idea, but whatever. It&#8217;s not the sort of thing that&#8217;s going to bite you every day, but when it does it will be in very weird ways. To wit:</p>
<p>First, a simple routes.rb.</p>
<pre name="code" class="ruby">
  resources :users do
    resources :projects
  end
</pre>
<p>Fill in some typical values, and you get a path:</p>
<pre name="code">
irb(main):009:0> app.user_projects_path("avdi")
=> "/users/avdi/projects"
</pre>
<p>Now fill in a value with a period in it, and watch it explode:</p>
<pre name="code">
irb(main):010:0> app.user_projects_path("avdi.grimm")
ActionController::RoutingError: No route matches {
  :user_id=>"avdi.grimm", :action=>"create", :controller=>"projects"
}
</pre>
<p><code>:action => "create"</code>? What?!! Who said anything about <strong>create</strong>?!</p>
<p>As it turns out, there is an invocation in your routes file which will fix this:</p>
<pre name="code" class="ruby">
  resources :users, :constraints => { :id => /.*/ } do
    resources :projects
  end
</pre>
<pre name="code">
irb(main):013:0> app.user_projects_path("avdi.grimm")
=> "/users/avdi.grimm/projects"
</pre>
<p>Now I know what you&#8217;re thinking. &#8220;That&#8217;s so obvious, why didn&#8217;t he think of that immediately?&#8221; What can I say, some days I&#8217;m slow.</p>

<p><a href="http://feedads.g.doubleclick.net/~a/hHlNvNgDrmTteLs4lltPSYb5nQk/0/da"><img src="http://feedads.g.doubleclick.net/~a/hHlNvNgDrmTteLs4lltPSYb5nQk/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/hHlNvNgDrmTteLs4lltPSYb5nQk/1/da"><img src="http://feedads.g.doubleclick.net/~a/hHlNvNgDrmTteLs4lltPSYb5nQk/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=8DMZOynmZno:I3TRp8ua24I:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=8DMZOynmZno:I3TRp8ua24I:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?i=8DMZOynmZno:I3TRp8ua24I:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=8DMZOynmZno:I3TRp8ua24I:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?i=8DMZOynmZno:I3TRp8ua24I:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=8DMZOynmZno:I3TRp8ua24I:cGdyc7Q-1BI"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?d=cGdyc7Q-1BI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=8DMZOynmZno:I3TRp8ua24I:bcOpcFrp8Mo"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?d=bcOpcFrp8Mo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/VirtuousCode/~4/8DMZOynmZno" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://avdi.org/devblog/2010/06/18/rails-3-resource-routes-with-dots-or-how-to-make-a-ruby-developer-go-a-little-bit-insane/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/us/</creativeCommons:license>
	<feedburner:origLink>http://avdi.org/devblog/2010/06/18/rails-3-resource-routes-with-dots-or-how-to-make-a-ruby-developer-go-a-little-bit-insane/</feedburner:origLink></item>
	</channel>
</rss><!-- Dynamic page generated in 0.515 seconds. --><!-- Cached page generated by WP-Super-Cache on 2010-09-06 02:22:30 -->
