<?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>Mon, 08 Feb 2010 17:46:55 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<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" /><item>
		<title>Cargo Cults and Dharma Transmission</title>
		<link>http://feedproxy.google.com/~r/VirtuousCode/~3/6amS72WIUWk/</link>
		<comments>http://avdi.org/devblog/2010/02/08/cargo-cults-and-dharma-transmission/#comments</comments>
		<pubDate>Mon, 08 Feb 2010 14:00:40 +0000</pubDate>
		<dc:creator>avdi</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[dharma]]></category>
		<category><![CDATA[practices]]></category>

		<guid isPermaLink="false">http://avdi.org/devblog/?p=450</guid>
		<description><![CDATA[Here&#8217;s a pattern I see a lot in discussions of development practices:


Skeptic:I&#8217;ve tried practice X, and it doesn&#8217;t work
Believer:What do you mean it doesn&#8217;t work?  It works for me and everyone I know. You must be doing it wrong.
Skeptic:Nonsense. I did it exactly the way the book says to do it. You&#8217;re just a [...]]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s a pattern I see a lot in discussions of development practices:</p>

<p><dialog><br />
<dt>Skeptic:</dt><dd>I&#8217;ve tried practice X, and it doesn&#8217;t work</dd><br />
<dt>Believer:</dt><dd>What do you mean it doesn&#8217;t work?  It works for me and everyone I know. You must be doing it wrong.</dd><br />
<dt>Skeptic:</dt><dd>Nonsense<strong>. I did it exactly the way the book says to do it</strong>. You&#8217;re just a blinded by the kool-aid.</dd><br />
<dt>Believer:</dt><dd>Unprofessional lout.</dd><br />
<dt>Skeptic:</dt><dd>Deluded imbecile.</dd><br />
<dt>Believer:</dt><dd>I know you are, but what am I?</dd><br />
</dialog></p>

<p>You get the idea.</p>

<p>I highlighted what I think is the key point n this conversation: the fact that the Skeptic learned about Practice X from a book.  It could just as well have been a Wikipedia article or a series of blog posts. The point is that our Skeptic tried to put into practice something which he had never witnessed first-hand, and was disappointed at the results.</p>

<p>It strikes me that there is a form of <a href="http://c2.com/cgi/wiki?CargoCultProgramming">cargo-culting</a> going on here. Only in this case, when the cargo planes fail to arrive, the cultists experience an understandable crisis of faith. Sometimes followed by a period of angry backlash against the&#8221;faithful&#8221;.</p>

<p>In some Buddhist traditions the concept of &#8220;<a href="http://en.wikipedia.org/wiki/Dharma_transmission">Dharma transmission</a>&#8221; is held to be central.  A Dharma transmission is the direct person-to-person teaching from master to student. A teaching is regarded as true and authentic if a lineage of direct transmissions can be traced, teacher to teacher, all the way back to Sakyamuni Buddha himself.</p>

<p>Dharma transmission cannot occur through reading holy books. It must occur in person.  I think this may sometimes be true of software development practices as well.  We have a wealth of books and articles on best practices.  You can learn everything there is to know about Test-Driven Development or Separation of Concerns without ever leaving your desk. But without sitting down with a master and working through a real-world problem, you risk missing that moment of enlightenment when everything clicks into place.</p>

<p>I&#8217;m usually quick to say &#8220;you&#8217;re doing it wrong; read more and try again&#8221; when I see people complaining about practices that I find profoundly beneficial.  But maybe that isn&#8217;t helpful. Maybe some understandings can only be effectively passed by direct transmission. </p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=6amS72WIUWk:Q5WiJbRlQ-U:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=6amS72WIUWk:Q5WiJbRlQ-U:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?i=6amS72WIUWk:Q5WiJbRlQ-U:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=6amS72WIUWk:Q5WiJbRlQ-U:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?i=6amS72WIUWk:Q5WiJbRlQ-U:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=6amS72WIUWk:Q5WiJbRlQ-U: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=6amS72WIUWk:Q5WiJbRlQ-U: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/6amS72WIUWk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://avdi.org/devblog/2010/02/08/cargo-cults-and-dharma-transmission/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/02/08/cargo-cults-and-dharma-transmission/</feedburner:origLink></item>
		<item>
		<title>First and Rest in Ruby</title>
		<link>http://feedproxy.google.com/~r/VirtuousCode/~3/GJqTIlzIStA/</link>
		<comments>http://avdi.org/devblog/2010/01/31/first-and-rest-in-ruby/#comments</comments>
		<pubDate>Mon, 01 Feb 2010 05:42:36 +0000</pubDate>
		<dc:creator>avdi</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[functional]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://avdi.org/devblog/?p=446</guid>
		<description><![CDATA[A common pattern when doing functional-style programming is to split a list into first and rest components, otherwise known as head and tail (or car and cdr in Lisp). first is the first item in the list, or nil if the list is empty. rest is a zero or more-length list containing the remaining elements [...]]]></description>
			<content:encoded><![CDATA[<p>A common pattern when doing functional-style programming is to split a list into <em>first</em> and <em>rest</em> components, otherwise known as <em>head</em> and <em>tail</em> (or <em>car</em> and <em>cdr</em> in Lisp). <em>first</em> is the first item in the list, or <code>nil</code> if the list is empty. <em>rest</em> is a zero or more-length list containing the remaining elements in the original list.</p>

<p>For instance, here&#8217;s a recursive reimplementation of Ruby&#8217;s <code>Array#join</code> method which splits the joined list into <em>first</em> and <em>rest</em>:</p>



<pre name="code" class="ruby">
def rec_join(list, delim)
  case list.size
  when 0 then &quot;&quot;
  when 1 then list.first.to_s
  else list.first.to_s + delim + rec_join(list[1..-1], delim)
  end
end

rec_join([:foo, :bar, :baz], ', ') # =&gt; &quot;foo, bar, baz&quot;
</pre>



<p>In this example we used <code>list.first</code> to get the first element, and <code>list[1..-1]</code> to get the rest. But is this a robust way to split an array into head and tail components? Let&#8217;s see:</p>



<pre name="code" class="ruby">
zero = []
one  = [0]
many = [0,1,2,3,4]

first, rest = zero.first, zero[1..-1]
first                           # =&gt; nil
rest                            # =&gt; nil
first, rest = one.first, one[1..-1]
first                           # =&gt; 0
rest                            # =&gt; []
first, rest = many.first, many[1..-1]
first                           # =&gt; 0
rest                            # =&gt; [1, 2, 3, 4]
</pre>



<p>Hmmm. We said that <em>rest</em> should always be a list with zero or most elements; but when given an empty list to start with, this technique gives us <code>nil</code> as the tail of the list. It&#8217;s also a bit ugly. Let&#8217;s see if we can do better.</p>



<pre name="code" class="ruby">
first, rest = *zero
first                           # =&gt; nil
rest                            # =&gt; nil
first, rest = *one    
first                           # =&gt; 0
rest                            # =&gt; nil
first, rest = *many        
first                           # =&gt; 0
rest                            # =&gt; 1
</pre>



<p>Now we&#8217;re using the splat operator to break the source list into it&#8217;s parts. The code is much more concise, but the results are very wrong. In this version <em>rest</em> is never a list!</p>

<p>However, a slight refinement and we have exactly what we want:</p>



<pre name="code" class="ruby">
first, *rest = *zero
first                           # =&gt; nil
rest                            # =&gt; []
first, *rest = *one    
first                           # =&gt; 0
rest                            # =&gt; []
first, *rest = *many        
first                           # =&gt; 0
rest                            # =&gt; [1, 2, 3, 4]
</pre>



<p>Here we&#8217;ve added a splat operator to the left side of the variable assignment as well, telling Ruby to collect all remaining values into an Array assigned to the <code>rest</code> variable.  This version works exactly as we intended, and is still concise. I first saw this technique used in the DataMapper codebase, and it&#8217;s the most elegant way I&#8217;ve come across to break a Ruby Enumerable object into <em>first</em> and <em>rest</em> components.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=GJqTIlzIStA:tSs1erdKnoQ:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=GJqTIlzIStA:tSs1erdKnoQ:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?i=GJqTIlzIStA:tSs1erdKnoQ:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=GJqTIlzIStA:tSs1erdKnoQ:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?i=GJqTIlzIStA:tSs1erdKnoQ:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=GJqTIlzIStA:tSs1erdKnoQ: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=GJqTIlzIStA:tSs1erdKnoQ: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/GJqTIlzIStA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://avdi.org/devblog/2010/01/31/first-and-rest-in-ruby/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/01/31/first-and-rest-in-ruby/</feedburner:origLink></item>
		<item>
		<title>Confident Code at B’More on Rails</title>
		<link>http://feedproxy.google.com/~r/VirtuousCode/~3/IOyx2Q8ZMcU/</link>
		<comments>http://avdi.org/devblog/2010/01/20/confident-code-at-bmore-on-rails/#comments</comments>
		<pubDate>Wed, 20 Jan 2010 13:17:41 +0000</pubDate>
		<dc:creator>avdi</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[confidence]]></category>
		<category><![CDATA[presentations]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[talks]]></category>

		<guid isPermaLink="false">http://avdi.org/devblog/?p=435</guid>
		<description><![CDATA[Here&#8217;s video of the talk I did at B&#8217;More on Rails January 12, 2010.  



If I seem nervous, it&#8217;s because it&#8217;s the first time I&#8217;ve done something like this. The two things I will try to remember for future talks are:

	Stand still!
	The audience is in front of you, dumbass!


The slides are available here. I [...]]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s video of the talk I did at <a href="http://www.meetup.com/bmore-on-rails/"><span class="caps">B&#8217;M</span>ore on Rails</a> January 12, 2010.  </p>

<p><object width="400" height="300"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=8856299&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=8856299&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="300"></embed></object></p>

If I seem nervous, it&#8217;s because it&#8217;s the first time I&#8217;ve done something like this. The two things I will try to remember for future talks are:<br />
<ol>
	<li>Stand still!</li>
	<li>The audience is in <em>front</em> of you, dumbass!</li>
</ol>

<p>The <a href="http://avdi.org/talks/confident-code-2010-01-12/confident-code.html">slides are available here</a>. I used <a href="http://www.gnu.org/software/emacs/"><span class="caps">GNU</span> Emacs</a> and <a href="http://orgmode.org/">Org-Mode</a> to write the presentation and all of the code samples, <a href="http://github.com/sigma/org-s5">org-s5.el</a> to convert the Org file into an <a href="http://meyerweb.com/eric/tools/s5/">S5</a> presentation, and <a href="http://www.gimp.org/">the <span class="caps">GIMP</span></a> for the source code overlays.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=IOyx2Q8ZMcU:S-QROuuzHJU:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=IOyx2Q8ZMcU:S-QROuuzHJU:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?i=IOyx2Q8ZMcU:S-QROuuzHJU:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=IOyx2Q8ZMcU:S-QROuuzHJU:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?i=IOyx2Q8ZMcU:S-QROuuzHJU:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=IOyx2Q8ZMcU:S-QROuuzHJU: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=IOyx2Q8ZMcU:S-QROuuzHJU: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/IOyx2Q8ZMcU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://avdi.org/devblog/2010/01/20/confident-code-at-bmore-on-rails/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/us/</creativeCommons:license>
	<feedburner:origLink>http://avdi.org/devblog/2010/01/20/confident-code-at-bmore-on-rails/</feedburner:origLink></item>
		<item>
		<title>Hammertime: An interactive error console for Ruby</title>
		<link>http://feedproxy.google.com/~r/VirtuousCode/~3/CDpLCvmdEwM/</link>
		<comments>http://avdi.org/devblog/2010/01/18/hammertime/#comments</comments>
		<pubDate>Mon, 18 Jan 2010 14:00:32 +0000</pubDate>
		<dc:creator>avdi</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[announcements]]></category>
		<category><![CDATA[errors]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://avdi.org/devblog/?p=411</guid>
		<description><![CDATA[Users of Lisp and Smalltalk environments are used to having some pretty powerful tools for debugging exceptions in their code.  For instance, here&#8217;s the dialog I see when I try to do execute some bad code in Squeak:



Ruby users are not so lucky. Our first indication of an error is either the code not [...]]]></description>
			<content:encoded><![CDATA[<p>Users of Lisp and Smalltalk environments are used to having some pretty powerful tools for debugging exceptions in their code.  For instance, here&#8217;s the dialog I see when I try to do execute some bad code in <a href="http://www.squeak.org/">Squeak</a>:</p>

<p><img src="http://avdi.org/devblog/wp-content/uploads/2010/01/squeak-error.png" alt="squeak-error" title="squeak-error" width="454" height="157" class="aligncenter size-full wp-image-412" /></p>

<p>Ruby users are not so lucky. Our first indication of an error is either the code not working or a stack trace, depending on whether the error is handled somewhere. Either way, we don&#8217;t get an opportunity to investigate the circumstances of the error when it is raised. All we get to see is the aftermath.</p>

<p>Ruby exceptions are raised with the <a href="http://ruby-doc.org/core/classes/Kernel.html#M005927"><code>raise</code></a> method, or with <code>fail</code>, which is an alias for <code>raise</code>. I use the term &#8220;method&#8221; deliberately. <code>raise</code> is not a keyword; it&#8217;s a method on <code>Kernel</code> just like <code>puts</code> and <code>exit</code>.</p>

<p>The fact that <code>raise</code> is just an ordinary method has some interesting implications. For instance, we can modify it to trace the location of every error raised in a program:</p>



<pre name="code" class="ruby">
module MyRaise
  def raise(*args)
    puts &quot;Error at #{caller.first}!&quot;
    super(*args)
  end
end

class Object
  include MyRaise
end

raise &quot;blah&quot; rescue nil         # =&gt; nil
# &gt;&gt; Error at -:12!
</pre>



<p>Since <code>MyRaise</code> is included in <code>Object</code> after the default <code>Kernel</code>, our definition of <code>raise</code> takes precedence.</p>

<p>Obviously, if we can intercept errors at the moment they are raised, there&#8217;s a lot more we can do beyond mere tracing. Introducing <a href="http://github.com/avdi/hammertime">Hammertime</a>.</p>

<p><img src="http://avdi.org/devblog/wp-content/uploads/2010/01/stop-hammertime.jpg" alt="stop-hammertime" title="stop-hammertime" width="390" height="328" class="aligncenter size-full wp-image-415" /></p>

<p>Hammertime is an interactive error console for Ruby. Using it is simple: just <tt>gem install hammertime</tt> and require the library:</p>



<pre name="code" class="ruby">
require 'hammertime'
</pre>



<p>Now when an error is raised, we&#8217;re be presented with a menu:</p>



<pre name="code" class="plain">
=== Stop! Hammertime. ===
An error has occurred at example.rb:6:in `faulty_method'
The error is: #&amp;lt;RuntimeError : Oh no!&amp;gt;
1. Continue (process the exception normally)            
2. Ignore (proceed without raising an exception)        
3. Permit by type (don't ask about future errors of this type)
4. Permit by line (don't ask about future errors raised from this point)
5. Backtrace (show the call stack leading up to the error)              
6. Debug (start a debugger)                                             
7. Console (start an IRB session)                                       
What now?
</pre>



<p>With Hammertime we can diagnose and fix errors at the point where they occur. Let&#8217;s walk through an example Hammertime session using the following highly contrived script:</p>



<pre name="code" class="ruby">
$broken = true

def faulty_method
  raise &quot;Oh no!&quot; if $broken
end

3.times do |n|
  puts &quot;Attempt (#{n+1}/3)&quot;
  begin
    faulty_method
    puts &quot;No error raised&quot;
  rescue =&gt; error
    puts &quot;Error raised: #{error.inspect}&quot;
  end
end
</pre>



<p>We start the code with Hammertime enabled:</p>



<pre name="code" class="plain">
$ ruby -rhammertime example.rb
</pre>



<p>The code raises an error, and we see the Hammertime menu:</p>



<pre name="code">
Attempt (1/3)

=== Stop! Hammertime. ===
An error has occurred at example.rb:6:in `faulty_method'
The error is: #&amp;lt;runtimeerror : Oh no!&amp;gt;
1. Continue (process the exception normally)
2. Ignore (proceed without raising an exception)
3. Permit by type (don't ask about future errors of this type)
4. Permit by line (don't ask about future errors raised from this point)
5. Backtrace (show the call stack leading up to the error)
6. Debug (start a debugger)
7. Console (start an IRB session)
What now?
</pre>



<p>We choose &#8220;Backtrace&#8221; to see the full trace leading up to the error:</p>



<pre name="code" class="plain">
5
example.rb:6:in `faulty_method'
example.rb:12
example.rb:9:in `times'
example.rb:9
1. Continue (process the exception normally)
2. Ignore (proceed without raising an exception)
3. Permit by type (don't ask about future errors of this type)
4. Permit by line (don't ask about future errors raised from this point)
5. Backtrace (show the call stack leading up to the error)
6. Debug (start a debugger)
7. Console (start an IRB session)
What now?
</pre>



<p>Note that Hammertime returns us to the menu after showing the stack trace. Next we choose &#8220;Console&#8221; to drop into an <span class="caps">IRB </span>session.  From there, we do a little snooping around:</p>



<pre name="code" class="plain">
&gt;&gt; $broken
=&gt; true
</pre>



<p>Well that seems to be the problem, someone left the &#8220;<a href="http://catb.org/jargon/html/magic-story.html">more magic</a>&#8221; switch off.  Let&#8217;s fix that:</p>



<pre name="code" class="plain">
&gt;&gt; $broken=false
=&gt; false
&gt;&gt; exit
1. Continue (process the exception normally)
2. Ignore (proceed without raising an exception)
3. Permit by type (don't ask about future errors of this type)
4. Permit by line (don't ask about future errors raised from this point)
5. Backtrace (show the call stack leading up to the error)
6. Debug (start a debugger)
7. Console (start an IRB session)
What now?
</pre>



<p>And now we&#8217;ll choose to Ignore the error and proceed:</p>



<pre name="code" class="plain">
What now?
2
No error raised
Attempt (2/3)
No error raised
Attempt (3/3)
No error raised
</pre>



<p>We&#8217;ve fixed the &#8220;bug&#8221;, so successive runs execute without problems.</p>

<p>Hammertime has other features, including the ability to specify certain errors which won&#8217;t trigger the menu to be presented. If you want to learn more about it I suggest installing it, playing around with it, and reading the code.</p>

<p>The biggest limitation of Hammertime is that it can only catch errors which are raised within Ruby code, not those raised in native code.  I threw it together in an afternoon, so it probably has other bugs as well. Please let me know if you get some use out of the tool. Patches, bug reports, and suggestions are welcome.</p>

<p><span class="caps">UPDATE</span>: Magnus Holm was inspired by this post to create an <a href="http://judofyr.net/posts/never-gonna-let-you-go.html">Exception#continue</a> method. With a little more work I think this could be the basis for a <a href="http://www.gigamonkeys.com/book/beyond-exception-handling-conditions-and-restarts.html">Lisp-style conditions</a> system, something I&#8217;d love to see implemented in Ruby.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=CDpLCvmdEwM:TI2uZj8dxIM:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=CDpLCvmdEwM:TI2uZj8dxIM:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?i=CDpLCvmdEwM:TI2uZj8dxIM:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=CDpLCvmdEwM:TI2uZj8dxIM:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?i=CDpLCvmdEwM:TI2uZj8dxIM:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=CDpLCvmdEwM:TI2uZj8dxIM: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=CDpLCvmdEwM:TI2uZj8dxIM: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/CDpLCvmdEwM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://avdi.org/devblog/2010/01/18/hammertime/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/us/</creativeCommons:license>
	<feedburner:origLink>http://avdi.org/devblog/2010/01/18/hammertime/</feedburner:origLink></item>
		<item>
		<title>Come see me run my mouth at B’More on Rails</title>
		<link>http://feedproxy.google.com/~r/VirtuousCode/~3/04xRcQhqngQ/</link>
		<comments>http://avdi.org/devblog/2010/01/11/come-see-me-run-my-mouth-at-bmore-on-rails/#comments</comments>
		<pubDate>Mon, 11 Jan 2010 18:03:43 +0000</pubDate>
		<dc:creator>avdi</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://avdi.org/devblog/?p=407</guid>
		<description><![CDATA[I&#8217;ll be speaking tomorrow night, Tuesday, January 12, at B&#8217;More on Rails. The topic will be &#8220;Confident Code&#8221;.  If you&#8217;re in the Baltimore area, I&#8217;d love to see you there!]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ll be speaking <a href="http://www.meetup.com/bmore-on-rails/calendar/12048116/">tomorrow night, Tuesday, January 12, at <span class="caps">B&#8217;M</span>ore on Rails</a>. The topic will be &#8220;Confident Code&#8221;.  If you&#8217;re in the Baltimore area, I&#8217;d love to see you there!</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=04xRcQhqngQ:VwEcSxj3LuM:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=04xRcQhqngQ:VwEcSxj3LuM:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?i=04xRcQhqngQ:VwEcSxj3LuM:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=04xRcQhqngQ:VwEcSxj3LuM:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?i=04xRcQhqngQ:VwEcSxj3LuM:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=04xRcQhqngQ:VwEcSxj3LuM: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=04xRcQhqngQ:VwEcSxj3LuM: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/04xRcQhqngQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://avdi.org/devblog/2010/01/11/come-see-me-run-my-mouth-at-bmore-on-rails/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/01/11/come-see-me-run-my-mouth-at-bmore-on-rails/</feedburner:origLink></item>
		<item>
		<title>The Pidgin “IRSSI Features” Plugin Will Spam Your Friends</title>
		<link>http://feedproxy.google.com/~r/VirtuousCode/~3/272aHneJo8M/</link>
		<comments>http://avdi.org/devblog/2010/01/04/the-pidgin-irssi-features-plugin-will-spam-your-friends/#comments</comments>
		<pubDate>Mon, 04 Jan 2010 13:38:17 +0000</pubDate>
		<dc:creator>avdi</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[identity]]></category>
		<category><![CDATA[im]]></category>
		<category><![CDATA[irc]]></category>
		<category><![CDATA[irssi]]></category>
		<category><![CDATA[libpurple]]></category>
		<category><![CDATA[pidgin]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[spam]]></category>

		<guid isPermaLink="false">http://avdi.org/devblog/?p=405</guid>
		<description><![CDATA[The Pidgin IRSSI Features plugin by Gary Kramlich and John Bailey contains a hard-coded &#8220;Easter Egg&#8221; which will spam all open conversation with a &#8220;Happy New Year!&#8221; message if Pidgin is running at midnight January 1st.  John Bailey has confirmed this &#8220;feature&#8221; is intentional.  The behavior is present in the  pidgin-plugin-pack package [...]]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://plugins.guifications.org/trac/wiki/irssi">Pidgin <span class="caps">IRSSI</span> Features</a> plugin by Gary Kramlich and John Bailey contains a hard-coded &#8220;Easter Egg&#8221; which will spam all open conversation with a &#8220;Happy New Year!&#8221; message if Pidgin is running at midnight January 1st.  John Bailey <a href="http://developer.pidgin.im/ticket/11070">has confirmed this &#8220;feature&#8221; is intentional</a>.  The behavior is present in the  pidgin-plugin-pack package for Ubuntu.  It has apparently been <a href="http://plugins.guifications.org/trac/browser/irssi/irssi.c?rev=74%3A1bb848ed9bf6#L115">part of the plugin</a> since its inception.</p>

<p>Some may find this easter egg as whimisical as its authors apparently intended. Personally, I find it to be an unprofessional abuse of my IM credentials and identity.  When we as users turn our logins and passwords over to a social software client, we implicitly trust that software to safeguard our our identity.  There is a reason people get irate when a Twitter app spams all their friends with messages without their express permission.  Impersonating a user and spamming their friends is a violation of trust.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=272aHneJo8M:uH1DHsJi15g:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=272aHneJo8M:uH1DHsJi15g:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?i=272aHneJo8M:uH1DHsJi15g:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=272aHneJo8M:uH1DHsJi15g:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?i=272aHneJo8M:uH1DHsJi15g:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=272aHneJo8M:uH1DHsJi15g: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=272aHneJo8M:uH1DHsJi15g: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/272aHneJo8M" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://avdi.org/devblog/2010/01/04/the-pidgin-irssi-features-plugin-will-spam-your-friends/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/01/04/the-pidgin-irssi-features-plugin-will-spam-your-friends/</feedburner:origLink></item>
		<item>
		<title>Wax on, Wax off</title>
		<link>http://feedproxy.google.com/~r/VirtuousCode/~3/cNoAjaJBrGs/</link>
		<comments>http://avdi.org/devblog/2009/12/29/wax-on-wax-off/#comments</comments>
		<pubDate>Tue, 29 Dec 2009 13:19:48 +0000</pubDate>
		<dc:creator>avdi</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[philosophy]]></category>
		<category><![CDATA[practices]]></category>

		<guid isPermaLink="false">http://avdi.org/devblog/?p=399</guid>
		<description><![CDATA[Zed&#8217;s post on mastery is great, as usual. I have only this to add: that while mastery transcends rules, no one achieves mastery without first acquiring discipline. The masters, who eschew wrote practices to cut straight to the heart of a problem, first spend years practicing forms, repeating katas, and studying theory.

I think every programmer [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://zedshaw.com/essays/master_and_expert.html?reddit">Zed&#8217;s post on mastery</a> is great, as usual. I have only this to add: that while mastery transcends rules, no one achieves mastery without first acquiring discipline. The masters, who eschew wrote practices to cut straight to the heart of a problem, first spend years practicing forms, repeating <a href="http://katas.softwarecraftsmanship.org/">katas</a>, and studying theory.</p>

<p>I think every programmer goes through stages of being enamored with certain practices.  Just like many other coders after I first read <a href="http://www.amazon.com/gp/product/0201633612?ie=UTF8&amp;tag=thlafa-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0201633612">Design Patterns</a><img src="http://www.assoc-amazon.com/e/ir?t=thlafa-20&amp;l=as2&amp;o=1&amp;a=0201633612" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /> I looked for excuses to use patterns everywhere.  After becoming &#8220;<a href="http://www.c2.com/cgi/wiki/Wiki?TestInfected">test-infected</a>&#8221; I wouldn&#8217;t write code without tests up-front &#8211; even if it meant spending a lot of time constructing elaborate test harnesses.  And then later on, just like many programmers before me, I moved on to a point where these practices were no longer ideologies but merely tools in my toolbox.</p>

<p>As programmers and engineers we are obsessed with optimizing processes, and I think for many of us after we &#8220;level up&#8221; our skill we look for ways the learning process could have been optimized. A lot of developers, when moving past strict rule-based approaches to coding adopt the idea that all those rigid procedures are really for the stupid mediocre programmers; here among the 10% we don&#8217;t need that sort of thing.  But I don&#8217;t think it&#8217;s that simple.</p>

<p>There are things you learn from consistent practice of a discipline which no amount of reading <em>about</em> the discipline can instill.  Learning to view software in terms of patterns and antipatterns improved my skill.  So did learning to illustrate software in <span class="caps">UML. </span> So has practicing strict <span class="caps">TDD. </span> So has practicing pair-programming.  The agile masters will tell you to practice one of the Agile methodologies fully and strictly before trying to customize it for your organization.  There is intangible value in discipline.</p>

<p>I&#8217;m all for embracing simplicity (<a href="http://avdi.org/devblog/2009/10/29/simplicity-is-complicated/">so long as we&#8217;re clear about what we mean by it</a>).  But I think we should recognize that disciplines, while not the end goal, are also not necessarily obstacles to ahieving mastery. Rather, they are essential stepping stones.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=cNoAjaJBrGs:e-GLyxa70i0:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=cNoAjaJBrGs:e-GLyxa70i0:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?i=cNoAjaJBrGs:e-GLyxa70i0:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=cNoAjaJBrGs:e-GLyxa70i0:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?i=cNoAjaJBrGs:e-GLyxa70i0:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=cNoAjaJBrGs:e-GLyxa70i0: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=cNoAjaJBrGs:e-GLyxa70i0: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/cNoAjaJBrGs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://avdi.org/devblog/2009/12/29/wax-on-wax-off/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/2009/12/29/wax-on-wax-off/</feedburner:origLink></item>
		<item>
		<title>Debugging Rule 1: It’s your fault</title>
		<link>http://feedproxy.google.com/~r/VirtuousCode/~3/jDYmdB8dFkg/</link>
		<comments>http://avdi.org/devblog/2009/12/09/its-your-fault/#comments</comments>
		<pubDate>Wed, 09 Dec 2009 10:00:30 +0000</pubDate>
		<dc:creator>avdi</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[debugging]]></category>

		<guid isPermaLink="false">http://avdi.org/devblog/?p=387</guid>
		<description><![CDATA[I recently added Debug It! to my stack of books to read, and I&#8217;m looking forward to digging in to it.  In the mean time here&#8217;s a little debugging advice from my own experience: 

It&#8217;s your fault.

I have GMail set up to SMS me when I break the build. Nearly every time I get [...]]]></description>
			<content:encoded><![CDATA[<p>I recently added <a href="http://www.amazon.com/gp/product/193435628X?ie=UTF8&amp;tag=thlafa-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=193435628X">Debug It!</a><img src="http://www.assoc-amazon.com/e/ir?t=thlafa-20&amp;l=as2&amp;o=1&amp;a=193435628X" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /> to my stack of books to read, and I&#8217;m looking forward to digging in to it.  In the mean time here&#8217;s a little debugging advice from my own experience: </p>

<p><strong>It&#8217;s your fault</strong>.</p>

<p>I have GMail set up to <span class="caps">SMS </span>me when I break the build. Nearly every time I get the dreaded notification, I go through the same defensive routine. &#8220;But the tests passed locally!&#8221; I protest. &#8220;I wasn&#8217;t working on anything that would have affected that!&#8221; I explain. &#8220;There&#8217;s no way that could <span class="caps">POSSIBLY </span>be related&#8221; I whine. &#8220;That shouldn&#8217;t even be possible!&#8221; I complain. &#8220;It&#8217;s not my fault!&#8221;</p>

<p>Nine times out of ten, though, after grudgingly debugging the issue I discover that yes, in fact, my changes were the culprit. Some unforseen side-effect of my changes caused the full-stack tests to fail. It&#8217;s usually an easy fix, albeit not always an obvious one.</p>

<p>The lesson here? Software is complex, and my brain is small. I often don&#8217;t even remember all the changes that went into a particular feature commit; there&#8217;s no way I can predict every tertiary effect those changes will have.  Nine times out of ten I&#8217;d save myself some time and my team some grief if I just assumed it was my fault and got to work.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=jDYmdB8dFkg:-Ov5mUB2ylw:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=jDYmdB8dFkg:-Ov5mUB2ylw:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?i=jDYmdB8dFkg:-Ov5mUB2ylw:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=jDYmdB8dFkg:-Ov5mUB2ylw:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?i=jDYmdB8dFkg:-Ov5mUB2ylw:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=jDYmdB8dFkg:-Ov5mUB2ylw: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=jDYmdB8dFkg:-Ov5mUB2ylw: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/jDYmdB8dFkg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://avdi.org/devblog/2009/12/09/its-your-fault/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/2009/12/09/its-your-fault/</feedburner:origLink></item>
		<item>
		<title>RightAWS and SSL Certificates</title>
		<link>http://feedproxy.google.com/~r/VirtuousCode/~3/1Ajj14_TBZo/</link>
		<comments>http://avdi.org/devblog/2009/11/30/rightaws-and-ssl-certificates/#comments</comments>
		<pubDate>Mon, 30 Nov 2009 14:00:01 +0000</pubDate>
		<dc:creator>avdi</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[aws]]></category>
		<category><![CDATA[right]]></category>
		<category><![CDATA[right_aws]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[ssl]]></category>

		<guid isPermaLink="false">http://avdi.org/devblog/?p=379</guid>
		<description><![CDATA[If you&#8217;ve used the RightAWS tools to talk to Amazon Web Services, you&#8217;ve probably seen this warning before:




warning: peer certificate won't be verified in this SSL session




No one likes warnings cluttering up their output, and this one indicates a very real security problem: no verification is being done to check that the server really is [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;ve used the RightAWS tools to talk to Amazon Web Services, you&#8217;ve probably seen this warning before:</p>

<p><tt></p>

<pre>
warning: peer certificate won't be verified in this SSL session
</pre>

<p></tt></p>

<p>No one likes warnings cluttering up their output, and this one indicates a very real security problem: no verification is being done to check that the server really is a legitimate Amazon host. Unfortunately, the warning doesn&#8217;t give you a lot of clues about how to go about addressing the issue.</p>

<p>Here&#8217;s what you need to do. First, you&#8217;ll need a certificate file. If you&#8217;re running Ubuntu, you can install the &#8220;<a href="http://packages.ubuntu.com/hardy/ca-certificates">ca-certificates</a>&#8221; package (on my system it was already installed). Once it&#8217;s installed you should have a master certificate file at /etc/ssl/certs/ca-certificates.crt. Now you just need to tell RightAWS about the file:</p>



<pre name="code" class="ruby">
require 'right_http_connection'
Rightscale::HttpConnection.params[:ca_file] = &quot;/etc/ssl/certs/ca-certificates.crt&quot;
</pre>



<p>&#8230;and you should get no more warnings.</p>

<p>I&#8217;ve submitted a <a href="http://github.com/devver/right_http_connection/commit/71abaed1f5221f01f28f906aae87bbe403fd5a73">patch</a> to the right_http_connection gem which, if accepted, will use this file by default if it exists. It will also enable users to override the CA file configuration using the <code>RIGHT_HTTP_CA_FILE</code> environment variable.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=1Ajj14_TBZo:5Xdz0K5w4bU:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=1Ajj14_TBZo:5Xdz0K5w4bU:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?i=1Ajj14_TBZo:5Xdz0K5w4bU:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=1Ajj14_TBZo:5Xdz0K5w4bU:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?i=1Ajj14_TBZo:5Xdz0K5w4bU:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=1Ajj14_TBZo:5Xdz0K5w4bU: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=1Ajj14_TBZo:5Xdz0K5w4bU: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/1Ajj14_TBZo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://avdi.org/devblog/2009/11/30/rightaws-and-ssl-certificates/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/2009/11/30/rightaws-and-ssl-certificates/</feedburner:origLink></item>
		<item>
		<title>Fetching multiple SimpleDB items in a single request</title>
		<link>http://feedproxy.google.com/~r/VirtuousCode/~3/Mz8bavpQPc0/</link>
		<comments>http://avdi.org/devblog/2009/11/24/fetching-multiple-simpledb-items-in-a-single-request/#comments</comments>
		<pubDate>Tue, 24 Nov 2009 16:43:43 +0000</pubDate>
		<dc:creator>avdi</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[aws]]></category>
		<category><![CDATA[simpledb]]></category>

		<guid isPermaLink="false">http://avdi.org/devblog/?p=372</guid>
		<description><![CDATA[The only way to retrieve multiple items at a time, along with their attributes, from Amazon SimpleDB is with the Select operation. Typically, you query for some property of the items which you want to retrieve, not by item name:




select * from my_domain where date &#62; '2009-01-01'




The only documented way to retrieve the attributes of [...]]]></description>
			<content:encoded><![CDATA[<p>The only way to retrieve multiple items at a time, along with their attributes, from Amazon SimpleDB is with the <code>Select</code> operation. Typically, you query for some property of the items which you want to retrieve, not by item name:</p>



<pre name="code" class="sql">
select * from my_domain where date &gt; '2009-01-01'
</pre>



<p>The only documented way to retrieve the attributes of an item by item name is with the <code>GetAttributes</code> operation, which only gets one item at a time. But what if you have a list of item names you want to retrieve, and you just want to avoid the overhead of making a separate <code>GetAttributes</code> call for each one?</p>

<p>A clue towards the solution can be found in the fact that the special <code>itemName()</code> token can be used in the field list for <code>Select:



<pre name="code" class="sql">
select itemName() from my_domain where date &gt; '2009-01-01'
</pre>



I didn't find this explicitly documented anywhere, but you can also use </code><code>itemName()</code> in a query condition:</p>



<pre name="code" class="sql">
select * from my_domain where itemName() = 'ABC123'
</pre>



<p>&#8230;and from there it&#8217;s a short step to our solution, which uses the <code>IN</code> predicate:</p>



<pre name="code" class="sql">
select * from my_domain where itemName() in ('ABC123', 'DEF456', ...)
</pre>



<p>And there you have it, a way to retrieve multiple items by name in a single request, subject only to limits on query size and response size. I don&#8217;t know if this is common knowledge to longtime SimpleDB users, but it was new to me, so I thought I&#8217;d share it.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=Mz8bavpQPc0:L3D4UmsLX1o:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=Mz8bavpQPc0:L3D4UmsLX1o:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?i=Mz8bavpQPc0:L3D4UmsLX1o:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=Mz8bavpQPc0:L3D4UmsLX1o:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/VirtuousCode?i=Mz8bavpQPc0:L3D4UmsLX1o:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VirtuousCode?a=Mz8bavpQPc0:L3D4UmsLX1o: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=Mz8bavpQPc0:L3D4UmsLX1o: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/Mz8bavpQPc0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://avdi.org/devblog/2009/11/24/fetching-multiple-simpledb-items-in-a-single-request/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/2009/11/24/fetching-multiple-simpledb-items-in-a-single-request/</feedburner:origLink></item>
	</channel>
</rss><!-- Dynamic Page Served (once) in 1.075 seconds --><!-- Cached page served by WP-Cache -->
