<?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:dc="http://purl.org/dc/elements/1.1/" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><description>
  
</description><title>Nils Jonsson, software builder</title><generator>Tumblr (3.0; @njonsson)</generator><link>http://blog.nilsjonsson.com/</link><feedburner:info uri="njonsson" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://tumblr.superfeedr.com/" /><geo:lat>29.772627</geo:lat><geo:long>-95.40319</geo:long><creativeCommons:license>http://creativecommons.org/licenses/by-sa/3.0/</creativeCommons:license><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://blog.nilsjonsson.com/rss" /><feedburner:feedFlare href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Fblog.nilsjonsson.com%2Frss" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Fblog.nilsjonsson.com%2Frss" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://feeds.my.aol.com/add.jsp?url=http%3A%2F%2Fblog.nilsjonsson.com%2Frss" src="http://o.aolcdn.com/favorites.my.aol.com/webmaster/ffclient/webroot/locale/en-US/images/myAOLButtonSmall.gif">Subscribe with My AOL</feedburner:feedFlare><feedburner:feedFlare href="http://www.bloglines.com/sub/http://blog.nilsjonsson.com/rss" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Fblog.nilsjonsson.com%2Frss" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Fblog.nilsjonsson.com%2Frss" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Fblog.nilsjonsson.com%2Frss" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><feedburner:feedFlare href="http://www.plusmo.com/add?url=http%3A%2F%2Fblog.nilsjonsson.com%2Frss" src="http://plusmo.com/res/graphics/fbplusmo.gif">Subscribe with Plusmo</feedburner:feedFlare><feedburner:feedFlare href="http://www.thefreedictionary.com/_/hp/AddRSS.aspx?http%3A%2F%2Fblog.nilsjonsson.com%2Frss" src="http://img.tfd.com/hp/addToTheFreeDictionary.gif">Subscribe with The Free Dictionary</feedburner:feedFlare><feedburner:feedFlare href="http://www.bitty.com/manual/?contenttype=rssfeed&amp;contentvalue=http%3A%2F%2Fblog.nilsjonsson.com%2Frss" src="http://www.bitty.com/img/bittychicklet_91x17.gif">Subscribe with Bitty Browser</feedburner:feedFlare><feedburner:feedFlare href="http://www.live.com/?add=http%3A%2F%2Fblog.nilsjonsson.com%2Frss" src="http://tkfiles.storage.msn.com/x1piYkpqHC_35nIp1gLE68-wvzLZO8iXl_JMledmJQXP-XTBOLfmQv4zhj4MhcWEJh_GtoBIiAl1Mjh-ndp9k47If7hTaFno0mxW9_i3p_5qQw">Subscribe with Live.com</feedburner:feedFlare><feedburner:feedFlare href="http://mix.excite.eu/add?feedurl=http%3A%2F%2Fblog.nilsjonsson.com%2Frss" src="http://image.excite.co.uk/mix/addtomix.gif">Subscribe with Excite MIX</feedburner:feedFlare><feedburner:feedFlare href="http://www.webwag.com/wwgthis.php?url=http%3A%2F%2Fblog.nilsjonsson.com%2Frss" src="http://www.webwag.com/images/wwgthis.gif">Subscribe with Webwag</feedburner:feedFlare><feedburner:feedFlare href="http://www.podcastready.com/oneclick_bookmark.php?url=http%3A%2F%2Fblog.nilsjonsson.com%2Frss" src="http://www.podcastready.com/images/podcastready_button.gif">Subscribe with Podcast Ready</feedburner:feedFlare><feedburner:feedFlare href="http://www.wikio.com/subscribe?url=http%3A%2F%2Fblog.nilsjonsson.com%2Frss" src="http://www.wikio.com/shared/img/add2wikio.gif">Subscribe with Wikio</feedburner:feedFlare><feedburner:feedFlare href="http://www.dailyrotation.com/index.php?feed=http%3A%2F%2Fblog.nilsjonsson.com%2Frss" src="http://www.dailyrotation.com/rss-dr2.gif">Subscribe with Daily Rotation</feedburner:feedFlare><feedburner:browserFriendly>Hi, everyone. Thanks for your interest in my blog. Enjoy!&#xD;
&#xD;
Feel free to write to me at contact@nilsjonsson.com.</feedburner:browserFriendly><item><title>Get your Cape on</title><description>&lt;p&gt;&lt;a href="http://www.flickr.com/photos/guccibear2005/5208121081"&gt;&lt;img align="right" src="http://media.tumblr.com/tumblr_lvdz4p8xx51qbnl92.jpg"/&gt;&lt;/a&gt; Over Thanksgiving Day weekend I released a new RubyGem called &lt;a href="http://github.com/njonsson/cape" title="Cape at GitHub"&gt;Cape&lt;/a&gt;. You may find it useful if you’re a user of both &lt;a href="http://capify.org"&gt;Capistrano&lt;/a&gt; and &lt;a href="http://github.com/jimweirich/rake" title="Rake at GitHub"&gt;Rake&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Install Cape by typing &lt;code&gt;gem install cape&lt;/code&gt; at the command line, or make it a dependency of your project by using &lt;a href="http://gembundler.com"&gt;Bundler&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;What can Cape do?&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;Mirror Rake tasks as Capistrano recipes, optionally filtered by namespace or name&lt;/li&gt;
&lt;li&gt;Embed Rake tasks in a Capistrano namespace&lt;/li&gt;
&lt;li&gt;Pass arguments to Rake tasks by setting environment variables with the same names&lt;/li&gt;
&lt;li&gt;Override the default executables for local and remote Rake installations (&lt;code&gt;/usr/bin/env rake&lt;/code&gt; is the default)&lt;/li&gt;
&lt;li&gt;Enumerate Rake tasks for your own purposes&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;If you’ve ever wanted to execute a Rake task remotely, Cape can help. In your Capistrano recipes, include the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;   require 'cape'

   Cape do
     # Create Capistrano recipes for all Rake tasks.
     mirror_rake_tasks
   end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now all your Rake tasks can be invoked as Capistrano recipes. See the &lt;a href="https://raw.github.com/njonsson/cape/master/README.markdown" title="Cape’s readme at GitHub"&gt;readme&lt;/a&gt; for more Cape-abilities.&lt;/p&gt;

&lt;p&gt;Up, up, and away! &lt;img alt="end of article" src="http://media.tumblr.com/tumblr_l1pci4Wr0V1qbnl92.png"/&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/njonsson?a=cMwVYUuNFs4:1v1g3JKd00Q:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/njonsson?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/njonsson?a=cMwVYUuNFs4:1v1g3JKd00Q:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/njonsson?i=cMwVYUuNFs4:1v1g3JKd00Q:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/njonsson/~4/cMwVYUuNFs4" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/njonsson/~3/cMwVYUuNFs4/13463210545</link><guid isPermaLink="false">http://blog.nilsjonsson.com/post/13463210545</guid><pubDate>Mon, 28 Nov 2011 14:06:00 -0600</pubDate><category>ruby</category><category>programming</category><feedburner:origLink>http://blog.nilsjonsson.com/post/13463210545</feedburner:origLink></item><item><title>Taking out the trash: disposing of C♯ objects that should implement IDisposable but don't</title><description>&lt;p&gt;&lt;a href="http://www.imdb.com/title/tt0312172" title="“Monk” (2002–2009)"&gt;&lt;img align="right" src="http://media.tumblr.com/tumblr_lr3yyc5BFH1qbnl92.jpg"/&gt;&lt;/a&gt; My wife speaks of two kinds of trash: “clean” trash and “dirty” trash. This is not a distinction I consciously would have made without being married to her, but I recognize how useful the categories are. “Clean” trash (non-recyclable plastic and the like) can wait till morning for me to haul it outside and the city to pick it up, whereas “dirty” trash (cantaloupe rinds, a chicken carcass, etc) will stink up the house if left inside even for an hour.&lt;/p&gt;

&lt;p&gt;Programmers writing code for the .NET Framework deal with these categories of refuse, too. Our clean trash is pure &lt;a href="http://msdn.microsoft.com/en-us/library/ms973872.aspx" title="“An Overview of Managed/Unmanaged Code Interoperability” in the MSDN Library"&gt;managed&lt;/a&gt; code. &lt;a href="http://msdn.microsoft.com/en-us/library/system.gc.aspx" title="‘System.GC’ in the MSDN Library"&gt;The garbage man&lt;/a&gt; takes care of this for us, and we rarely have to think about it.&lt;/p&gt;

&lt;p&gt;Our dirty trash is unmanaged resources, such as handles to Win32 API objects. We want to get that stuff out of &lt;a href="http://msdn.microsoft.com/en-us/library/system.appdomain.aspx" title="‘System.AppDomain’ in the MSDN Library"&gt;the house&lt;/a&gt; as soon as we’re done with it, rather than wait for the garbage man to show up. The .NET pattern for this is that such objects must implement the &lt;a href="http://msdn.microsoft.com/en-us/library/system.idisposable.aspx" title="‘System.IDisposable’ in the MSDN Library"&gt;&lt;em&gt;IDisposable&lt;/em&gt; interface&lt;/a&gt;. C♯ provides syntactic sugar for consumers to hygienically and conveniently handle &lt;em&gt;IDisposable&lt;/em&gt; objects: &lt;a href="http://msdn.microsoft.com/en-us/library/yh598w02.aspx" title="‘using’ at the MSDN Library"&gt;the &lt;code&gt;using&lt;/code&gt; statement&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;Other people’s garbage&lt;/h3&gt;

&lt;p&gt;Sometimes while using somebody else’s &lt;small&gt;API&lt;/small&gt; you run across a particularly smelly kind of trash:&lt;/p&gt;

&lt;ol&gt;&lt;li&gt;An object allocates unmanaged resources.&lt;/li&gt;
&lt;li&gt;The object provides a method for deallocating same.&lt;/li&gt;
&lt;li&gt;The object &lt;strong&gt;does not implement &lt;em&gt;IDisposable&lt;/em&gt;.&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;An example of this software antipattern is the &lt;em&gt;OpenNETCF.Phone.Sim.Sim&lt;/em&gt; class. &lt;a href="http://opennetcf.com/library/sdf/html/290cdaba-0f3a-02f8-855d-07165f7310ae.htm" title="‘OpenNETCF.Phone.Sim.Sim’ in the OpenNETCF Smart Device Framework 2.3"&gt;Its documentation&lt;/a&gt; states:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;It is not recommended that you have more than one SIM object open in your application at one time.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This object helpfully proves a &lt;em&gt;Close&lt;/em&gt; method, but it does not implement &lt;em&gt;IDisposable&lt;/em&gt;. If it did, we could &lt;a href="http://gist.github.com/1198041"&gt;tidy up&lt;/a&gt; by writing:&lt;/p&gt;

&lt;script src="http://gist.github.com/1198041.js"&gt;&lt;/script&gt;&lt;p&gt;But instead we’re reduced to &lt;a href="http://gist.github.com/1198077"&gt;this&lt;/a&gt;:&lt;/p&gt;

&lt;script src="http://gist.github.com/1198077.js"&gt;&lt;/script&gt;&lt;p&gt;Where’s the sink? I need to wash my hands!&lt;/p&gt;

&lt;h3&gt;I’m not being paranoid if there are actually germs everywhere&lt;/h3&gt;

&lt;p&gt;I’ve written a class called &lt;em&gt;Disposer&lt;T&gt;&lt;/em&gt; that makes cleaning up dirty trash a less distasteful experience. It makes the &lt;code&gt;using&lt;/code&gt; block &lt;a href="http://gist.github.com/1198106"&gt;useful&lt;/a&gt; for such objects as OpenNETCF’s &lt;em&gt;Sim&lt;/em&gt;:&lt;/p&gt;

&lt;script src="http://gist.github.com/1198106.js"&gt;&lt;/script&gt;&lt;p&gt;See? Your hands didn’t even get dirty.&lt;/p&gt;

&lt;p&gt;Under the covers &lt;em&gt;Disposer&lt;T&gt;&lt;/em&gt; uses reflection to get at the &lt;em&gt;Close()&lt;/em&gt; method of &lt;em&gt;Sim&lt;/em&gt;. There is certainly a performance penalty for using reflection. If you’re calling the same disposal method many times, you can &lt;a href="http://gist.github.com/1198118"&gt;hang onto it and pass it to &lt;em&gt;Disposer&lt;T&gt;&lt;/em&gt;&lt;/a&gt;:&lt;/p&gt;

&lt;script src="http://gist.github.com/1198118.js"&gt;&lt;/script&gt;&lt;p&gt;I wrote &lt;a href="http://gist.github.com/1198180"&gt;this code&lt;/a&gt; in a test-driven fashion, so hopefully I’ve managed to keep the bugs away.&lt;/p&gt;

&lt;p&gt;Stay healthy! &lt;img alt="end of article" src="http://media.tumblr.com/tumblr_l1pci4Wr0V1qbnl92.png"/&gt;&lt;/p&gt;

&lt;script src="http://gist.github.com/1198180.js"&gt;&lt;/script&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/njonsson?a=8bs3Ln9rg0Y:gEflu0krRTU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/njonsson?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/njonsson?a=8bs3Ln9rg0Y:gEflu0krRTU:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/njonsson?i=8bs3Ln9rg0Y:gEflu0krRTU:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/njonsson/~4/8bs3Ln9rg0Y" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/njonsson/~3/8bs3Ln9rg0Y/9880142753</link><guid isPermaLink="false">http://blog.nilsjonsson.com/post/9880142753</guid><pubDate>Tue, 06 Sep 2011 11:29:00 -0500</pubDate><category>csharp</category><category>programming</category><feedburner:origLink>http://blog.nilsjonsson.com/post/9880142753</feedburner:origLink></item><item><title>Rebasing tags in Git repositories</title><description>&lt;p&gt;&lt;strong&gt;UPDATE:&lt;/strong&gt; I didn’t realize that &lt;a href="http://csurs.csr.uky.edu/cgi-bin/man/man2html?1+git-filter-branch" title="man page for ‘git-filter-branch(1)’"&gt;&lt;code&gt;git-filter-branch(1)&lt;/code&gt;&lt;/a&gt; has the option built in: &lt;code&gt;--tag-name-filter&lt;/code&gt;. The moral of the story is: RTFM to avoid writing unnecessary code. :-/&lt;/p&gt;

&lt;hr&gt;&lt;p&gt;&lt;a href="http://jagermeister.com"&gt;&lt;image align="right" src="http://media.tumblr.com/tumblr_ljat1evkfo1qbnl92.jpg"&gt;&lt;/image&gt;&lt;/a&gt; Perhaps you’ve noticed commits in your Git repository that you or a team member created with the wrong credentials. Perhaps you see personal email addresses instead of corporate email addresses among the commit authors. Perhaps — for reasons known only to you and the empty bottle of Jägermeister in your recycle bin — there is a commit whose author name is that ridiculous nickname you acquired in high school. These can be career-limiting maneuvers.&lt;/p&gt;

&lt;p&gt;How to fix these commits? &lt;code&gt;git-filter-branch(1)&lt;/code&gt; is the answer. Mr Google can tell you about &lt;a href="http://stackoverflow.com/questions/750172/how-do-i-change-the-author-of-a-commit-in-git" title="“How do I change the author of a commit in git?” at Stack Overflow"&gt;how to use&lt;/a&gt; &lt;a href="http://csurs.csr.uky.edu/cgi-bin/man/man2html?1+git-filter-branch" title="man page for ‘git-filter-branch(1)’"&gt;it&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;After you’ve used &lt;code&gt;git-filter-branch(1)&lt;/code&gt; to rewrite history, you’ll notice that all the tags you had created on that branch are gone!&lt;/p&gt;

&lt;p&gt;Don’t panic. The tags still exist, but they are pointing to the original commits prior to your rewriting exercise. You have to manually update these tags to point to the rewritten commits. You might try the following:&lt;/p&gt;

&lt;ol&gt;&lt;li&gt;&lt;code&gt;git tag -l&lt;/code&gt; to list all your tags.&lt;/li&gt;
&lt;li&gt;For each tag, &lt;code&gt;git show TAG_NAME&lt;/code&gt; to see the details of the old commit. Make note of the subject line, date, and hash of the old commit.&lt;/li&gt;
&lt;li&gt;Page through &lt;code&gt;git log&lt;/code&gt; looking for that subject line and date. Make note of the hash of the new commit when you find it.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git tag --force TAG_NAME NEW_COMMIT_HASH&lt;/code&gt; to update the tag.&lt;/li&gt;
&lt;li&gt;Hope that you have not mistaken one commit for another with a similar subject line and date.&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;This is a seriously mind-numbing and error-prone process, especially if you have a dozen or more tags: &lt;strong&gt;freebasing&lt;/strong&gt; not rebasing.&lt;/p&gt;

&lt;p&gt;What you really want is a &lt;code&gt;--tags&lt;/code&gt; option for &lt;code&gt;git-rebase(1)&lt;/code&gt; that would do this work for you: &lt;code&gt;git rebase --tags NAME_OF_REWRITTEN_BRANCH&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I’ve written &lt;a href="http://gist.github.com/908381"&gt;a script&lt;/a&gt; that fills the bill. You invoke it with &lt;code&gt;git-rebase-tags NAME_OF_REWRITTEN_BRANCH&lt;/code&gt;. If there is exactly one commit on that branch whose tree hash (i.e., diff) is identical to a tag, the tag gets repointed to that commit.&lt;/p&gt;

&lt;p&gt;A votre santé! &lt;img alt="end of article" src="http://media.tumblr.com/tumblr_l1pci4Wr0V1qbnl92.png"/&gt;&lt;/p&gt;

&lt;script src="http://gist.github.com/908381.js"&gt;&lt;/script&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/njonsson?a=vM0z1e4DqH0:_o7M5g1JaW8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/njonsson?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/njonsson?a=vM0z1e4DqH0:_o7M5g1JaW8:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/njonsson?i=vM0z1e4DqH0:_o7M5g1JaW8:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/njonsson/~4/vM0z1e4DqH0" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/njonsson/~3/vM0z1e4DqH0/4421450571</link><guid isPermaLink="false">http://blog.nilsjonsson.com/post/4421450571</guid><pubDate>Thu, 07 Apr 2011 14:53:00 -0500</pubDate><category>git</category><category>ruby</category><category>shell scripting</category><feedburner:origLink>http://blog.nilsjonsson.com/post/4421450571</feedburner:origLink></item><item><title>Vanquish ghoulish bit rot in Ruby source code with Bundler, GitHub, and Ruby Tracker</title><description>&lt;p&gt;&lt;strong&gt;UPDATE:&lt;/strong&gt;  I used &lt;a href="http://htty.github.com"&gt;&lt;em&gt;htty&lt;/em&gt;&lt;/a&gt; as an example project in this post, but its use of Bundler has since changed. Because &lt;em&gt;htty&lt;/em&gt; is a &lt;a href="http://rubygems.org/gems/htty"&gt;gem&lt;/a&gt;, its dependencies are now defined in &lt;a href="http://github.com/htty/htty/blob/master/htty.gemspec"&gt;&lt;em&gt;htty.gemspec&lt;/em&gt;&lt;/a&gt;, along with all &lt;em&gt;htty&lt;/em&gt;’s other RubyGems metadata.&lt;/p&gt;

&lt;p&gt;Application projects (such as Rails applications) should use the techniques described in this post; RubyGems projects should not. To understand why, read Yehuda Katz’s post on this topic, &lt;a href="http://yehudakatz.com/2010/12/16/clarifying-the-roles-of-the-gemspec-and-gemfile" title="“Clarifying the Roles of the ‘.gemspec’ and ‘Gemfile’ ” at Katz Got Your Tongue"&gt;“Clarifying the Roles of the &lt;em&gt;.gemspec&lt;/em&gt; and &lt;em&gt;Gemfile&lt;/em&gt;.”&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I’ve made some amendments (in &lt;strong&gt;bold&lt;/strong&gt; type) to this post.&lt;/p&gt;

&lt;hr&gt;&lt;p&gt;Continuously upgrading your code’s dependencies can be a chore. But when you neglect the chore, it doesn’t take long for bit rot to start haunting you.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.imdb.com/title/tt0087332" title="Ghost Busters (1984)"&gt;&lt;img align="right" src="http://media.tumblr.com/tumblr_lbg0zd1JPI1qbnl92.jpg"/&gt;&lt;/a&gt; Today your code may run bug-free on Ruby interpreters and libraries. Tomorrow those other projects will advance and thereby invite poltergeists of incompatibility into your code. Before long your code won’t run at all on the versions everybody else will be using. There will be “fire and brimstone coming down from the skies, rivers and seas boiling, forty years of darkness, earthquakes, volcanoes, the dead rising from the grave, human sacrifice, dogs and cats living together — mass hysteria.” All right, all right — you get the point.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://gembundler.com"&gt;Bundler&lt;/a&gt; was created to exorcise the demons of dependencies in Ruby projects. Here I’ll explain a Bundler best practice for defining dependencies and a tip for upgrading dependencies over time.&lt;/p&gt;

&lt;p&gt;By the way, I highly recommend getting comfortable with the combination of Bundler and &lt;a href="http://rvm.beginrescueend.com"&gt;RVM&lt;/a&gt;. It’ll help you wrangle combinations of Ruby interpreters and libraries with as much panache as Dr Venkman wrangled spooks, specters, and ghosts. You’ll say, “We came, we saw, we kicked its [&lt;a href="http://en.wikipedia.org/wiki/Standard_streams#Standard_output_.28stdout.29"&gt;stdout&lt;/a&gt;].”&lt;/p&gt;

&lt;h3&gt;Specify dependency versions in &lt;em&gt;Gemfile&lt;/em&gt;&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Gemfile&lt;/em&gt; is the file you use to describe your code’s dependencies to Bundler. Consider, for example, &lt;a href="http://github.com/htty/htty/blob/master/Gemfile"&gt;the &lt;em&gt;Gemfile&lt;/em&gt; for &lt;em&gt;htty&lt;/em&gt;&lt;/a&gt; (my console application for exploring web services and web sites). &lt;strong&gt;[Note that &lt;em&gt;htty&lt;/em&gt;’s &lt;em&gt;Gemfile&lt;/em&gt; no longer looks like this.]&lt;/strong&gt;&lt;/p&gt;

&lt;script src="http://gist.github.com/671657.js"&gt;&lt;/script&gt;&lt;p&gt;A dependency can be tightened using a version spec expression (for example, &lt;code&gt;gem 'rake', '~&gt; 0.8'&lt;/code&gt;, vs the looser &lt;code&gt;gem 'rake'&lt;/code&gt;). But &lt;em&gt;htty&lt;/em&gt;’s &lt;em&gt;Gemfile&lt;/em&gt; contains no version specs.&lt;/p&gt;

&lt;p&gt;Why is this?&lt;/p&gt;

&lt;p&gt;First, version specs are already captured in &lt;a href="http://github.com/htty/htty/blob/master/Gemfile.lock"&gt;&lt;em&gt;Gemfile.lock&lt;/em&gt;&lt;/a&gt;. (Bundler generates &lt;em&gt;Gemfile.lock&lt;/em&gt; from &lt;em&gt;Gemfile&lt;/em&gt;.) There’s no need to duplicate this information. &lt;strong&gt;[&lt;em&gt;Gemfile.lock&lt;/em&gt; is no longer under version control in the &lt;em&gt;htty&lt;/em&gt; project.]&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Second, omitting or loosening the version specs in your &lt;em&gt;Gemfile&lt;/em&gt; means you can upgrade to a newer version of a dependency using a single Bundler command: &lt;code&gt;bundle update &lt;i&gt;name-of-gem&lt;/i&gt;&lt;/code&gt;. This command regenerates &lt;em&gt;Gemfile.lock&lt;/em&gt; to reflect the newest available version of that dependency.&lt;/p&gt;

&lt;p&gt;Note that when you first add a particular dependency to a &lt;em&gt;Gemfile&lt;/em&gt;, you may wish to specify a version temporarily. For example, perhaps you want to use &lt;a href="http://rspec.info"&gt;RSpec&lt;/a&gt; v2.0.0 in your project, even though the latest available version may be 2.1.0. You would:&lt;/p&gt;

&lt;ol&gt;&lt;li&gt;Cite an older version of RSpec in &lt;em&gt;Gemfile&lt;/em&gt;: &lt;code&gt;gem 'rspec', '2.0.0'&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Update the bundle with the &lt;code&gt;bundle&lt;/code&gt; command.&lt;/li&gt;
&lt;li&gt;Remove the RSpec version spec in &lt;em&gt;Gemfile&lt;/em&gt;: &lt;code&gt;gem 'rspec'&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Commit the changes to &lt;em&gt;Gemfile&lt;/em&gt; and &lt;em&gt;Gemfile.lock&lt;/em&gt;.&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;The end result is exactly what you want. Your code depends on the desired, old version of RSpec, and your dependency configuration retains the convenience of a one-step upgrade when the need arises.&lt;/p&gt;

&lt;h3&gt;Keep up with evolving dependencies&lt;/h3&gt;

&lt;p&gt;How do you know when new versions of your dependencies are available? Must you periodically run &lt;code&gt;bundle update&lt;/code&gt; to see what happens?&lt;/p&gt;

&lt;p&gt;Enter &lt;a href="http://rubytracker.com"&gt;Ruby Tracker&lt;/a&gt;, a useful addition to the GitHub open-source ecosystem. Ruby Tracker watches your project’s &lt;em&gt;Gemfile.lock&lt;/em&gt; in your GitHub repository. It alerts you when new versions of the gems you depend on become available.&lt;/p&gt;

&lt;p&gt;Gregg Pollack has a great little &lt;a href="http://www.youtube.com/watch?v=YMC-TV2FCXg" title="Ruby Tracker video on YouTube"&gt;video explaining more about Ruby Tracker&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Create a Ruby Tracker account today and set it up to help you banish bit rot from your Ruby projects. &lt;img alt="end of article" src="http://media.tumblr.com/tumblr_l1pci4Wr0V1qbnl92.png"/&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/njonsson?a=I-d0fbu0ILU:wsMIdvr-R04:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/njonsson?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/njonsson?a=I-d0fbu0ILU:wsMIdvr-R04:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/njonsson?i=I-d0fbu0ILU:wsMIdvr-R04:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/njonsson/~4/I-d0fbu0ILU" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/njonsson/~3/I-d0fbu0ILU/1539806410</link><guid isPermaLink="false">http://blog.nilsjonsson.com/post/1539806410</guid><pubDate>Wed, 10 Nov 2010 22:03:00 -0600</pubDate><category>ruby</category><category>programming</category><feedburner:origLink>http://blog.nilsjonsson.com/post/1539806410</feedburner:origLink></item><item><title>‘htty’ v1.1 is now available</title><description>&lt;p&gt;&lt;a href="http://www.imdb.com/title/tt0058805"&gt;&lt;img align="right" alt="Maxwell Smart with early ‘htty’ handset?" src="http://media.tumblr.com/tumblr_lbg0wr6dtU1qbnl92.jpg"/&gt;&lt;/a&gt; Since its &lt;a href="http://blog.nilsjonsson.com/post/1076166313/introducing-htty-the-http-tty" title="my earlier post, “Introducing ‘htty’, the HTTP TTY”"&gt;release&lt;/a&gt; three weeks ago, lots of people have started using my console application for HTTP called &lt;em&gt;htty&lt;/em&gt;. It’s been called the perfect tool for exploring web services.&lt;/p&gt;

&lt;p&gt;Install it with &lt;a href="http://gist.github.com/567189"&gt;one command&lt;/a&gt;.&lt;/p&gt;

&lt;script src="http://gist.github.com/567189.js"&gt;&lt;/script&gt;&lt;p&gt;You’ll need Ruby and RubyGems. It’s known to work well under OS X against Ruby v1.8.7 and v1.9.2.&lt;/p&gt;

&lt;p&gt;There’s a new version out today. What’s new?&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;HTTP Secure support&lt;/li&gt;
&lt;li&gt;HTTP Basic Authentication support&lt;/li&gt;
&lt;li&gt;Support for arrow keys and Emacs key bindings (thanks, &lt;a href="http://github.com/rbxbx" title="Robert Pitts’s profile at GitHub"&gt;rbxbx&lt;/a&gt;!)&lt;/li&gt;
&lt;li&gt;Support for Ctrl-D for terminating input (thanks, &lt;a href="http://github.com/bofrede" title="Bo Frederiksen’s profile at GitHub"&gt;bofrede&lt;/a&gt;!)&lt;/li&gt;
&lt;li&gt;A smarter &lt;code&gt;userinfo-set&lt;/code&gt; command that:

&lt;ul&gt;&lt;li&gt;Permits separate entry of username and (optional) password&lt;/li&gt;
&lt;li&gt;Permits colon-separated “username:password” entry&lt;/li&gt;
&lt;li&gt;Automatically URL-escapes &lt;em&gt;@&lt;/em&gt; symbols to avoid invalid URLs&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Various bug fixes&lt;/li&gt;
&lt;li&gt;Corrected and expanded built-in help content&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Check out the &lt;a href="http://htty.github.com/"&gt;updated readme&lt;/a&gt; for details on how to install and use &lt;em&gt;htty&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Enjoy! &lt;img alt="end of article" src="http://media.tumblr.com/tumblr_l1pci4Wr0V1qbnl92.png"/&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/njonsson?a=D6bLj_9-o2E:q58lcsmTYLY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/njonsson?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/njonsson?a=D6bLj_9-o2E:q58lcsmTYLY:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/njonsson?i=D6bLj_9-o2E:q58lcsmTYLY:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/njonsson/~4/D6bLj_9-o2E" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/njonsson/~3/D6bLj_9-o2E/1208503245</link><guid isPermaLink="false">http://blog.nilsjonsson.com/post/1208503245</guid><pubDate>Tue, 28 Sep 2010 22:53:00 -0500</pubDate><category>ruby</category><category>programming</category><feedburner:origLink>http://blog.nilsjonsson.com/post/1208503245</feedburner:origLink></item><item><title>Introducing ‘htty’, the HTTP TTY</title><description>&lt;p&gt;I’ve been hacking instead of writing during my spare time the last couple months. The result is &lt;a href="http://htty.github.com"&gt;a streamlined console application&lt;/a&gt; for exploring web services and web sites. It’s something of a cross between &lt;em&gt;curl&lt;/em&gt; and the Lynx browser.&lt;/p&gt;

&lt;h3&gt;Installation&lt;/h3&gt;

&lt;p&gt;&lt;a href="http://gist.github.com/567189"&gt;It couldn’t be much easier.&lt;/a&gt;&lt;/p&gt;

&lt;script src="http://gist.github.com/567189.js"&gt;&lt;/script&gt;&lt;p&gt;You’ll need Ruby and RubyGems. It’s known to work well under OS X against Ruby v1.8.7 and v1.9.2.&lt;/p&gt;

&lt;h3&gt;Features&lt;/h3&gt;

&lt;ul&gt;&lt;li&gt;Intuitive commands and command aliases&lt;/li&gt;
&lt;li&gt;Support for familiar HTTP methods &lt;em&gt;GET&lt;/em&gt;, &lt;em&gt;POST&lt;/em&gt;, &lt;em&gt;PUT&lt;/em&gt;, and &lt;em&gt;DELETE&lt;/em&gt;, as well as &lt;em&gt;HEAD&lt;/em&gt;, &lt;em&gt;OPTIONS&lt;/em&gt; and &lt;em&gt;TRACE&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Automatic URL-encoding of query-string parameters and URL fragments&lt;/li&gt;
&lt;li&gt;Transcripts, both verbose and summary&lt;/li&gt;
&lt;li&gt;Dead-simple cookie handling and redirect following&lt;/li&gt;
&lt;li&gt;Built-in help&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;The things you can do with &lt;em&gt;htty&lt;/em&gt; are:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Build a request&lt;/strong&gt; — you can tweak the address, headers, cookies, and body at will&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Send the request to the server&lt;/strong&gt; — after the request is sent, it remains unchanged in your session history&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Inspect the server’s response&lt;/strong&gt; — you can look at the status, headers, cookies, and body in various ways&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Review history&lt;/strong&gt; — a normal and a verbose transcript of your session are available at all times (destroyed when you quit &lt;em&gt;htty&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reuse previous requests&lt;/strong&gt; — you can refer to prior requests and copy them&lt;/li&gt;
&lt;/ul&gt;&lt;h3&gt;Examples&lt;/h3&gt;

&lt;p&gt;Here are a few annotated &lt;em&gt;htty&lt;/em&gt; session transcripts to get you started.&lt;/p&gt;

&lt;h4&gt;Querying a web service&lt;/h4&gt;

&lt;p&gt;This simple example shows how to explore read-only web services with &lt;em&gt;htty&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://htty.github.com/images/esvapi1.png"&gt;&lt;img align="center" alt="ESVAPI.org example #1" src="http://media.tumblr.com/tumblr_l8c2f9mZbU1qbnl92.png"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can point &lt;em&gt;htty&lt;/em&gt; at a complete or partial web URL. If you don’t supply a URL, &lt;a href="http://0.0.0.0/"&gt;http://0.0.0.0/&lt;/a&gt; (port 80) will be used. You can vary the protocol scheme, userinfo, host, port, path, query string, and fragment as you wish.&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;htty&lt;/em&gt; shell prompt shows the address of the current request.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;get&lt;/code&gt; command is one of seven HTTP request methods supported. A concise summary of the response is shown when you issue a request.&lt;/p&gt;

&lt;p&gt;You can follow redirects using the &lt;code&gt;follow&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://htty.github.com/images/esvapi2.png"&gt;&lt;img align="center" alt="ESVAPI.org example #2" src="http://media.tumblr.com/tumblr_l8c2vkNcO01qbnl92.png"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can tweak segments of the address at will. Here we are navigating the site’s path hierarchy, which you can do with relative as well as absolute pathspecs.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://htty.github.com/images/esvapi3.png"&gt;&lt;img align="center" alt="ESVAPI.org example #3" src="http://media.tumblr.com/tumblr_l8c2z49FEd1qbnl92.png"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here we add query-string parameters. Notice that characters that require URL encoding are automatically URL-encoded (unless they are part of a URL-encoded expression).&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;headers-response&lt;/code&gt; and &lt;code&gt;body-response&lt;/code&gt; commands reveal the details of a response.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://htty.github.com/images/esvapi4.png"&gt;&lt;img align="center" alt="ESVAPI.org example #4" src="http://media.tumblr.com/tumblr_l8c30wO8zq1qbnl92.png"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There was some cruft in the web service’s response (a horizontal line, a passage reference, verse numbers, a copyright stamp, and line breaks). We eliminate it by using API options provided by the web service we’re talking to.&lt;/p&gt;

&lt;p&gt;We do a Julia Child maneuver and use the &lt;code&gt;address&lt;/code&gt; command to change the entire URL, rather than add individual query-string parameters one by one.&lt;/p&gt;

&lt;p&gt;Exit your session at any time by typing &lt;code&gt;quit&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;Working with cookies&lt;/h4&gt;

&lt;p&gt;The next example demonstrates &lt;em&gt;htty&lt;/em&gt;’s cookies features, as well as how to review and revisit past requests.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://htty.github.com/images/google1.png"&gt;&lt;img align="center" alt="Google example #1" src="http://media.tumblr.com/tumblr_l8c33ij01p1qbnl92.png"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice that when cookies are offered in a response, a bold asterisk (it looks like a cookie) appears in the response summary. The same cookie symbol appears next to the &lt;em&gt;Set-Cookie&lt;/em&gt; header when you display response headers.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://htty.github.com/images/google2.png"&gt;&lt;img align="center" alt="Google example #2" src="http://media.tumblr.com/tumblr_l8c35j2CM61qbnl92.png"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;cookies-use&lt;/code&gt; command copies cookies out of the response into the next request. The cookie symbol appears next to the &lt;em&gt;Cookie&lt;/em&gt; header when you display request headers.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://htty.github.com/images/google3.png"&gt;&lt;img align="center" alt="Google example #3" src="http://media.tumblr.com/tumblr_l8c390nLY71qbnl92.png"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;An abbreviated history is available through the &lt;code&gt;history&lt;/code&gt; command. Information about requests in the history includes request method, URL, number of headers (and a cookie symbol, if cookies were sent), and the size of the body. Information about responses in the history includes response code, number of headers (and a cookie symbol, if cookies were received), and the size of the body.&lt;/p&gt;

&lt;p&gt;Note that history contains only numbered HTTP request and response pairs, not a record of all the commands you enter.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;reuse&lt;/code&gt; command makes a copy of the headers and body of an earlier request for you to build on.&lt;/p&gt;

&lt;h4&gt;Understanding complex HTTP conversations at a glance using history&lt;/h4&gt;

&lt;p&gt;Assume that we have &lt;a href="http://gist.github.com/567234"&gt;the following Sinatra application&lt;/a&gt; listening on Sinatra’s default port, 4567.&lt;/p&gt;

&lt;script src="http://gist.github.com/567234.js"&gt; &lt;/script&gt;&lt;p&gt;This application expects &lt;em&gt;GET&lt;/em&gt; and &lt;em&gt;POST&lt;/em&gt; requests and responds in various contrived ways.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://htty.github.com/images/sinatra1.png"&gt;&lt;img align="center" alt="Sinatra example #1" src="http://media.tumblr.com/tumblr_l8c3jlAg8l1qbnl92.png"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here you can see a request body being specified. Type &lt;code&gt;body-set&lt;/code&gt; to enter body data, and terminate it by typing Return three times consecutively.&lt;/p&gt;

&lt;p&gt;Also note how different response codes are rendered:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;Response codes between 200 and 299 appear black on green to indicate success&lt;/li&gt;
&lt;li&gt;Response codes between 300 and 399 appear white on blue to indicate redirection&lt;/li&gt;
&lt;li&gt;Response codes between 400 and 499 appear white on red to indicate failure&lt;/li&gt;
&lt;li&gt;Response codes between 500 and 599 appear flashing black on yellow to indicate a server error&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;a href="http://htty.github.com/images/sinatra2.png"&gt;&lt;img align="center" alt="Sinatra example #2" src="http://media.tumblr.com/tumblr_l8c3mnqjso1qbnl92.png"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As with the abbreviated history demonstrated earlier, verbose history shows a numbered list of requests and the responses they elicited. All information exchanged between client and server is shown.&lt;/p&gt;

&lt;h4&gt;Getting help&lt;/h4&gt;

&lt;p&gt;You can learn how to use &lt;em&gt;htty&lt;/em&gt; commands from within &lt;em&gt;htty&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://htty.github.com/images/help.png"&gt;&lt;img align="center" alt="Sinatra example #2" src="http://media.tumblr.com/tumblr_l8cb323z2T1qbnl92.png"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;help&lt;/code&gt; command takes an optional argument of the abbreviated or full name of a command.&lt;/p&gt;

&lt;h3&gt;Coming soon&lt;/h3&gt;

&lt;p&gt;Here are some features that are coming down the pike.&lt;/p&gt;

&lt;h4&gt;HTTP Secure URLs&lt;/h4&gt;

&lt;p&gt;The HTTPS code is broken right now. Pardon the dust.&lt;/p&gt;

&lt;h4&gt;Commands for streamlining web form submission&lt;/h4&gt;

&lt;p&gt;These features will make &lt;em&gt;htty&lt;/em&gt; better at screen-scraping.&lt;/p&gt;

&lt;p&gt;Using any of the forthcoming &lt;code&gt;form&lt;/code&gt; commands will clear any non-form content in the body of the request. Adding at least one URL-encoded form parameter to the request will set the &lt;em&gt;Content-Type&lt;/em&gt; header to &lt;em&gt;application/x-www-form-urlencoded&lt;/em&gt;. Removing all URL-encoded form parameters will remove this header.&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;code&gt;form&lt;/code&gt; — display all form parameters offered in the response&lt;/li&gt;
&lt;li&gt;&lt;code&gt;form-fill&lt;/code&gt; — prompt in turn for a value for each of the form inputs in the response&lt;/li&gt;
&lt;li&gt;&lt;tt&gt;form-add &lt;i&gt;name&lt;/i&gt; &lt;i&gt;value&lt;/i&gt;&lt;/tt&gt; — add a URL-encoded form parameter for the request, using the specified name and value&lt;/li&gt;
&lt;li&gt;&lt;tt&gt;form-remove &lt;i&gt;name&lt;/i&gt;&lt;/tt&gt; — remove a URL-encoded form parameter from the request, using the specified name&lt;/li&gt;
&lt;li&gt;&lt;code&gt;form-remove-all&lt;/code&gt; — remove all URL-encoded form parameters from the request&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;You will also be able to pop open a browser window containing request and response bodies.&lt;/p&gt;

&lt;h4&gt;Shiny &lt;em&gt;curses&lt;/em&gt; goodness&lt;/h4&gt;

&lt;p&gt;We’ll have command history using the arrow keys, command autocompletion, and Tab key navigation of forms.&lt;/p&gt;

&lt;h4&gt;Custom command aliases and shell emulation of &lt;em&gt;http-console&lt;/em&gt;&lt;/h4&gt;

&lt;p&gt;You should be able to make your own command aliases.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;http-console&lt;/em&gt; has a nice command-line. We should have an &lt;em&gt;http-console&lt;/em&gt; skin for &lt;em&gt;htty&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;Contributing&lt;/h3&gt;

&lt;p&gt;Your patches are welcome, and you will receive attribution for good stuff.&lt;/p&gt;

&lt;p&gt;Fork the official &lt;em&gt;htty&lt;/em&gt; repository located at &lt;a href="http://github.com/htty/htty"&gt;http://github.com/htty/htty&lt;/a&gt; and send a pull request to &lt;a href="http://github.com/htty"&gt;htty&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;News and information&lt;/h3&gt;

&lt;p&gt;Stay in touch with the &lt;em&gt;htty&lt;/em&gt; project by following the Twitter account: &lt;a href="http://twitter.com/get_htty"&gt;get_htty&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can also get help in the #htty channel on &lt;a href="http://webchat.freenode.net/?channels=htty"&gt;Freenode&lt;/a&gt;. &lt;img alt="end of article" src="http://media.tumblr.com/tumblr_l1pci4Wr0V1qbnl92.png"/&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/njonsson?a=-TMUXKgZlPo:EiBGytY65KI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/njonsson?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/njonsson?a=-TMUXKgZlPo:EiBGytY65KI:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/njonsson?i=-TMUXKgZlPo:EiBGytY65KI:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/njonsson/~4/-TMUXKgZlPo" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/njonsson/~3/-TMUXKgZlPo/1076166313</link><guid isPermaLink="false">http://blog.nilsjonsson.com/post/1076166313</guid><pubDate>Mon, 06 Sep 2010 11:46:00 -0500</pubDate><category>ruby</category><category>programming</category><feedburner:origLink>http://blog.nilsjonsson.com/post/1076166313</feedburner:origLink></item><item><title>Never declare another C♯ delegate again</title><description>&lt;p&gt;I recently did some refactoring of our .NET Compact Framework codebase. The goal was to tighten up our use of delegates a bit. In case you didn’t know, there’s never a need to declare custom delegates in &lt;abbr title="C-Sharp"&gt;C♯&lt;/abbr&gt; code.&lt;/p&gt;

&lt;p&gt;By way of a quick review, delegates are &lt;abbr title="C-Sharp"&gt;C♯&lt;/abbr&gt;’s strongly-typed function pointers. Closures, callbacks, and events are all implemented using delegates. The &lt;code&gt;delegate&lt;/code&gt; statement declares the signature of a function pointer and gives that signature a name. You can then assign a variable of that delegate type to a method or an anonymous function whose signature matches the delegate.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://media.tumblr.com/tumblr_l302afbh471qbnl92.jpg"&gt;&lt;img align="right" alt="Thelonious Monk, Howard McGhee, Roy Eldridge, and Teddy Hill, ca. 1947" src="http://media.tumblr.com/tumblr_l302oxf5aY1qbnl92.gif"/&gt;&lt;/a&gt; &lt;a href="http://gist.github.com/413840#file_nightclub.cs"&gt;This example&lt;/a&gt;, obtained via 1940s corporate espionage, illustrates how the club software running the legendary &lt;a href="http://en.wikipedia.org/wiki/Minton's_Playhouse" title="Minton’s Playhouse at Wikipedia"&gt;Minton’s Playhouse&lt;/a&gt; kept out unwanted patrons and novice musicians who couldn’t hack the hot new bebop tunes.&lt;/p&gt;

&lt;script src="http://gist.github.com/413840.js?file=Nightclub.cs"&gt;&lt;/script&gt;&lt;p&gt;The body of the &lt;em&gt;Nightclub#Bouncer&lt;/em&gt; function is defined outside the &lt;em&gt;Nightclub&lt;/em&gt; class, possibly in another program altogether. (That part of the source code was lost when an intrepid corporate spy died trying to smuggle it out of Minton’s. It has been painstakingly reconstructed &lt;a href="http://gist.github.com/413840#file_mintons_playhouse.cs"&gt;here&lt;/a&gt;.)&lt;/p&gt;

&lt;script src="http://gist.github.com/413840.js?file=MintonsPlayhouse.cs"&gt;&lt;/script&gt;&lt;p&gt;An annoying thing about the &lt;code&gt;delegate&lt;/code&gt; statement is that it’s hard to know where to put it. Do we nest it inside a class, as shown above? Do we put it in a separate &lt;em&gt;.cs&lt;/em&gt; file? Do we group multiple &lt;code&gt;delegate&lt;/code&gt; statements in a file, or put each one in its own file?&lt;/p&gt;

&lt;p&gt;Another misfortune of custom delegates is that each one is yet another thing that we have to come up with a name for. Naming is often &lt;a href="http://martinfowler.com/bliki/TwoHardThings.html" title="a Phil Karlton quotation via Martin Fowler"&gt;cited&lt;/a&gt; as one of the harder things programmers must do. I myself have uttered &lt;a href="http://en.wikipedia.org/wiki/Hungarian_notation" title="Hungarian notation at Wikipedia"&gt;Hungarian&lt;/a&gt; obscenities such as &lt;code&gt;delegate void VoidFormDoubleDelegate(Form form, double @double);&lt;/code&gt; when a good name escaped me or when I wanted to reuse the declaration for multiple purposes.&lt;/p&gt;

&lt;p&gt;Wouldn’t it be nice to do away with the &lt;code&gt;delegate&lt;/code&gt; statement altogether in our applications? We can.&lt;/p&gt;

&lt;p&gt;All delegates of a particular arity are alike and can be unified through generics. So all we need is a generic delegate declaration for each possible arity.&lt;/p&gt;

&lt;p&gt;Microsoft has provided those declarations in the form of the &lt;em&gt;System.Action&lt;/em&gt; and &lt;em&gt;System.Func&lt;/em&gt; generic delegates, introduced as long ago as .NET 2.0. These generic delegates accommodate nullary procedures, unary procedures, binary procedures, ternary procedures, and so forth through 10-ary procedures. (‘Nullary’ means zero parameters; it’s represented by either the &lt;em&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.action.aspx" title=".NET Framework Class Library’s System.Action delegate"&gt;System.Action&lt;/a&gt;&lt;/em&gt; delegate or the &lt;em&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/bb534960.aspx" title=".NET Framework Class Library’s System.Func&lt;TResult&gt; delegate"&gt;System.Func&lt;TResult&gt;&lt;/a&gt;&lt;/em&gt; delegate. A 10-ary procedure can use &lt;em&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/dd387291(v=VS.100).aspx" title=".NET Framework Class Library’s System.Action&lt;T1 … T10&gt; delegate"&gt;System.Action&lt;T1 … T10&gt;&lt;/a&gt;&lt;/em&gt; or &lt;em&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/dd383294(v=VS.100).aspx" title=".NET Framework Class Library’s System.Func&lt;T1 … T10, TResult&gt; delegate"&gt;System.Func&lt;T1 … T10, TResult&gt;&lt;/a&gt;&lt;/em&gt;.)&lt;/p&gt;

&lt;p&gt;Clear as mud, right?&lt;/p&gt;

&lt;p&gt;Here’s how the Minton’s code can be &lt;a href="http://gist.github.com/413865"&gt;refactored&lt;/a&gt; to eliminate the unnecessary delegate declaration. The client code using &lt;em&gt;Nightclub&lt;/em&gt; remains the same.&lt;/p&gt;

&lt;script src="http://gist.github.com/413865.js"&gt;&lt;/script&gt;&lt;p&gt;Admittedly, the refactoring amounts to a minuscule improvement in this example. Projects that make heavy use of custom delegates will benefit more dramatically.&lt;/p&gt;

&lt;p&gt;Perhaps you need a delegate for a function that has 11 parameters and a return value. In that case you need to declare your own &lt;a href="http://gist.github.com/413874"&gt;11-parameter generic delegate&lt;/a&gt; because the .NET Framework Class Library only declares generic delegates up to an arity of 10.&lt;/p&gt;

&lt;script src="http://gist.github.com/413874.js"&gt;&lt;/script&gt;&lt;p&gt;If you need to declare an 11-parameter delegate, you’ve got bigger problems to solve than the question of where to put a &lt;code&gt;delegate&lt;/code&gt; statement. &lt;img alt="end of article" src="http://media.tumblr.com/tumblr_l1pci4Wr0V1qbnl92.png"/&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/njonsson?a=tcyMw9AN6DE:zqvJ0Jh-cD0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/njonsson?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/njonsson?a=tcyMw9AN6DE:zqvJ0Jh-cD0:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/njonsson?i=tcyMw9AN6DE:zqvJ0Jh-cD0:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/njonsson/~4/tcyMw9AN6DE" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/njonsson/~3/tcyMw9AN6DE/632748350</link><guid isPermaLink="false">http://blog.nilsjonsson.com/post/632748350</guid><pubDate>Tue, 25 May 2010 19:32:00 -0500</pubDate><category>programming</category><category>csharp</category><category>dotnet</category><feedburner:origLink>http://blog.nilsjonsson.com/post/632748350</feedburner:origLink></item><item><title>A quick ’n’ clean jQuery plugin for measuring password complexity</title><description>&lt;p&gt;&lt;a href="http://www.flickr.com/photos/45025094@N00/4373613067"&gt;&lt;img alt="peanut butter kisses" align="right" src="http://media.tumblr.com/tumblr_l2c8244ctR1qbnl92.jpg"/&gt;&lt;/a&gt; The tasty morsel of the day is &lt;a href="http://gist.github.com/399181" title="a code snippet at gist.github"&gt;a simple jQuery plugin&lt;/a&gt;. It makes suggestions to the user for how to strengthen a weak password. For the purposes of this example, strong passwords contain characters in all of four categories: capital letters, lower case letters, numerals, and punctuation characters.&lt;/p&gt;

&lt;p&gt;Several jQuery and JavaScript best practices are in evidence here.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It’s written using only JavaScript’s “&lt;a href="http://oreilly.com/catalog/9780596517748" title="JavaScript: The Good Parts (2008) by Douglas Crockford"&gt;Good Parts&lt;/a&gt;.”&lt;/strong&gt; Run your code through &lt;a href="http://jslint.com"&gt;JSLint&lt;/a&gt; to find what my grandmother from Utah would have called “an accident what’s lookin’ fer a place ta happen.”&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reusable behavior is implemented as a jQuery plugin.&lt;/strong&gt; Adding behavior with jQuery is a snap. But one-off jQuery snippets can be made more maintainable and reusable by rewriting them as &lt;a href="http://docs.jquery.com/Plugins/Authoring" title="“Plugins/Authoring” in jQuery Documentation"&gt;plugins&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It plays nicely with libraries that may be in use besides jQuery.&lt;/strong&gt; Like a number of other JavaScript frameworks, jQuery defines a &lt;a href="http://api.jquery.com/jQuery" title="jQuery’s $() function"&gt;&lt;em&gt;$&lt;/em&gt; function&lt;/a&gt;. Be a conflict avoider. Tell jQuery to keep its hands to itself by invoking &lt;a href="http://api.jquery.com/jQuery.noConflict" title="jQuery’s $.noConflict method"&gt;no-conflict mode&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Behavior can be applied to multiple elements on a page.&lt;/strong&gt; An easy mistake to make in your jQuery plugin work is to assume that only one element per page will be affected by a particular behavior. If all you’re doing is altering the element itself then this may work just fine. In this example, however, we’re adding password suggestions in a &lt;code&gt;&lt;span&gt;&lt;/code&gt; next to the password input box. Each of multiple input boxes with this behavior should have its own suggestions &lt;code&gt;&lt;span&gt;&lt;/code&gt;. Note the use of &lt;a href="http://api.jquery.com/each" title="jQuery’s $.each method"&gt;&lt;em&gt;each&lt;/em&gt;&lt;/a&gt; and how we create a corresponding &lt;code&gt;&lt;span&gt;&lt;/code&gt; for each input box receiving the behavior.&lt;/p&gt;

&lt;p&gt;Bon appétit! &lt;img alt="end of article" src="http://media.tumblr.com/tumblr_l1pci4Wr0V1qbnl92.png"/&gt;&lt;/p&gt;

&lt;script src="http://gist.github.com/399181.js"&gt;&lt;/script&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/njonsson?a=zlH3xTUsFnE:HDRyJnwq-So:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/njonsson?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/njonsson?a=zlH3xTUsFnE:HDRyJnwq-So:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/njonsson?i=zlH3xTUsFnE:HDRyJnwq-So:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/njonsson/~4/zlH3xTUsFnE" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/njonsson/~3/zlH3xTUsFnE/594212479</link><guid isPermaLink="false">http://blog.nilsjonsson.com/post/594212479</guid><pubDate>Wed, 12 May 2010 22:45:00 -0500</pubDate><category>programming</category><category>javascript</category><category>jquery</category><feedburner:origLink>http://blog.nilsjonsson.com/post/594212479</feedburner:origLink></item><item><title>Throw a wrench in the works</title><description>&lt;p&gt;Programmers who come to Ruby from other languages — particularly &lt;abbr title="C-Plus-Plus"&gt;C++&lt;/abbr&gt;, &lt;abbr title="C-Sharp"&gt;C♯&lt;/abbr&gt; or Java — tend to misuse Ruby’s &lt;code&gt;throw&lt;/code&gt; statement. They type &lt;code&gt;throw&lt;/code&gt; when they mean to type &lt;code&gt;raise&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;What’s the difference?&lt;/p&gt;

&lt;p&gt;Like &lt;abbr title="C-Plus-Plus"&gt;C++&lt;/abbr&gt;, &lt;abbr title="C-Sharp"&gt;C♯&lt;/abbr&gt; and Java, Ruby has first-class support for exceptions. Exceptions can be thrown using the &lt;code&gt;raise&lt;/code&gt; statement and caught using the &lt;code&gt;rescue&lt;/code&gt; keyword. Rubyists often speak of “errors” rather than “exceptions.” This is because it’s accepted that the names of Ruby exception classes generally end in &lt;em&gt;Error&lt;/em&gt; rather than &lt;em&gt;Exception&lt;/em&gt;, excepting the base class for exceptions which is called &lt;a href="http://ruby-doc.org/core/classes/Exception.html" title="Ruby’s Exception class"&gt;&lt;em&gt;Exception&lt;/em&gt;&lt;/a&gt;. (Still with me?)&lt;/p&gt;

&lt;p&gt;You may say, “Okay, so I’ll start saying ‘error’ when I mean ‘exception.’ But why can’t I at least type the &lt;code&gt;throw&lt;/code&gt; and &lt;code&gt;catch&lt;/code&gt; keywords I’m used to typing?”&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.imdb.com/title/tt0067093" title="Fiddler on the Roof (1971)"&gt;&lt;img align="right" alt="Motel and Tzeitel" src="http://media.tumblr.com/tumblr_l1hxhh0QOi1qbnl92.gif"/&gt;&lt;/a&gt; Ruby has a distinctive language feature that consists of pairs of &lt;code&gt;throw&lt;/code&gt; and &lt;code&gt;catch&lt;/code&gt; statements. The &lt;code&gt;throw&lt;/code&gt;-&lt;code&gt;catch&lt;/code&gt; paradigm works similarly to &lt;code&gt;raise&lt;/code&gt; and &lt;code&gt;rescue&lt;/code&gt;. When Ruby encounters a &lt;code&gt;throw&lt;/code&gt; statement, like a good matchmaker, she walks back up the execution stack (“catch me a catch!”) looking for a suitable &lt;code&gt;catch&lt;/code&gt;. Here’s &lt;a href="http://gist.github.com/386008" title="a code snippet at gist.github"&gt;some code&lt;/a&gt; to illustrate.&lt;/p&gt;

&lt;script src="http://gist.github.com/386008.js"&gt;&lt;/script&gt;&lt;p&gt;What is inevitable &lt;code&gt;result&lt;/code&gt; of toiling in Anatevka? Nothing too surprising: it is being a &lt;code&gt;:pauper&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;But let’s change Tevye’s fortunes a bit and reward him richly for his labor. &lt;a href="http://gist.github.com/386009" title="another code snippet at gist.github"&gt;Take a look.&lt;/a&gt;&lt;/p&gt;

&lt;script src="http://gist.github.com/386009.js?file=rich_tevye.rb"&gt;&lt;/script&gt;&lt;p&gt;What comes of Tevye’s hard work if &lt;em&gt;deus ex machina&lt;/em&gt; descends upon the village? Tevye gets to retire to the western Caribbean, and his wife, Golde, grows a proper double chin.&lt;/p&gt;

&lt;p&gt;Just as an unrescued error causes the Ruby process to crash, so a &lt;code&gt;throw&lt;/code&gt; without a matching &lt;code&gt;catch&lt;/code&gt; will raise an error (which in turn you can rescue).&lt;/p&gt;

&lt;h3&gt;It’s not just semantics&lt;/h3&gt;

&lt;p&gt;You cannot simply throw and catch wherever you would otherwise raise and rescue. There are differences beyond that the latter is for representing exception conditions and the former for other kinds of stack popping.&lt;/p&gt;

&lt;p&gt;To begin with, (as you would expect from your experiences with other languages) &lt;code&gt;rescue NameError&lt;/code&gt; rescues errors of type &lt;a href="http://ruby-doc.org/core/classes/NameError.html" title="Ruby’s NameError class"&gt;&lt;em&gt;NameError&lt;/em&gt;&lt;/a&gt; as well as subclasses such as &lt;a href="http://ruby-doc.org/core/classes/NoMethodError.html" title="Ruby’s NoMethodError class"&gt;&lt;em&gt;NoMethodError&lt;/em&gt;&lt;/a&gt;. By analogy you might presume that &lt;code&gt;catch Entertainer&lt;/code&gt; would handle all these &lt;code&gt;throw&lt;/code&gt; statements:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;code&gt;throw Entertainer&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;throw Entertainer.new&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;throw BroadwayStar&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;throw BroadwayStar.new&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;You would be wrong: &lt;code&gt;catch Entertainer&lt;/code&gt; handles only &lt;code&gt;throw Entertainer&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Another important difference is that &lt;code&gt;throw&lt;/code&gt; can take two arguments, as demonstrated in the &lt;em&gt;Tevye&lt;/em&gt; class above. The second argument to &lt;code&gt;throw&lt;/code&gt; is what Ruby returns from the matching &lt;code&gt;catch&lt;/code&gt; statement (also demonstrated above).&lt;/p&gt;

&lt;p&gt;A further distinction is the fact that &lt;code&gt;rescue&lt;/code&gt; can appear &lt;a href="http://gist.github.com/386012" title="yet another code snippet at gist.github"&gt;more than once&lt;/a&gt; in a &lt;code&gt;begin&lt;/code&gt;-&lt;code&gt;end&lt;/code&gt; or &lt;code&gt;def&lt;/code&gt;-&lt;code&gt;end&lt;/code&gt; pair. The first matching &lt;code&gt;rescue&lt;/code&gt; in a sequence wins.&lt;/p&gt;

&lt;script src="http://gist.github.com/386012.js"&gt;&lt;/script&gt;&lt;p&gt;By contrast, &lt;code&gt;catch&lt;/code&gt; is a block construct. &lt;a href="http://gist.github.com/386013" title="yet again, another code snippet at gist.github"&gt;Multiple &lt;code&gt;catch&lt;/code&gt; statements&lt;/a&gt; must be nested in order to appear together.&lt;/p&gt;

&lt;script src="http://gist.github.com/386013.js"&gt;&lt;/script&gt;&lt;p&gt;Prior to Ruby &lt;abbr title="version"&gt;v&lt;/abbr&gt;1.9, only symbols (for example, &lt;code&gt;:pauper&lt;/code&gt;) could be thrown and caught. This restriction was removed, so now you can throw any Ruby object and catch it successfully.&lt;/p&gt;

&lt;h3&gt;The bottom line&lt;/h3&gt;

&lt;p&gt;When should you use this language feature? Not very often. As you probably noticed, my contrived example about peasant life in Tsarist Russia is a questionable application of the &lt;code&gt;throw&lt;/code&gt;-&lt;code&gt;catch&lt;/code&gt; pattern. There are two plausible examples in &lt;a href="http://ruby-doc.org/docs/ProgrammingRuby/html/tut_exceptions.html#S4" title="“Catch and Throw” in Programming Ruby (2001) by Dave Thomas and Andy Hunt"&gt;the Pickaxe book&lt;/a&gt;. Fundamentally, &lt;code&gt;throw&lt;/code&gt;-&lt;code&gt;catch&lt;/code&gt; is a way to escape from the bowels of multiple layers of control flow without abusing &lt;code&gt;raise&lt;/code&gt;-&lt;code&gt;rescue&lt;/code&gt; for this purpose.&lt;/p&gt;

&lt;p&gt;But if you have so many layers of flow control that you’re tempted to &lt;code&gt;throw&lt;/code&gt; in order to get out of them quickly, consider trying to eliminate the layers first. &lt;img alt="end of article" src="http://media.tumblr.com/tumblr_l1pci4Wr0V1qbnl92.png"/&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/njonsson?a=ojni6N49wbs:pkZizqjzMHQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/njonsson?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/njonsson?a=ojni6N49wbs:pkZizqjzMHQ:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/njonsson?i=ojni6N49wbs:pkZizqjzMHQ:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/njonsson/~4/ojni6N49wbs" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/njonsson/~3/ojni6N49wbs/562328378</link><guid isPermaLink="false">http://blog.nilsjonsson.com/post/562328378</guid><pubDate>Fri, 30 Apr 2010 22:31:00 -0500</pubDate><category>programming</category><category>ruby</category><feedburner:origLink>http://blog.nilsjonsson.com/post/562328378</feedburner:origLink></item></channel></rss>

