<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;CEMERH04fCp7ImA9WhNXGEg.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117</id><updated>2012-12-06T19:53:25.334-08:00</updated><category term="apache" /><category term="opinionated" /><category term="DVCS" /><category term="business" /><category term="Microsoft" /><category term="postgres" /><category term="p2p" /><category term="personal" /><category term="appliance" /><category term="Mongrel" /><category term="Bootstrap" /><category term="fcgid" /><category term="programming" /><category term="Google Docs" /><category term="Free Software" /><category term="Entertainment" /><category term="apt" /><category term="cucumber" /><category term="ffmpeg" /><category term="music" /><category term="GNU" /><category term="Bazaar" /><category term="NetBeans" /><category term="Blogger" /><category term="Refactoring" /><category term="Gnome" /><category term="Open Source" /><category term="free culture" /><category term="BDDBlog" /><category term="appserver" /><category term="Syntax" /><category term="RSpec" /><category term="agile" /><category term="Git" /><category term="KanbanOnRails" /><category term="Ruby" /><category term="Linux" /><category term="rails" /><category term="CFLAGS" /><category term="debian" /><category term="Launchpad" /><category term="Lazy" /><category term="tdd" /><category term="datetime" /><category term="ubuntu" /><category term="Facebook" /><category term="authlogic" /><category term="SOPA" /><title>Michael Greenly</title><subtitle type="html">Ruby, Rails, Ubuntu and what ever else.</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://blog.michaelgreenly.com/" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>88</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>88</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/MichaelGreenly" /><feedburner:info uri="michaelgreenly" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><geo:lat>46.131798</geo:lat><geo:long>-92.71377</geo:long><link rel="license" type="text/html" href="http://creativecommons.org/licenses/by-sa/2.0/" /><entry gd:etag="W/&quot;CEUGQXsyeip7ImA9WhVaGUQ.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-2908027067126266892</id><published>2012-06-17T09:34:00.000-07:00</published><updated>2012-06-17T21:03:40.592-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-06-17T21:03:40.592-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><title>Just Maybe, Maybe - Pattern in Ruby</title><content type="html">&lt;span style="background-color: yellow;"&gt;The original code I posted was flawed. &amp;nbsp;The gist below is modified and I think would work but it's not as clear as I'd like it to be. &amp;nbsp;I'll follow up on this soon.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
I recently released a tiny Gem called &lt;a href="https://github.com/mgreenly/just_maybe"&gt;JustMaybe&lt;/a&gt;. &amp;nbsp;This caused me to do more reading on the subject. &amp;nbsp;I ran across the&amp;nbsp;&lt;a href="http://robots.thoughtbot.com/post/8181879506/if-you-gaze-into-nil-nil-gazes-also-into-you"&gt;If you gaze into nil nil gazes also into you&lt;/a&gt;&amp;nbsp;post. &amp;nbsp;In the JustMaybe readme I sort of mention this but I wanted to express it more clearly here. &lt;br /&gt;
&lt;br /&gt;
I don't really think using Maybe mixed in with the logic of your application is a good idea. &amp;nbsp;&lt;strike&gt;As an example I think the problem presented in that article could be solved much more clearly with this bit of code&lt;/strike&gt;. &amp;nbsp;Here's a solution that will never return nil.&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/2944913.js"&gt;
 
&lt;/script&gt;
&lt;br /&gt;
&lt;br /&gt;
My suggestion is that if you find yourself wrestling with possible nil return values . &amp;nbsp;See if you can turn the operation on it's head. &amp;nbsp;Don't ask your object about it's associations. &amp;nbsp;Ask the association about your object. &amp;nbsp;I often find this will clean up the logic.&lt;br /&gt;
&lt;br /&gt;
I did however just release &lt;a href="https://github.com/mgreenly/just_maybe"&gt;JustMaybe&lt;/a&gt; so obviously I think it's useful in some way? &amp;nbsp;For me that's almost strictly in presentation. &amp;nbsp;When you are presenting information you often have to reach deep down into the&amp;nbsp;hierarchy&amp;nbsp;of objects to extract the necessary bits. &amp;nbsp;Interestingly, at presentation, is when I think you should be deciding what to display when information is missing. &amp;nbsp;To me that creates a perfect situation for using the Maybe pattern.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=GihwWUV3vz8:r1GjemnqkFM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/GihwWUV3vz8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/2908027067126266892/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=2908027067126266892" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/2908027067126266892?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/2908027067126266892?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/GihwWUV3vz8/just-maybe-maybe-pattern-in-ruby.html" title="Just Maybe, Maybe - Pattern in Ruby" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2012/06/just-maybe-maybe-pattern-in-ruby.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkYFQ3w7eSp7ImA9WhVTE0g.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-3388043488910563412</id><published>2012-02-27T07:54:00.001-08:00</published><updated>2012-02-27T07:55:12.201-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-02-27T07:55:12.201-08:00</app:edited><title>Apache HTTP to HTTPS Redirect</title><content type="html">&lt;br /&gt;
Here's a micro-nugget. The following Apache config redirects incoming HTTP traffic to the equivalent HTTPS page.  Nothing special but I don't spend enough time working on Apache configurations to keep this stuff fresh in my mind so I find it useful to record what I learn in case I need to do it again later.
&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="white-space: pre-wrap; word-wrap: break-word;"&gt;
&amp;lt;virtualhost *:80&amp;gt;
  RedirectMatch permanent /(.*)$ https://example.com/$1
&amp;lt;/virtualhost&amp;gt;

&amp;lt;virtualhost *:443&amp;gt;
  ServerName example.com
  # config...
&amp;lt;/virtualhost&amp;gt;
&lt;/pre&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=W8yaEHLcbl8:E4QqgRyTmkw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/W8yaEHLcbl8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/3388043488910563412/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=3388043488910563412" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/3388043488910563412?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/3388043488910563412?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/W8yaEHLcbl8/apache-http-to-https-redirect.html" title="Apache HTTP to HTTPS Redirect" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2012/02/apache-http-to-https-redirect.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0cFR30zeSp7ImA9WhRaF0o.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-4527552002095625663</id><published>2012-02-20T12:48:00.000-08:00</published><updated>2012-02-20T12:50:16.381-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-02-20T12:50:16.381-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><category scheme="http://www.blogger.com/atom/ns#" term="datetime" /><title>Extending Date Parsing In Ruby 1.9.3</title><content type="html">&lt;br /&gt;
&lt;span style="font-size: large;"&gt;I had previously made posts about parsing user supplied dates in Ruby&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blog.michaelgreenly.com/2012/01/more-parsing-user-supplied-dates-and.html"&gt;http://blog.michaelgreenly.com/2012/01/more-parsing-user-supplied-dates-and.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.michaelgreenly.com/2012/01/parsing-user-supplied-dates-and-times.html"&gt;http://blog.michaelgreenly.com/2012/01/parsing-user-supplied-dates-and-times.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Apparently in Ruby 1.9.3 the Date library was re-implemented in C for performance and of course that broke my extension. &amp;nbsp;I updated it to support Ruby 1.9.3 below&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1871238.js"&gt;
 
&lt;/script&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;This may not work on Ruby versions prior to 1.9.3 I didn't try it.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;I also found the &lt;a href="https://github.com/jeremyevans/ruby-american_date"&gt;american_date&lt;/a&gt; gem which apparently existed before I had originally written my extension and is almost certainly a better choice if you don't need any custom formats.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=zZMIO49h6RM:uzjJmglpCkg:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/zZMIO49h6RM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/4527552002095625663/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=4527552002095625663" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/4527552002095625663?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/4527552002095625663?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/zZMIO49h6RM/extending-date-parsing-in-ruby-193.html" title="Extending Date Parsing In Ruby 1.9.3" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2012/02/extending-date-parsing-in-ruby-193.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUQFSXc9eCp7ImA9WhRbFUg.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-1801325084991030218</id><published>2012-02-06T10:23:00.000-08:00</published><updated>2012-02-06T10:35:18.960-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-02-06T10:35:18.960-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Lazy" /><category scheme="http://www.blogger.com/atom/ns#" term="Ruby" /><title>Generic ".rvmrc" File For Ruby Projects</title><content type="html">&lt;br /&gt;
&lt;span style="background-color: white; color: #333333; line-height: 20px; text-align: left;"&gt;&lt;span style="font-family: inherit;"&gt;I'm really lazy and have started using the exact same ".rvmrc" file for all my Ruby projects....&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre&gt;rvm use @$(basename `pwd`) --create&lt;/pre&gt;
&lt;br /&gt;
&lt;span style="font-family: inherit;"&gt;&lt;span style="background-color: white; line-height: 20px; text-align: left;"&gt;&lt;span style="color: #333333;"&gt;I'm not sure but I think I first seen this exact format while reading this code&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;a href="https://github.com/dkubb/veritas"&gt;https://github.com/dkubb/veritas&lt;/a&gt;&lt;/span&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=OkCWRmaD_EY:z__dIByUAoE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/OkCWRmaD_EY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/1801325084991030218/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=1801325084991030218" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/1801325084991030218?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/1801325084991030218?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/OkCWRmaD_EY/generic-rvmrc-file-for-ruby-projects.html" title="Generic &quot;.rvmrc&quot; File For Ruby Projects" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2012/02/generic-rvmrc-file-for-ruby-projects.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEEBRno4fSp7ImA9WhRbFUg.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-8772620224127564874</id><published>2012-01-27T08:37:00.000-08:00</published><updated>2012-02-06T10:24:17.435-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-02-06T10:24:17.435-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Lazy" /><category scheme="http://www.blogger.com/atom/ns#" term="Ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><category scheme="http://www.blogger.com/atom/ns#" term="postgres" /><title>Generic "config/database.yml" for Postgres</title><content type="html">I'm really lazy and always use the exact same "config/database.yml" file with my Rails projects....
&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1689643.js"&gt; &lt;/script&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=a4sRrrvQXOc:BPeXIOqdrKg:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/a4sRrrvQXOc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/8772620224127564874/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=8772620224127564874" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/8772620224127564874?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/8772620224127564874?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/a4sRrrvQXOc/generic-configdatabaseyml-for-postgres.html" title="Generic &quot;config/database.yml&quot; for Postgres" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2012/01/generic-configdatabaseyml-for-postgres.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0UHRXk6fyp7ImA9WhRVFkU.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-7749982836613975560</id><published>2012-01-07T11:20:00.000-08:00</published><updated>2012-01-15T20:47:14.717-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-15T20:47:14.717-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="SOPA" /><title>What The Hell Is SOPA?</title><content type="html">&lt;div style="text-align: left;"&gt;
&lt;span style="font-family: inherit; line-height: 16px;"&gt;Here's some links and a bit of explanation if you're new to the debate about SOPA.&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;span style="font-family: inherit; line-height: 16px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;span style="font-family: inherit; line-height: 16px;"&gt;I think the best place to start is this clip from &lt;a href="http://bit.ly/xioJ0x"&gt;"Up with Chris Hayes"&lt;/a&gt;&amp;nbsp;on MSNBC which provides a fairly good intro. &amp;nbsp;The biggest problem I have with this video is that NBC exec, Richard Cotten, is never challenged in his assertion that it only covers foreign sites. &amp;nbsp;You can see Fred von Lohman, a laywer from Google and the EFF, in this &lt;a href="http://bit.ly/zzhyZM"&gt;video from the Standford Center for Internet and Society&lt;/a&gt; rebuff Cotten's position.&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;span style="font-family: inherit; line-height: 16px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;span style="font-family: inherit; line-height: 16px;"&gt;In the first video a poor attempt is made to present Internet piracy as a service problem. &amp;nbsp;That happens to be a view I agree with. &amp;nbsp;I think it's expressed much more eloquently by Tim O'Reilly in this &lt;a href="http://bit.ly/w2BrZP"&gt;Gigaom article&lt;/a&gt;&amp;nbsp;or by Gotham Gal in this &lt;a href="http://bit.ly/x6g2nY"&gt;AVC.com post&lt;/a&gt;. &amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;span style="font-family: inherit; line-height: 16px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;span style="font-family: inherit;"&gt;&lt;span style="line-height: 16px;"&gt;Richard Cotten argues against "the service problem" by pointing out that Netflix, Hulu and others exist. &amp;nbsp;What he doesn't mention is they're prevented by licensing from providing the content consumers want. &amp;nbsp;In this blog post you can see&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: inherit;"&gt;&lt;span style="line-height: 16px;"&gt;&lt;a href="http://bit.ly/A3dqCj"&gt;Netflix only had 5 of the top 100 box office titles&lt;/a&gt; available last year. &amp;nbsp;The best score was by Amazon which only had 45 of the top 100 titles, less than half. &amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: inherit;"&gt;&lt;span style="line-height: 16px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: inherit;"&gt;&lt;span style="line-height: 16px;"&gt;Until they make the content available when people want to see it on which ever device or service they want to view it they have no footing in the argument against it being a service problem.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: inherit;"&gt;&lt;span style="line-height: 16px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="line-height: 16px;"&gt;There's a ton more material out there but that's a good start if you're new to the topic.&lt;/span&gt;&lt;br /&gt;
&lt;span style="line-height: 16px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=sT1qwCHplt8:2GpgmdF2DoE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/sT1qwCHplt8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/7749982836613975560/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=7749982836613975560" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/7749982836613975560?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/7749982836613975560?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/sT1qwCHplt8/what-hell-is-sopa.html" title="What The Hell Is SOPA?" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2012/01/what-hell-is-sopa.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkQFQ30ycSp7ImA9WhRWGUg.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-6156203012426724465</id><published>2012-01-06T19:25:00.000-08:00</published><updated>2012-01-07T09:45:12.399-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-07T09:45:12.399-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><category scheme="http://www.blogger.com/atom/ns#" term="datetime" /><title>More Parsing User Supplied Dates and Times in Rails</title><content type="html">&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Rails does a pretty good job of making work with time zones feel transparent. &amp;nbsp;If you do everything it's way, including use ActionView::Helpers::DateHelper. &amp;nbsp;&lt;/span&gt;&lt;span style="font-size: large;"&gt;If you use a Javascript control that returns a text input field or if you allow the users to enter values directly or need to process uploaded content things get a bit more complicated.&lt;/span&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;If the string returned by the text input can be parsed by Date._parse your in luck. &amp;nbsp;Everything will still work as expected with no extra effort. &amp;nbsp;If on the other hand you want to do something as simple as display U.S. style dates, in the format "MM/DD/YYYY", you will have to manually parse the input. &amp;nbsp;Ruby's Date._parse understands 'YYYY/MM/DD' and 'DD/MM/YYYY' but not 'MM/DD/YYYY'. &amp;nbsp;In the case where you're processing the input from a Javascript control the most direct solution is to do something like this...&lt;/span&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1573618.js"&gt;&lt;/script&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;T&lt;/span&gt;&lt;span style="font-size: large;"&gt;he example above does return a time value in the current timezone and will work as expected. &amp;nbsp;One big problem with strptime is that it isn't very flexible, the input string must match the provided format string exactly right down the the separator characters and spaces. &amp;nbsp;So this approach can work if your processing the output of a control but tends to fail if you need to process human input.&lt;/span&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Another problem I have with the approach above is that it quickly becomes incredibly redundant if you're working with a large number of date/time fields in many different models. &amp;nbsp;To Dry that up a bit I decided to move my specialized processing into a modified version of Date._parse. &amp;nbsp;This means I don't have to litter my controllers with date time parsing code and I have a single entry point to test that all desired formats are supported.&lt;/span&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1573519.js"&gt;&lt;/script&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Basically all this is doing is taking the input string and re-arranging the values into an order the original method will understand. &amp;nbsp;The biggest disadvantage to this problem is that it doesn't support per-locale input formats. &amp;nbsp;It guess I'll cross that bridge if I ever get to it.&lt;/span&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=xTWjOUpagmc:y_7IwiFv-pw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/xTWjOUpagmc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/6156203012426724465/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=6156203012426724465" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/6156203012426724465?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/6156203012426724465?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/xTWjOUpagmc/more-parsing-user-supplied-dates-and.html" title="More Parsing User Supplied Dates and Times in Rails" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2012/01/more-parsing-user-supplied-dates-and.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DE8DR3w4eSp7ImA9WhRWGU0.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-1921006441828013255</id><published>2012-01-06T18:06:00.000-08:00</published><updated>2012-01-06T19:27:56.231-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-06T19:27:56.231-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><category scheme="http://www.blogger.com/atom/ns#" term="datetime" /><category scheme="http://www.blogger.com/atom/ns#" term="postgres" /><title>Another Quick Rails/Postgres Tip</title><content type="html">&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Assuming your local timezone is not 'UTC' you most likely will want to configure Postgres to use it anyway on your development machine so that your development environment behaves like your production environment. &amp;nbsp;To do this just&amp;nbsp;&lt;/span&gt;&lt;span style="font-size: large;"&gt;find the 'timezone=' line in postgresql.conf and set it to 'UTC'.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=BM8hyFVS7WE:5gOrrLRdAKY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/BM8hyFVS7WE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/1921006441828013255/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=1921006441828013255" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/1921006441828013255?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/1921006441828013255?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/BM8hyFVS7WE/another-quick-railspostgres-tip.html" title="Another Quick Rails/Postgres Tip" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2012/01/another-quick-railspostgres-tip.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DE8AQX0_eSp7ImA9WhRWGU0.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-4289026120646782597</id><published>2012-01-04T19:31:00.000-08:00</published><updated>2012-01-06T19:27:20.341-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-06T19:27:20.341-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><category scheme="http://www.blogger.com/atom/ns#" term="datetime" /><title>Parsing User Supplied Dates and Times In Ruby</title><content type="html">&lt;br /&gt;
&lt;span style="font-size: large;"&gt;I'm in the middle of correcting some date/time handling in a Rails app.  One of things that was wrong was the handling of user input date/time fields. &amp;nbsp;Obviously when users provide date/time values they're assuming we understand the information was provided from the perspective of their timezone. &amp;nbsp;Especially when we don't explicitly require them to provide timezone information.&lt;/span&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;The problem with this is that Ruby's DateTime.parse method always returns UTC based times. &amp;nbsp;You can see this clearly in the example below:&lt;/span&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1563536.js"&gt;
 
&lt;/script&gt;
&lt;span style="font-size: large;"&gt;You can see the problem on the 6th line in the example above. &amp;nbsp;Even though the user input "2011/01/01T00:00" when that DateTime instance is converted to localtime the current timezone offset was subtracted. &amp;nbsp;In this case resulting in a time that's 6 hours earlier than desired.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;The solution is straight forward of course. You just have to add the inverse of the users timezone offset to the value returned from DateTime.parse as demonstrated below.&lt;/span&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1563503.js"&gt;
&lt;/script&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;On line 4 you can see it's correct even when converted from UTC to local time.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;As an alternative you could include the timezone information before parsing it but that's not always easy because you don't necessarily now the format of the user's input.
&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Of course all of this is generally pretty obvious but I shared just in case it can help some one less familiar with the issues.&lt;/span&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=X5sr2q_GVoM:8mgnG4uvjtY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/X5sr2q_GVoM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/4289026120646782597/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=4289026120646782597" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/4289026120646782597?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/4289026120646782597?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/X5sr2q_GVoM/parsing-user-supplied-dates-and-times.html" title="Parsing User Supplied Dates and Times In Ruby" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2012/01/parsing-user-supplied-dates-and-times.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DE8GQ3o4cSp7ImA9WhRWGU0.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-5434410529074915268</id><published>2012-01-03T18:13:00.000-08:00</published><updated>2012-01-06T19:27:02.439-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-06T19:27:02.439-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><category scheme="http://www.blogger.com/atom/ns#" term="datetime" /><category scheme="http://www.blogger.com/atom/ns#" term="postgres" /><title>Time Zones in Rails using Postgres</title><content type="html">&lt;br /&gt;
&lt;span style="font-size: large;"&gt;It appears that by default Rails creates it's timestamps in Postgres using timestamps without time zone information. &amp;nbsp;This means that if you're working directly with the database, using psql for example, and want to see local time representations you'll have to do something like this.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1558038.js"&gt;
&lt;/script&gt;
&lt;span style="font-size: large;"&gt;Specifically notice that I'm using the TIMEZONE function to re-cast the column to a timestamp with timezone. &amp;nbsp;Since the columns implied timezone is 'UTC' that's what's used. &amp;nbsp;Now that we have a timestamp with timezone we can convert that to local time using the "AT TIME ZONE" syntax.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=xPAjEudjIYA:JSu36UK3sh4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/xPAjEudjIYA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/5434410529074915268/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=5434410529074915268" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/5434410529074915268?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/5434410529074915268?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/xPAjEudjIYA/time-zones-in-rails-using-postgres.html" title="Time Zones in Rails using Postgres" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2012/01/time-zones-in-rails-using-postgres.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEYGRnkycCp7ImA9WhRWGU0.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-3729049658770888350</id><published>2011-12-27T21:24:00.000-08:00</published><updated>2012-01-06T18:08:47.798-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-06T18:08:47.798-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><category scheme="http://www.blogger.com/atom/ns#" term="Bootstrap" /><title>More on Twitter Bootstrap in Rails</title><content type="html">&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;a href="http://blog.michaelgreenly.com/2011/12/formatting-rails-errors-for-twitter.html"&gt;Yesterday&lt;/a&gt; I wrote about error handling in Rails while using Twitter Bootstrap. &amp;nbsp;One of the interesting things I was able to do with the custom form builder was move the active record attribute errors to the input fields they're associated with. &amp;nbsp;&lt;/span&gt;&lt;span style="font-size: large;"&gt;The example below is a bit simple but it should get the point across....&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-_UkbmwwiGzs/TvqmpGZEFAI/AAAAAAAABZo/JBo1C8_bpVQ/s1600/Screenshot+at+2011-12-27+23%253A17%253A40.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;span style="font-size: large;"&gt;&lt;img border="0" height="416" src="http://3.bp.blogspot.com/-_UkbmwwiGzs/TvqmpGZEFAI/AAAAAAAABZo/JBo1C8_bpVQ/s640/Screenshot+at+2011-12-27+23%253A17%253A40.png" width="640" /&gt;&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;span style="font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: large;"&gt;If you look at the template that created the form below you can see that that it doesn't include any special functionality. &amp;nbsp;All the work happens in the form builder. &lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;script src="https://gist.github.com/1526419.js"&gt;
&lt;/script&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: large;"&gt;If you look at the "text_field" method in the code below you can see that it just calls "input_wrapper" to add some html around the "text_field". &amp;nbsp;Since "input_wrapper" already had to test each active record attribute for errors so that it could add "error" to the classes of those elements it was pretty straight forward to tack an inline-help span on the end. 
&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;script src="https://gist.github.com/1526415.js"&gt;
&lt;/script&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: large;"&gt;The code above is not elegant, it's just an experiment. &amp;nbsp;I certainly don't&amp;nbsp;recommend&amp;nbsp;using it as is but I wanted to share just in case some one is thinking about similar problems.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: large;"&gt;In general though I am fairly happy with the separation of concerns so far. &amp;nbsp;I think that by treating the multi-element fields bootstrap expects in it's forms as primitives I will be able keep my templates focused on the content and my presenters on the logic of the view.&lt;/span&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=0fKn0lfbMRU:QJj7juQxY_8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/0fKn0lfbMRU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/3729049658770888350/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=3729049658770888350" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/3729049658770888350?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/3729049658770888350?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/0fKn0lfbMRU/more-on-twitter-bootstrap-in-rails.html" title="More on Twitter Bootstrap in Rails" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-_UkbmwwiGzs/TvqmpGZEFAI/AAAAAAAABZo/JBo1C8_bpVQ/s72-c/Screenshot+at+2011-12-27+23%253A17%253A40.png" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2011/12/more-on-twitter-bootstrap-in-rails.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0YBRnY6eSp7ImA9WhRXGUg.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-5285231970333470787</id><published>2011-12-26T20:12:00.000-08:00</published><updated>2011-12-26T20:12:37.811-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-26T20:12:37.811-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><category scheme="http://www.blogger.com/atom/ns#" term="Bootstrap" /><title>Formatting Rails Errors for Twitter Bootstrap</title><content type="html">I'm using Twitter's Bootstrap toolkit for the layout in a proof of concept application I'm working on. &amp;nbsp;So far my general impression is that I really like Bootstrap but there are a few obstacles to making it play nice with Rails. &lt;br /&gt;
&lt;br /&gt;
One of those obstacles is that Rails formats fields with errors quite a bit differently than Bootstrap's CSS expects. &amp;nbsp;Below I describe a possible solution. &amp;nbsp;I'm not 100% sure this is the best approach but it seems to work well and I'm currently working on a proof of concept app that will be thrown out in several weeks so there's little risk if I'm wrong.&lt;br /&gt;
&lt;br /&gt;
Rails default formatting looks like this...&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1522584.js"&gt;
&lt;/script&gt;

&lt;br /&gt;
Bootstrap's CSS expects this....&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1522591.js"&gt;
&lt;/script&gt;

&lt;br /&gt;
The solution I've arrived at is to first remove the "field_with_errors" div. &amp;nbsp;This is done by setting the field_error_proc to simply return the html passed in without wrapping it.&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1522595.js"&gt;
&lt;/script&gt;

&lt;br /&gt;
The next step was to create a FormBuilder subclass with the desired functionality. &amp;nbsp;The example below only demonstrates the 'text_field' method. &amp;nbsp;In practice I'll have to create a separate method for each Bootstrap form element I want to use in my application.&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1522609.js"&gt;
&lt;/script&gt;
&lt;br /&gt;
Then to use the custom form builder I'd do somthing like this....&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1522651.js"&gt;
 
&lt;/script&gt;
&lt;br /&gt;
I realize this wasn't exactly a detailed explanation of a solution but hopefully I managed to get the gist of the idea across.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=fYf7UusAp9k:LvCYxb5fB1A:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/fYf7UusAp9k" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/5285231970333470787/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=5285231970333470787" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/5285231970333470787?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/5285231970333470787?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/fYf7UusAp9k/formatting-rails-errors-for-twitter.html" title="Formatting Rails Errors for Twitter Bootstrap" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2011/12/formatting-rails-errors-for-twitter.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUQDSHgzcSp7ImA9WhRXFkg.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-2996226755040164771</id><published>2011-12-23T08:22:00.000-08:00</published><updated>2011-12-23T08:22:59.689-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-23T08:22:59.689-08:00</app:edited><title>Just Doing It!</title><content type="html">Almost 18 months ago a had an an epiphany. &amp;nbsp;I'm not exactly sure what caused the thought to form but I know when it happened. &amp;nbsp;I'm certain I know when because I shared the idea in an email with a friend&amp;nbsp;the moment the thought completed&amp;nbsp;synthesizing&amp;nbsp;it's self.&lt;br /&gt;
&lt;br /&gt;
It's taken me a long time to put together a plan that I thought would let me&amp;nbsp;execute on the idea sucessfully but I think I've finally gotten there. &amp;nbsp;Today, I'm shifting gears. &amp;nbsp;I'm no longer just thinking about the idea, I'm acting on it. &lt;br /&gt;
&lt;br /&gt;
In fact I'm jumping in with both feet right now!&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=gqdzL32F7FA:WOdTQU_e-aM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/gqdzL32F7FA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/2996226755040164771/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=2996226755040164771" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/2996226755040164771?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/2996226755040164771?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/gqdzL32F7FA/just-doing-it.html" title="Just Doing It!" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2011/12/just-doing-it.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEYMQHw-eip7ImA9WhRXFkw.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-5472911723507345074</id><published>2011-12-22T19:49:00.000-08:00</published><updated>2011-12-22T19:49:41.252-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-22T19:49:41.252-08:00</app:edited><title>Simple EC2 Configuration</title><content type="html">&lt;span style="font-family: inherit;"&gt;Over the last few years I've used different approaches to scripting the configuration of my EC2 servers. Recently I discarded a more sophisticated approach for a very simple system. &amp;nbsp;This is all pretty obvious and I'm sure you'll notice that I stole this directly from &lt;a href="http://beginrescueend.com/"&gt;RVM&lt;/a&gt; but it's working out so well for me I feel compelled to share anyway.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
I created a public &lt;a href="https://github.com/mgreenly/aws"&gt;repository of scripts&lt;/a&gt; on Github. &amp;nbsp;Then, like RVM, I take advantage of the fact that Github allows access to the raw content of the master branch through a fixed url. &amp;nbsp;This allows me to execute commands like the one below which will run my script for installing the Passenger gem and Apache module:&lt;br /&gt;
&lt;pre style="white-space: pre-wrap; word-wrap: break-word;"&gt;sudo su -c "bash &amp;lt; &amp;lt;(curl -s https://raw.github.com/mgreenly/aws/master/shared/passenger.sh)" -&lt;/pre&gt;
&lt;br /&gt;
Then I combine that with a strict set of conventions; for example I always use Ubuntu so all of my scripts assume they are being executed as the ubuntu user. &amp;nbsp;This can make some of the scripts a bit tougher to write, for example when you have to sudo su to become postgres to execute database commands, but it makes it easy to execute one script after another in a chain right from your initial login.&lt;br /&gt;
&lt;br /&gt;
This approach may not compare to using tools like Chef or Puppet but I'm finding I really like the simplicity of it.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=qqZzxBBt8Ns:ESla_4dBHYY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/qqZzxBBt8Ns" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/5472911723507345074/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=5472911723507345074" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/5472911723507345074?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/5472911723507345074?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/qqZzxBBt8Ns/simple-ec2-configuration.html" title="Simple EC2 Configuration" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2011/12/simple-ec2-configuration.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkcMR389eCp7ImA9WhRXEUk.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-5831462025930386682</id><published>2011-12-17T09:21:00.000-08:00</published><updated>2011-12-17T09:48:06.160-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-17T09:48:06.160-08:00</app:edited><title>EC2 Friendly SSH Config</title><content type="html">If you spend lots of time in EC2 or any other cloud service your going to collect tons of junk in your $HOME/.ssh/known_hosts file.  If you're remapping domain names to cloud based servers and those IPs change SSH's default settings will prevent you from connecting until the conflict is fixed. Instead of constantly having to edit known_hosts a better approach is to have SSH ignore known_hosts while you work in the cloud.&lt;br /&gt;&lt;br /&gt;Here's my $HOME/.ssh/config. In addition to ignoring known_hosts I also set the identiy key file and the default user.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;Host *compute-1.amazonaws.com&lt;br /&gt;User ubuntu&lt;br /&gt;StrictHostKeyChecking no&lt;br /&gt;UserKnownHostsFile /dev/null&lt;br /&gt;IdentityFile ~/.ssh/your-ec2-key&lt;br /&gt;ServerAliveInterval 30&lt;br /&gt;ServerAliveCountMax 120&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;With these settings I can copy the DNS name straight from the AWS console, type 'ssh ' at the command line, paste the DNS name and then connect; example:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;ssh ec2-107-100-123-99.compute-1.amazonaws.com&lt;/pre&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=D4xSB-PopWA:jdB5qUPnJvE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/D4xSB-PopWA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/5831462025930386682/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=5831462025930386682" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/5831462025930386682?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/5831462025930386682?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/D4xSB-PopWA/ec2-friendly-ssh-config.html" title="EC2 Friendly SSH Config" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2011/12/ec2-friendly-ssh-config.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0QEQX06eCp7ImA9WhRREEQ.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-1412946490974975492</id><published>2011-11-23T15:02:00.001-08:00</published><updated>2011-11-23T17:48:20.310-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-11-23T17:48:20.310-08:00</app:edited><title>Unity fucking blows! Gnome Shell has potential.</title><content type="html">&lt;div&gt;The title may be flame bait but hopefully this will help some fence sitters in their evaluation of Unity and Gnome Shell.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The most significant factor in my statement above is that I think the Gnome Shell developers realized there needed to be a stronger context switch between using applications and managing them.  In Gnome Shell when you bring up the launcher or the desktop switcher all of the applications fall away from focus and tile in the center of the screen so that the launcher and desktop switcher can be exposed.  At first I found this behavior a bit distracting and figured it was all eye candy but after a while I realized just how brilliant it was.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In Unity the context switch isn't as significant.  The launcher comes into view when you need it and hides when you don't.  In theory anyway.  In reality it's a frustrating game of whack-o-mole.  The launcher is never there when you want it and it's always in the way when you don't.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It seems the Gnome developers had a much better grasp of the basic user experience issue at hand.  By design or intuition they better understood that you manage applications in a different context than you use them and there was benefit in making that separation more distinct not less.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Gnome Shell certainly has room for improvement but the amount of change required to make it great is significantly less than Unity will need.&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=7OA01KA0VSo:UzqvBhiqiQQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/7OA01KA0VSo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/1412946490974975492/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=1412946490974975492" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/1412946490974975492?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/1412946490974975492?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/7OA01KA0VSo/unity-fucking-blows-gnome-shell-has.html" title="Unity fucking blows! Gnome Shell has potential." /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2011/11/unity-fucking-blows-gnome-shell-has.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0YAR30ycCp7ImA9WhdXFUg.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-2636984452375457768</id><published>2011-08-28T12:02:00.001-07:00</published><updated>2011-08-28T12:19:06.398-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-28T12:19:06.398-07:00</app:edited><title>Almost a full year no posts!</title><content type="html">&lt;div&gt;I'm not at all sure what I'm going to do with this space.&lt;/div&gt;&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Tomorrow would have been an entire year with no posts if it hadn't been for this one.&lt;/div&gt;&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I have been posting on &lt;a href="https://plus.google.com/118145172612811800326/posts"&gt;Google+&lt;/a&gt; quite a bit but that's certainly no substitute for a blog.&lt;/div&gt;&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I'm also a bit conflicted about how to focus my energy.  Do I post here in a personal space?  Or on a blog for my business under my name?&lt;/div&gt;&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Oh well, when I get it figured out I'll definitely share here.&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;&lt;div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;a lot but I really should blog it and link it there since the Google+ posts fade with time.  On the other hand I've &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;consideree&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=xc9uKy9z-3I:iEGBQcSrd0E:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/xc9uKy9z-3I" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/2636984452375457768/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=2636984452375457768" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/2636984452375457768?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/2636984452375457768?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/xc9uKy9z-3I/almost-full-year-no-posts.html" title="Almost a full year no posts!" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2011/08/almost-full-year-no-posts.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEMAQX8-eyp7ImA9Wx5QEEQ.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-2202793901676348799</id><published>2010-08-29T08:37:00.000-07:00</published><updated>2010-08-29T08:40:40.153-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-08-29T08:40:40.153-07:00</app:edited><title>Basic Git Configuration</title><content type="html">I recently purchased a new machine and had to configure Git again.  The email/user setup it reminds you of but I couldn't remember how to configure color output without some digging.  So I decided to share it here just in case anyone else may find it useful.&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/556385.js"&gt; &lt;/script&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=pIVmpX20LV0:1zWKofCfAO4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/pIVmpX20LV0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/2202793901676348799/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=2202793901676348799" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/2202793901676348799?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/2202793901676348799?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/pIVmpX20LV0/basic-git-configuration.html" title="Basic Git Configuration" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2010/08/basic-git-configuration.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C04FRXg4eCp7ImA9WxFbGEw.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-1785094030824064104</id><published>2010-07-10T18:20:00.000-07:00</published><updated>2010-07-10T18:31:54.630-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-10T18:31:54.630-07:00</app:edited><title>Browser Profile Backup</title><content type="html">While I was trying to configure a specific user profile for a Selenium testing today I accidentally deleted my Firefox profile.  At first I thought no big deal, my lap top (the machine I was using), is regularly backed up to an external USB drive attached to the docking station.  Unfortunately for some strange reason I chose to exclude the $HOME/.mozilla/ directory that contains the profile.&lt;br /&gt;&lt;br /&gt;I use Delicious for bookmarks so it mostly just means re-populating my tools bars and resetting passwords on rarely used sites if I can't remember them, not all that big of a deal really.&lt;br /&gt;&lt;br /&gt;Still, I couldn't help but notice how much more I depend on the browser than desktop applications these days.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=rwUMpyRAlY0:9ZlFJU7GHMU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/rwUMpyRAlY0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/1785094030824064104/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=1785094030824064104" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/1785094030824064104?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/1785094030824064104?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/rwUMpyRAlY0/browser-profile-backup.html" title="Browser Profile Backup" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2010/07/browser-profile-backup.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0YBRnw_cCp7ImA9WxFREU4.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-3107314955577522234</id><published>2010-04-24T08:06:00.000-07:00</published><updated>2010-04-24T11:52:37.248-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-04-24T11:52:37.248-07:00</app:edited><title>Ruby On Rails and Selenium wait_for_page</title><content type="html">I'm moving my current project's cucumber+webrat testing over to cucumber+webrat+selenium.  The biggest issue as I expected was timing problems but a fairly liberal sprinkingling of wait_for_page commands through the relevant methods in web_steps.rb file seems to have fixed most of the issues.&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/377697.js"&gt;&lt;/script&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=zn--i7A2g8E:W0-kGMo_mRI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/zn--i7A2g8E" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/3107314955577522234/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=3107314955577522234" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/3107314955577522234?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/3107314955577522234?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/zn--i7A2g8E/ruby-on-rails-and-selenium-waitforpage.html" title="Ruby On Rails and Selenium wait_for_page" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2010/04/ruby-on-rails-and-selenium-waitforpage.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEADRns6fyp7ImA9WxFTGUQ.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-1007131903146001342</id><published>2010-04-11T07:33:00.001-07:00</published><updated>2010-04-11T07:39:37.517-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-04-11T07:39:37.517-07:00</app:edited><title>User Centric Design</title><content type="html">Everyone fails if the cat's not satisfied!&lt;br /&gt;&lt;br /&gt;&lt;object width="640" height="505"&gt;&lt;param name="movie" value="http://www.youtube.com/v/dln9xDsmCoY&amp;hl=en_US&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/dln9xDsmCoY&amp;hl=en_US&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="505"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=e2O_BC3rnfw:3Y67_bECGbM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/e2O_BC3rnfw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/1007131903146001342/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=1007131903146001342" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/1007131903146001342?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/1007131903146001342?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/e2O_BC3rnfw/user-centric-design.html" title="User Centric Design" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2010/04/user-centric-design.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0QGR3w-fSp7ImA9WxBaE0o.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-28216835976424665</id><published>2010-03-23T14:20:00.001-07:00</published><updated>2010-03-23T14:22:06.255-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-03-23T14:22:06.255-07:00</app:edited><title>Command Line Ubuntu Upgrades</title><content type="html">I've tried to track this info down a few times in the past and failed.  Now that I've found it I figured I'd leave myself a bread crumb trail to find it next time.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.ubuntusolutions.org/2009/04/upgrading-ubuntu-from-the-command-line.html"&gt;http://www.ubuntusolutions.org/2009/04/upgrading-ubuntu-from-the-command-line.html&lt;/a&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=Q3mN6Z_njz0:q-9Uz9vK6rM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/Q3mN6Z_njz0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/28216835976424665/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=28216835976424665" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/28216835976424665?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/28216835976424665?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/Q3mN6Z_njz0/command-line-ubuntu-upgrades.html" title="Command Line Ubuntu Upgrades" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2010/03/command-line-ubuntu-upgrades.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CU4FQ306cSp7ImA9WxBSF0s.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-6690238663952969572</id><published>2009-12-25T08:05:00.000-08:00</published><updated>2009-12-25T09:58:32.319-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-25T09:58:32.319-08:00</app:edited><title>Google, Go, and Native Client</title><content type="html">I may have been a bit slow getting to the party but the obviousness of it really hit me this morning.  Google has exposed a few early stage projects that could work together to provide some really interesting options in the future.&lt;br /&gt;&lt;br /&gt;Specifically I'm looking at &lt;a href="http://code.google.com/p/nativeclient/"&gt;Native Client&lt;/a&gt; and &lt;a href="http://golang.org/"&gt;Go&lt;/a&gt;.  Initially I really didn't get Native Client, but when you combine it with a language like Go which is specifically designed to be sand-boxable and have fast compile times you start to get some interesting options.&lt;br /&gt;&lt;br /&gt;Google could choose to incorporate the Go language tool chain inside the browser along with Native Client.  This would mean that developers wouldn't need to build binaries for every CPU they wanted to target.  Instead users could simply visit a web page that would pull down the source and compile it on the fly.&lt;br /&gt;&lt;br /&gt;It'll be interesting to see where all of this goes.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=wM0NRlaGG_M:4FfnWu0D0Y0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/wM0NRlaGG_M" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/6690238663952969572/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=6690238663952969572" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/6690238663952969572?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/6690238663952969572?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/wM0NRlaGG_M/google-go-and-native-client.html" title="Google, Go, and Native Client" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2009/12/google-go-and-native-client.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ck8MQXs7eip7ImA9WxNXFkU.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-3642849109476120979</id><published>2009-10-04T11:14:00.000-07:00</published><updated>2009-10-04T11:28:00.502-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-04T11:28:00.502-07:00</app:edited><title>The Details of Javascript</title><content type="html">I've recently been reading  &lt;a href="http://amzn.com/0596517742"&gt;JavaScript: The Good Parts&lt;/a&gt; and have found it to be an excellent look at the details of the language itself while ignoring the DOM (which is exactly what I wanted).  Then today I ran across this &lt;a href="http://www.youtube.com/watch?v=hQVTIJBZook"&gt;Google Tech Talk&lt;/a&gt; by the author, &lt;span class="description"&gt;&lt;a href="http://www.crockford.com/"&gt;Doug Crockford&lt;/a&gt;.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;object height="344" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/hQVTIJBZook&amp;amp;hl=en&amp;amp;fs=1&amp;amp;"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/hQVTIJBZook&amp;amp;hl=en&amp;amp;fs=1&amp;amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" height="344" width="425"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=bhCRXAURvS4:PUZEpkIQQao:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/bhCRXAURvS4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/3642849109476120979/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=3642849109476120979" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/3642849109476120979?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/3642849109476120979?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/bhCRXAURvS4/details-of-javascript.html" title="The Details of Javascript" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2009/10/details-of-javascript.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0ENRXozfSp7ImA9WxNTGUo.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-5125199212511608923</id><published>2009-08-22T10:23:00.000-07:00</published><updated>2009-08-22T13:08:14.485-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-22T13:08:14.485-07:00</app:edited><title>Something Different</title><content type="html">Moving forward I'm going to be focusing on the techniques necessary to develop AJAX rich client apps tied to RESTful rails backends for internal business use.  In all likely hood I will be providing these applications to users as (single site browser) via Google Chromes &lt;a href="http://www.google.com/support/chrome/bin/answer.py?hl=en&amp;amp;answer=95710"&gt;application short cuts&lt;/a&gt; but my intention is to write code that works on any browser; IE8, Firefox, Safari and Chrome.&lt;br /&gt;&lt;br /&gt;And now for something different....&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=SKa0aCkCl3s:vsHXYx4Gqac:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/SKa0aCkCl3s" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/5125199212511608923/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=5125199212511608923" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/5125199212511608923?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/5125199212511608923?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/SKa0aCkCl3s/something-different.html" title="Something Different" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2009/08/something-different.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUMGR3s6eip7ImA9WxJSGUo.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-3847898965067366925</id><published>2009-05-10T09:34:00.000-07:00</published><updated>2009-05-10T09:37:06.512-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-10T09:37:06.512-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Entertainment" /><title>Onion News Network Has Fun With Star Trek Movie</title><content type="html">I haven't seen the movie but I stumbled across this and got a good laugh.&lt;br /&gt;&lt;br /&gt;&lt;object width="480" height="430"&gt;&lt;param name="allowfullscreen" value="true" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="movie" value="http://www.theonion.com/content/themes/common/assets/onn_embed/embedded_player.swf?image=http%3A%2F%2Fwww.theonion.com%2Fcontent%2Ffiles%2Fimages%2FSTAR_TREK_article.jpg&amp;amp;videoid=94844&amp;title=Trekkies%20Bash%20New%20Star%20Trek%20Film%20As%20%27Fun%2C%20Watchable%27" /&gt;&lt;param name="wmode" value="transparent" /&gt;&lt;embed src="http://www.theonion.com/content/themes/common/assets/onn_embed/embedded_player.swf"type="application/x-shockwave-flash" allowScriptAccess="always" allowFullScreen="true" wmode="transparent" width="480" height="430"flashvars="image=http%3A%2F%2Fwww.theonion.com%2Fcontent%2Ffiles%2Fimages%2FSTAR_TREK_article.jpg&amp;videoid=94844&amp;title=Trekkies%20Bash%20New%20Star%20Trek%20Film%20As%20%27Fun%2C%20Watchable%27"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;a href="http://www.theonion.com/content/video/trekkies_bash_new_star_trek_film?utm_source=videoembed"&gt;Trekkies Bash New Star Trek Film As 'Fun, Watchable'&lt;/a&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=seza4C4wPFc:QGzRXti4CSc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/seza4C4wPFc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/3847898965067366925/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=3847898965067366925" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/3847898965067366925?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/3847898965067366925?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/seza4C4wPFc/onion-news-network-has-fun-with-star.html" title="Onion News Network Has Fun With Star Trek Movie" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2009/05/onion-news-network-has-fun-with-star.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CE8NQXg4cSp7ImA9WxJSGUs.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-2168778048066578039</id><published>2009-05-10T06:31:00.000-07:00</published><updated>2009-05-10T06:41:30.639-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-10T06:41:30.639-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="BDDBlog" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><category scheme="http://www.blogger.com/atom/ns#" term="cucumber" /><title>Writing the Reader's Stories for the First BDD Blog Release</title><content type="html">I continue with my plan to &lt;a href="http://blog.michaelgreenly.com/2009/05/writing-user-stories-for-first-bddblog.html"&gt;write user stories&lt;/a&gt; for my &lt;a href="http://blog.michaelgreenly.com/2009/05/planning-features-for-first-bddblog.html"&gt;first release&lt;/a&gt;.  In this post I'll cover features from the readers perspective.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Must be able to Create, Edit and View posts.&lt;/li&gt;&lt;li&gt;Must support per post permanent URLs&lt;/li&gt;&lt;/ol&gt;Here's the first draft of the readers browsing feature.  We'll see where it evolves to in the future.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;Feature: browsing&lt;br /&gt;As a reader&lt;br /&gt;I want to browse the site&lt;br /&gt;So that I can read it's content&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;#&lt;br /&gt;# scenarios that involve the reader navigating to the&lt;br /&gt;# home page as the number of available posts vary&lt;br /&gt;#&lt;br /&gt;Scenario: 0 of 0&lt;br /&gt;    Given that 0 posts exist&lt;br /&gt;    When I go to the home page&lt;br /&gt;    Then I should be on the error page&lt;br /&gt;    And I should see "page not found"&lt;br /&gt;&lt;br /&gt;Scenario: 1 of 1&lt;br /&gt;    Given that 1 post exists&lt;br /&gt;    When I go to the home page&lt;br /&gt;    Then I should be on post page 1&lt;br /&gt;    And I should not see a link to the next post&lt;br /&gt;    And I should not see a link to the previous post&lt;br /&gt;&lt;br /&gt;Scenario: 2 of 2&lt;br /&gt;    Given that 2 posts exist&lt;br /&gt;    When I go to the home page&lt;br /&gt;    Then I should be on post page 2&lt;br /&gt;    And I should see a link to the previous post&lt;br /&gt;    And I should not see a link to the next post&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;#&lt;br /&gt;# Scenarios that involve the reader navigating to a specific&lt;br /&gt;# post; the first, middle and last.  These primarily demonstrate&lt;br /&gt;# the behavior of the navigation links to previous and next&lt;br /&gt;# post pages&lt;br /&gt;#&lt;br /&gt;Scenario: 1 of 2&lt;br /&gt;    Given that 2 posts exist&lt;br /&gt;    When I go to post page 1&lt;br /&gt;    Then I should not see a link to the previous post&lt;br /&gt;    And I should see a lnk to the next post&lt;br /&gt;&lt;br /&gt;Scenario: 2 of 3&lt;br /&gt;    Given that 3 posts exist&lt;br /&gt;    When I go to post page 2&lt;br /&gt;    Then I should see a link to the previous post&lt;br /&gt;    And I should see a link to the next post&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;#&lt;br /&gt;# navigation to specific posts is done through post&lt;br /&gt;# page permalinks.  The permalinks are derived from&lt;br /&gt;# the title of the post&lt;br /&gt;#&lt;br /&gt;Scenario: navigate to an non-existant post&lt;br /&gt;    Given that no posts have been created&lt;br /&gt;    When I go to the path /posts/get-rich-overnight&lt;br /&gt;    Then I should be on the error page&lt;br /&gt;    And I should see "page not found"&lt;br /&gt;    And I should see a link to the home page&lt;br /&gt;&lt;br /&gt;Scenario: navigate to an existing post&lt;br /&gt;    Given that post 1 exists&lt;br /&gt;    And that post 1 has the title "Get Rich Overnight"&lt;br /&gt;    And that post 1 has the body lorem ispum&lt;br /&gt;    When I go to /posts/get-rich-overnight&lt;br /&gt;    Then I should see "Get Rich Overnight"&lt;br /&gt;    And I should see lorem ipsum&lt;/pre&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=eWyelGmM2TQ:mfPRLOBMkz8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/eWyelGmM2TQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/2168778048066578039/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=2168778048066578039" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/2168778048066578039?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/2168778048066578039?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/eWyelGmM2TQ/writing-readers-stories-for-first-bdd.html" title="Writing the Reader's Stories for the First BDD Blog Release" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2009/05/writing-readers-stories-for-first-bdd.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUAFR3s-fip7ImA9WxJSGUU.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-3390412335542294741</id><published>2009-05-10T06:28:00.001-07:00</published><updated>2009-05-10T13:35:16.556-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-10T13:35:16.556-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="BDDBlog" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><category scheme="http://www.blogger.com/atom/ns#" term="cucumber" /><title>Writing User Stories for the First BDDBlog Release</title><content type="html">In a &lt;a href="http://blog.michaelgreenly.com/2009/05/planning-features-for-first-bddblog.html"&gt;previous post&lt;/a&gt; I shared the basics of my release plan, crude as it was.  Next I'm going to create user stories for the entire first release once that's done I'll plan and execute regular weekly iterations to complete all the release stories.  The one thing I'm going to do a bit different is that I'm going to rough out my user stories directly to cucumber features then I will maintain a list of uncompleted features that can be prioritized as I burn it down.&lt;br /&gt;&lt;br /&gt;The first task at hand is to turn my first release's outline into Cucumber features.  As I do this I'm not going to get overly concerned about the wording of my features.  I expect that I'll be massaging them as I implement them.&lt;br /&gt;&lt;br /&gt;With all that out of the way It's time to burn down the items on my release list and create some features.  The first two items in the list is the most basic;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Must be able to Create, Edit and View posts.&lt;/li&gt;&lt;li&gt;Must support per post permanent URLs&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;Next I'll look at this from each type of users role; &lt;a href="http://blog.michaelgreenly.com/2009/05/writing-readers-stories-for-first-bdd.html"&gt;Reader&lt;/a&gt;, Author and Admin but I'm going to do that in seperate posts.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=1fQlaSnu-HA:OUjenMlppy0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/1fQlaSnu-HA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/3390412335542294741/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=3390412335542294741" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/3390412335542294741?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/3390412335542294741?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/1fQlaSnu-HA/writing-user-stories-for-first-bddblog.html" title="Writing User Stories for the First BDDBlog Release" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2009/05/writing-user-stories-for-first-bddblog.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUYMQXc9cSp7ImA9WxJSE0s.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-2846096283434584949</id><published>2009-05-03T07:59:00.000-07:00</published><updated>2009-05-03T08:06:20.969-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-03T08:06:20.969-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="BDDBlog" /><title>My First BDDBlog Design Decisions</title><content type="html">Website navigation should just work from the users perspective.  It should seem simple and intuitive they should never have to think about it.  That of course means the burden to 'think about it' is on the developer.  Today I spent some time trying to decide how I wanted navigation to work in my new blog.  It wasn't as easy to make these decisions as I would have expected before hand.  &lt;br /&gt;&lt;br /&gt;Specifically I was trying to figure out exactly what a reader expects to see when they navigate to the home page and where they expect to find older posts.  I spent a fair bit of time looking at other blogs and in the end I found two basic approaches.  &lt;br /&gt;&lt;br /&gt;In one case the blogs tend to provide some number of recent posts one below the next on the home page.  Typically the posts are separated by dates as appropriate.  This style seems to be more appropriate for blogs with frequent small posts.  &lt;br /&gt;&lt;br /&gt;The other common approach was to only display the most recent post on the homepage and to provide navigation links to previous posts.  This style seems to be more appropriate for blogs with longer posts.&lt;br /&gt;&lt;br /&gt;This left me a bit unsure at first.  Quite a few of my posts are much to big for Blogger's format.  On the other hand It's not entirely uncommon for me to do micro posts.  What to do?&lt;br /&gt;&lt;br /&gt;Well after spending quite a bit of time thinking about it, for now, my decision is that I'll use the latter style.  My blog will feature a single post per page and provide links to older or newer posts as appropriate but this means I can't easily roll a twitter or delicious summary into my blog without it displacing the most recent post.&lt;br /&gt;&lt;br /&gt;After spending some time pondering that problem I decided that I may not be able to roll those other feeds into my blog but it most certianly doesn't prevent me from splicing them into my feed.&lt;br /&gt;&lt;br /&gt;So it looks like I've already stumbled on to another requirement; the ability to splice multiple RSS/Atom feeds into one.  Feature creep already =(&lt;br /&gt;&lt;br /&gt;On the other hand maybe I've stumbled on to a useful service?  Atom/RSS Feed splicing with format conversion?  Does anyone already offer that?  Hmmm... I'll have to think about that one.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=giodNPleqi4:JvpCzT1xOss:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/giodNPleqi4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/2846096283434584949/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=2846096283434584949" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/2846096283434584949?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/2846096283434584949?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/giodNPleqi4/my-first-bddblog-design-decisions.html" title="My First BDDBlog Design Decisions" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2009/05/my-first-bddblog-design-decisions.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0AHRH47cSp7ImA9WxJSGUs.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-3240182004378931989</id><published>2009-05-02T10:50:00.000-07:00</published><updated>2009-05-10T06:22:15.009-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-10T06:22:15.009-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="BDDBlog" /><title>Planning Features for the First BDDBlog Release</title><content type="html">In a &lt;a href="http://blog.michaelgreenly.com/2009/03/project-within-project.html"&gt;previous post&lt;/a&gt; I talked a bit about my motivations and just what I was up to.  In this post I'm going to start to define some specifics for the inner blog project.&lt;br /&gt;&lt;br /&gt;I'm planning on making at least three releases.  The first release is intended to replicate the basic functionality of Blogger.  The second release will expand on the first, provide better tools for managing multi-part articles and some wiki like editing features.  The third release, which is being developed for a different domain and not this blog, will incorporate the shopping cart functionality.&lt;br /&gt;&lt;br /&gt;Here's my laundry list of functionality in the order I intend to implement it in the first release:&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Must be able to Create, Edit and View posts&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Must support per post permanent URLs&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Must allow posts to be tagged&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;del&gt;Must support monthly archiving&lt;/del&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Must support authenticated admin/author logins&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Must have admin editing of site title and description&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Must have admin editing of site CSS and HTML header/footers&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Must have admin editing of side panel html/javascript&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Must be able to import Blogger's exported content&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Must provide full text search functionality&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Must provide tag search functionality&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Must provide an Atom 1.0 full content feed&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Must be able to ping blog search engines&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;Now on to the coding....&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=eKdIYqDiK1g:nGNTvLGXgGw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/eKdIYqDiK1g" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/3240182004378931989/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=3240182004378931989" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/3240182004378931989?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/3240182004378931989?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/eKdIYqDiK1g/planning-features-for-first-bddblog.html" title="Planning Features for the First BDDBlog Release" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2009/05/planning-features-for-first-bddblog.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkYFQH06eyp7ImA9WxJSEUU.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-1968227071995027417</id><published>2009-05-01T06:41:00.000-07:00</published><updated>2009-05-01T07:28:31.313-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-01T07:28:31.313-07:00</app:edited><title>Dissident Movments Of The Future</title><content type="html">&lt;a href="http://en.wikipedia.org/wiki/Anonymous_(group)"&gt;Anonymous&lt;/a&gt;' target may be Scientology but it's interesting to think about how these tactics maybe applied more broadly in the future by other interests.&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/JCbKv9yiLiQ&amp;hl=en&amp;fs=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/JCbKv9yiLiQ&amp;hl=en&amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=ga2DpV6tjFg:bswwMB0of8g:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/ga2DpV6tjFg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/1968227071995027417/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=1968227071995027417" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/1968227071995027417?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/1968227071995027417?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/ga2DpV6tjFg/disedants-movments-of-future.html" title="Dissident Movments Of The Future" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2009/05/disedants-movments-of-future.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkQCR34zcSp7ImA9WxJSEUU.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-1119093503267207103</id><published>2009-05-01T06:08:00.000-07:00</published><updated>2009-05-01T07:32:46.089-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-01T07:32:46.089-07:00</app:edited><title>How Long Before TV Programming Follows Print Media?</title><content type="html">You'd pretty much have to be living under a rock not be aware of the changes the 21st century is imposing on the old media industries.  Print news papers have been especially hard hit recently.  Still, it really sunk in today, that television is next and when their financial problems start, it will happen just as rapidly and be just as significant.&lt;br /&gt;&lt;br /&gt;What made this especially clear today was watching this:&lt;br /&gt;&lt;embed src="http://blip.tv/play/7FD+gQaCiiA" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="390"&gt;&lt;/embed&gt;&lt;br /&gt;I'm not entirely new to &lt;a href="http://www.epicfu.com/"&gt;EPIC FU&lt;/a&gt;, I first ran across it quite a while back, but what what really struck me today was the high quality of the production.  If this is what you can get for free and on demand why would I want to pay to have crap streamed to me?&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=Bvt-hY7WrVo:xyfGSpYzraY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/Bvt-hY7WrVo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/1119093503267207103/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=1119093503267207103" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/1119093503267207103?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/1119093503267207103?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/Bvt-hY7WrVo/how-long-before-tv-programming-follows.html" title="How Long Before TV Programming Follows Print Media?" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2009/05/how-long-before-tv-programming-follows.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkQHQng4eyp7ImA9WxJTF0o.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-4620943076588890359</id><published>2009-04-26T09:51:00.000-07:00</published><updated>2009-04-26T11:25:33.633-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-26T11:25:33.633-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="BDDBlog" /><category scheme="http://www.blogger.com/atom/ns#" term="Ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><category scheme="http://www.blogger.com/atom/ns#" term="cucumber" /><title>Some Progress On My BDD Blog Project</title><content type="html">I finally got around to doing some more work on my BDD Blog project over the weekend.  Up to this point I had mostly been just experimenting (&lt;a href="http://blog.michaelgreenly.com/2009/03/baby-step-1-with-rails-rspec-and.html"&gt;here&lt;/a&gt;, &lt;a href="http://blog.michaelgreenly.com/2009/03/baby-step-2-with-rails-rspec-and.html"&gt;here&lt;/a&gt; and &lt;a href="http://blog.michaelgreenly.com/2009/03/rails-authentication.html"&gt;here&lt;/a&gt;), but this time I decided I was going to try and write and implement a real scenario.&lt;br /&gt;&lt;br /&gt;My goal though is not so much to implement code.  Instead I'm still trying to learn how to write features and specs.  I want to get to the point where I'm comfortable enough with Cucumber, Webrat and RSpec that I'm confident I can express all the features for a release without wasting my time.&lt;br /&gt;&lt;br /&gt;So lets start with the feature I'm going to try and implement. The feature it self is very straight forward.  It walks through the process used by an author when creating a new post.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;Scenario: save a draft post&lt;br /&gt;  Given I am logged in as John Doe&lt;br /&gt;  And I am on the post creation page&lt;br /&gt;  And I have filled in the title with "Get Rich Overnight"&lt;br /&gt;  And I have filled in the body with "lorem ipsum"&lt;br /&gt;  When I click the "Create" button&lt;br /&gt;  Then I should be on the post index page&lt;br /&gt;  And I should see "Post successfully created"&lt;br /&gt;  And I should see "1 to 1 of 1 posts"&lt;br /&gt;  And there should only be 1 post listed&lt;br /&gt;  And the first post's title should be "Get Rich Overnight"&lt;br /&gt;  And the first post's author should be "John Doe"&lt;br /&gt;  And the first post's status should be "draft"&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;I've already &lt;a href="http://blog.michaelgreenly.com/2009/03/rails-authentication.html"&gt;played around&lt;/a&gt; with &lt;a href="http://wiki.github.com/binarylogic/authlogic"&gt;AuthLogic&lt;/a&gt; and demonstrated it's use but there's a minor change here.  I'm no longer testing authentication so I needed to reduce the login process to a single given statement.&lt;br /&gt;&lt;pre&gt;Given I am logged in as John Doe&lt;/pre&gt;&lt;br /&gt;The code I used to do that is pretty straight foward.&lt;br /&gt;&lt;pre class="ruby"&gt;&lt;code&gt;&lt;span class="constant"&gt;Given&lt;/span&gt; &lt;span class="punct"&gt;/^&lt;/span&gt;&lt;span class="constant"&gt;I&lt;/span&gt; &lt;span class="ident"&gt;am&lt;/span&gt; &lt;span class="ident"&gt;logged&lt;/span&gt; &lt;span class="keyword"&gt;in&lt;/span&gt; &lt;span class="ident"&gt;as&lt;/span&gt; &lt;span class="punct"&gt;(.+)&lt;/span&gt;&lt;span class="global"&gt;$/&lt;/span&gt; &lt;span class="ident"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;login&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;&lt;br /&gt;  &lt;span class="constant"&gt;Given&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;I am the registered user &lt;span class="expr"&gt;#{login}&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;  &lt;span class="ident"&gt;visit&lt;/span&gt; &lt;span class="ident"&gt;path_to&lt;/span&gt;&lt;span class="punct"&gt;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;the login page&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;)&lt;/span&gt;&lt;br /&gt;  &lt;span class="ident"&gt;fill_in&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;Login&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="symbol"&gt;:with&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;login&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span class="ident"&gt;fill_in&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;Password&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="symbol"&gt;:with&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;password&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;)&lt;/span&gt;&lt;br /&gt;  &lt;span class="ident"&gt;click_button&lt;/span&gt;&lt;span class="punct"&gt;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;Login&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;)&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The only thing even remotely interesting here is that I'm calling one of my previously defined 'Given' statements from within this one.&lt;br /&gt;&lt;br /&gt;The next few statements are very straight forward and were implemented entirely in cucumber with the existing scaffold for the Post resource.&lt;br /&gt;&lt;pre&gt;And I am on the post creation page&lt;br /&gt;And I have filled in the title with "Get Rich Overnight"&lt;br /&gt;And I have filled in the body with "lorem ipsum"&lt;br /&gt;When I click the "Create" button&lt;br /&gt;Then I should be on the post index page&lt;br /&gt;And I should see "Post successfully created"&lt;br /&gt;&lt;/pre&gt;The next line in this scenario:&lt;br /&gt;&lt;pre&gt;And I should see "1 to 1 of 1 posts"&lt;/pre&gt;I now realize didn't belong in this scenario (I'll refactor that out later) but since I learned something while implementing it I'm going to share.&lt;br /&gt;&lt;br /&gt;Specifically, what I learned was this statement has no real purpose.  I wanted to make sure that only the new post was present but all this really does it check to see if the "&lt;code&gt;1 to 1 of 1 posts&lt;/code&gt;" text is present.  It doesn't provide any real validation of the number of posts on the page.  In the future I'll move this out to a new feature that's specifically written to test the pagination summary.&lt;br /&gt;&lt;br /&gt;This line was not originally in my feature:&lt;br /&gt;&lt;pre&gt;And there should only be 1 post listed&lt;/pre&gt;I added it when I realized my mistake with the previous line.  This statement directly tests the number of posts on the page by counting the table rows in the post index table.  It's implementation is very straight forward:&lt;br /&gt;&lt;pre class="ruby"&gt;&lt;code&gt;&lt;span class="constant"&gt;Then&lt;/span&gt; &lt;span class="punct"&gt;/^&lt;/span&gt;&lt;span class="ident"&gt;there&lt;/span&gt; &lt;span class="ident"&gt;should&lt;/span&gt; &lt;span class="ident"&gt;only&lt;/span&gt; &lt;span class="ident"&gt;be&lt;/span&gt; &lt;span class="punct"&gt;(\&lt;/span&gt;&lt;span class="ident"&gt;d&lt;/span&gt;&lt;span class="punct"&gt;+)&lt;/span&gt; &lt;span class="ident"&gt;posts?&lt;/span&gt; &lt;span class="ident"&gt;listed&lt;/span&gt;&lt;span class="global"&gt;$/&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;count&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;&lt;br /&gt;  &lt;span class="ident"&gt;response&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;should&lt;/span&gt; &lt;span class="ident"&gt;have_tag&lt;/span&gt;&lt;span class="punct"&gt;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;tr&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:count&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;(&lt;/span&gt;&lt;span class="ident"&gt;count&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;to_i&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt; &lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;))&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The next three lines:&lt;pre&gt;And the first post's title should be "Get Rich Overnight"&lt;br /&gt;And the first post's author should be "John Doe"&lt;br /&gt;And the first post's status should be "draft"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;These lines were all very similar.  They are simply looking to make sure that the contents of specific columns in the post index table have the correct information.  This statement is implemented with the following code:&lt;br /&gt;&lt;pre class="ruby"&gt;&lt;code&gt;&lt;span class="constant"&gt;Then&lt;/span&gt; &lt;span class="punct"&gt;/^&lt;/span&gt;&lt;span class="ident"&gt;the&lt;/span&gt; &lt;span class="punct"&gt;(.+)&lt;/span&gt; &lt;span class="ident"&gt;post&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;s (.+) should be &amp;quot;([^\&amp;quot;]*)&amp;quot;$/ do |index, column, text|&lt;br /&gt;  response.should have_selector(&amp;quot;table&amp;gt;tr:nth-child(#{position_to(index) + 1})&amp;quot;) do |tr|&lt;br /&gt;    tr.should have_selector(&amp;quot;td[class=&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="comment"&gt;#{column}']&amp;quot;) do |td|&lt;/span&gt;&lt;br /&gt;      &lt;span class="ident"&gt;td&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;should&lt;/span&gt; &lt;span class="ident"&gt;contain&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;text&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;There's not much special there but it was my first attempt at really trying to use the CSS selector notation.  Maybe after I'm more comfortable with it I'll devote a post to just that but for now I'll just explain this method.&lt;br /&gt;&lt;br /&gt;In a nutshell it simply looks to make sure that nth row in the post index table has a td tag with a class matching the column name and that it's content matches the text passed in.&lt;br /&gt;&lt;br /&gt;You may also notice I have a poorly named method called position_to in this method that simply turns the english words; first, second, third, etc... into the appropriate fixnum.  Hopefully down the road I can find a library that does this but if not maybe I'll expand my approach into a full fledged gem.&lt;br /&gt;&lt;br /&gt;This pretty much covered what I did with Cucumber and Webrat to fully implement this scenario but I did dip down into some view, controller and model specs to get the job done.  I'll save that for another post.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=9SJUpkDv2MM:7QdP0580JPs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/9SJUpkDv2MM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/4620943076588890359/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=4620943076588890359" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/4620943076588890359?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/4620943076588890359?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/9SJUpkDv2MM/some-progress-on-my-bdd-blog-project.html" title="Some Progress On My BDD Blog Project" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2009/04/some-progress-on-my-bdd-blog-project.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcAQn86fCp7ImA9WxJTF0g.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-2679346916101031623</id><published>2009-04-26T06:28:00.000-07:00</published><updated>2009-04-26T06:37:23.114-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-26T06:37:23.114-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="RSpec" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><title>Can't Use Ruby 1.9.1 Just Yet</title><content type="html">I had wanted to &lt;a href="http://blog.michaelgreenly.com/2009/04/multiple-versions-of-ruby-on-ubuntu-3.html"&gt;switch to Ruby 1.9&lt;/a&gt; for my current project.  I'm using a fairly minimal number of dependencies and didn't expect any problems.  Unfortunately for what ever reason RSpec fails silently under Ruby1.9.1 but works properly on Ruby1.8.7 (at least on my machine).  Since I don't have the time to track it down right now it looks like I'm reverting back to Ruby1.8.7 for the time being.&lt;br /&gt;&lt;br /&gt;Hopefully I'll have time to dig into it later in the week.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=B8e9KtDD89E:i2oDsXsOOas:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/B8e9KtDD89E" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/2679346916101031623/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=2679346916101031623" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/2679346916101031623?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/2679346916101031623?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/B8e9KtDD89E/cant-use-ruby-191-just-yet.html" title="Can't Use Ruby 1.9.1 Just Yet" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2009/04/cant-use-ruby-191-just-yet.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0AAQnw6eip7ImA9WxJTFUU.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-2283976792602911075</id><published>2009-04-24T06:05:00.000-07:00</published><updated>2009-04-24T07:02:23.212-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-24T07:02:23.212-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Linux" /><category scheme="http://www.blogger.com/atom/ns#" term="ubuntu" /><title>The 'sudo' Command's Environment</title><content type="html">I'm sure most people are aware the '&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;sudo&lt;/span&gt;' command sterilizes the user's environment variables before executing the command passed to it.  The most common issue I've run into with this is $PATH not being preserved.  The usual scenario is that I have an application installed into /opt and I've appended it's location to $PATH, which works just fine until you try to execute the application with '&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;sudo&lt;/span&gt;' and it fails because the command is no longer in the current path.&lt;br /&gt;&lt;br /&gt;The fix to this is really straight forward and I'm surprised I hadn't thought of it earlier.  Simply add the following to your $HOME/.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;bashrc&lt;/span&gt; file.&lt;br /&gt;&lt;pre&gt;alias &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;sudo&lt;/span&gt;="&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;sudo&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;env&lt;/span&gt; PATH=$PATH"&lt;/pre&gt;What this does is use '&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;sudo&lt;/span&gt;' to run '&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;env&lt;/span&gt;' which is passed the provided command but sets the target environment's PATH to match the current users before executing it.&lt;br /&gt;&lt;br /&gt;Don't forget that you can always run the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;unaliased&lt;/span&gt; version of a command simply by prefixing it with a backslash.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=MM6oqSWm2Ow:k_-dhc8uZ9w:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/MM6oqSWm2Ow" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/2283976792602911075/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=2283976792602911075" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/2283976792602911075?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/2283976792602911075?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/MM6oqSWm2Ow/sudo-commands-environment.html" title="The 'sudo' Command's Environment" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>3</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2009/04/sudo-commands-environment.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkYNRnozeCp7ImA9WhRbFU4.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-2466102816213486069</id><published>2009-04-12T05:53:00.000-07:00</published><updated>2012-02-06T06:23:17.480-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-02-06T06:23:17.480-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="ubuntu" /><title>Multiple Versions of Ruby on Ubuntu #3</title><content type="html">&lt;span style="color: #cc0000; font-style: italic;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #cc0000; font-style: italic;"&gt;This post is from a time before&amp;nbsp;&lt;a href="http://beginrescueend.com/"&gt;RVM&lt;/a&gt;&amp;nbsp;or&amp;nbsp;&lt;a href="https://github.com/sstephenson/rbenv"&gt;rbenv&lt;/a&gt;&amp;nbsp;you should check out those instead.&lt;/span&gt;&lt;span style="color: #cc0000; font-style: italic;"&gt;.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
I decided it's time to switch to Ruby 1.9 but I still have a couple of Ruby 1.8 projects I need to maintain.  That means I need a simple technique for switching back and forth between multiple versions of Ruby.  I've experimented with different approaches in the past but I'm not completely satisfied with any of them.&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blog.michaelgreenly.com/2007/12/multiple-ruby-version-on-ubuntu.html"&gt;Multiple Versions of Ruby on Ubuntu #1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.michaelgreenly.com/2008/08/multiple-versions-of-ruby-on-ubuntu-2.html"&gt;Multiple Versions of Ruby on Ubuntu #2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
This time I've decided to use a shell script to update a symbolic link that points to the active version.  It's extremely fast and simple.&lt;br /&gt;
&lt;br /&gt;
I started by purging my system of any apt installed Ruby packages.&lt;br /&gt;
&lt;pre&gt;sudo apt-get remove --purge ruby1.8 ruby1.9&lt;/pre&gt;
&lt;br /&gt;
Then I installed Ruby 1.8 from source.&lt;br /&gt;
&lt;pre&gt;sudo apt-get build-dep ruby1.8
wget -c ftp://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.7-p72.tar.gz
tar -xvzf ruby-1.8.7-p72.tar.gz
cd ruby-1.8.7-p72
./configure --prefix=/opt/ruby-1.8.7-p72 --enable-pthread --enable-shared --enable-openssl --enable-readline --enable-zlib
make
sudo make install
wget -c http://rubyforge.org/frs/download.php/45905/rubygems-1.3.1.tgz
tar -xvzf rubygems-1.3.1.tgz
cd rubygems-1.3.1
sudo /opt/ruby-1.8.7-p72/bin/ruby setup.rb&lt;/pre&gt;
&lt;br /&gt;
Then I installed Ruby 1.9 from source.&lt;br /&gt;
&lt;pre&gt;sudo apt-get build-dep ruby1.9
wget -c ftp://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.1-p0.tar.gz
tar -xvzf ruby-1.9.1-p0.tar.gz
cd ruby-1.9.1-p0/
./configure --prefix=/opt/ruby-1.9.1-p0 --enable-pthread --enable-shared
make
sudo make install&lt;/pre&gt;
&lt;br /&gt;
Then I add the following line to the bottom of $HOME/.bashrc&lt;br /&gt;
&lt;pre&gt;export PATH=/opt/ruby/bin:$PATH&lt;/pre&gt;
&lt;br /&gt;
Then I saved the following script in /usr/local/bin/select_ruby&lt;br /&gt;
&lt;pre&gt;#!/bin/sh

while : # Loop forever
do
cat &amp;lt;&amp;lt; !

current = $(/opt/ruby/bin/ruby --version)

Select Option

1. ruby-1.8.6-p368
2. ruby-1.8.7-p72
3. ruby-1.8.7-p160
4. ruby-1.9.1-p0
5. exit

!

echo -n " Your choice? : "
read choice

case $choice in
1) rm -rf /opt/ruby; ln -s /opt/ruby-1.8.6-p368 /opt/ruby;;
2) rm -rf /opt/ruby; ln -s /opt/ruby-1.8.7-p72 /opt/ruby;;
3) rm -rf /opt/ruby; ln -s /opt/ruby-1.8.7-p160 /opt/ruby;;
4) rm -rf /opt/ruby; ln -s /opt/ruby-1.9.1-p0 /opt/ruby;;
5) exit;;
*) echo "\"$choice\" is not valid "; sleep 2 ;;
esac
exit
done&lt;/pre&gt;
&lt;br /&gt;
Now to switch I just run the script and select the version I want.&lt;br /&gt;
&lt;pre&gt;sudo select_ruby&lt;/pre&gt;
&lt;br /&gt;
There's a couple of things to be aware of using this approach.  Each ruby installation has it's own separate instance of rubygems so gems will have to be installed multiple times.  Also since sudo doesn't preserve the users $PATH you will need to use the full path with the gem command; example:&lt;br /&gt;
&lt;pre&gt;sudo /opt/ruby/bin/gem install rails&lt;/pre&gt;
Or this &lt;a href="http://blog.michaelgreenly.com/2009/04/sudo-commands-environment.html"&gt;fix&lt;/a&gt;.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=MykJ222HHHo:atuLVvk4i1A:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/MykJ222HHHo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/2466102816213486069/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=2466102816213486069" title="16 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/2466102816213486069?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/2466102816213486069?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/MykJ222HHHo/multiple-versions-of-ruby-on-ubuntu-3.html" title="Multiple Versions of Ruby on Ubuntu #3" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>16</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2009/04/multiple-versions-of-ruby-on-ubuntu-3.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkEERXoyfip7ImA9WxVbGUg.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-3670090631799356</id><published>2009-04-05T08:26:00.000-07:00</published><updated>2009-04-05T09:56:44.496-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-05T09:56:44.496-07:00</app:edited><title>As The Prouduct Owner What's My Goal?</title><content type="html">I've been away from rails for a bit and to catch up I've decided to write an application to re-familiarize myself with the frame work and at the same time try and apply what I think I've learned about behavior driven development.  There's an &lt;a href="http://blog.michaelgreenly.com/2009/03/project-within-project.html"&gt;earlier post&lt;/a&gt; with more details.&lt;br /&gt;&lt;br /&gt;Today, in this post, I'm going to be the &lt;a href="http://en.wikipedia.org/wiki/Scrum_%28development%29#.22Pig.22_roles"&gt;product owner&lt;/a&gt; and attempt to define my goals for this project.&lt;br /&gt;&lt;br /&gt;I want to create a blog with built in shopping cart functionality.  The intention is that the original content generated for the blog will generate traffic to the site that can be converted into sales.  I realize that if this was my only goal it would be smarter to use an existing blog framework that has an available shopping cart plugin, but it's not my only goal.&lt;br /&gt;&lt;br /&gt;I want to break development into two major parts.  The first phase will be to develop the blog and the second the shopping cart functionality.  I'm going this route because it will allow the blog to start building traffic while the shopping cart is being developed.&lt;br /&gt;&lt;br /&gt;This means I need to define what I want in a blog....&lt;br /&gt;&lt;ul&gt;&lt;li&gt;It should support a write to draft, edit, preview then publish work flow.  When drafts are previewed they should be seen exactly as they will appear on the finished page.  Nothing annoys me more about blogger than the fact that it's preview does not use the blog's styles sheets.&lt;/li&gt;&lt;li&gt;It should provide a sane default permalink based on the title but it should also allow the permalink to be overridden.&lt;/li&gt;&lt;li&gt;It should allow additional alias permalinks.  This is specifically to make importing the content of other blogs with different permalink formats easier.&lt;/li&gt;&lt;li&gt;The markup should be a subset of html.  I don't need a WYSIWYG editor or a markdown syntax.&lt;/li&gt;&lt;li&gt;It should handle tags for blog articles and be able to display a tag cloud on the side bar.&lt;/li&gt;&lt;li&gt;It should support interactive editing of javascript widgets for the side bar.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;It should handle article grouping to create a series of articles.  When an article is made part of a series it should automatically include links to the previous and next articles in the series.&lt;/li&gt;&lt;li&gt;It obviously needs to generate rss/atom feeds.&lt;/li&gt;&lt;li&gt;It should support search but it can be an external service (google site search) if it's incorporated really well.&lt;/li&gt;&lt;li&gt;It should support online editing of the site wide css.  It shouldn't be necessary to change sources code, commit and deploy it just for a CSS tweak.&lt;/li&gt;&lt;li&gt;It should support comments from authenticated users (OpenID and Facebook authentication) and anonymous comments after review.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;It should be able to import a blog from Blogger.&lt;/li&gt;&lt;li&gt;It should support syntax highlighting for ruby, xml, yaml, css, html and json code.&lt;/li&gt;&lt;li&gt;It should be able to compile a daily digest of Twitter comments.&lt;/li&gt;&lt;li&gt;It shoudl be able to compile a daily digest of Delicious links.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;That spells out pretty much what I'm after.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=WUGE3gcBaZ0:B5n70xHJA-o:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/WUGE3gcBaZ0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/3670090631799356/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=3670090631799356" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/3670090631799356?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/3670090631799356?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/WUGE3gcBaZ0/as-prouduct-owner-whats-my-goal.html" title="As The Prouduct Owner What's My Goal?" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2009/04/as-prouduct-owner-whats-my-goal.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0YASHk9fip7ImA9WxVbGEQ.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-3161740964832950229</id><published>2009-04-04T18:54:00.000-07:00</published><updated>2009-04-04T19:39:09.766-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-04T19:39:09.766-07:00</app:edited><title>Python's DVCS Comparison</title><content type="html">I ran across this comparison of &lt;a href="http://www.python.org/dev/peps/pep-0374/"&gt;distributed version control systems&lt;/a&gt;.  It also appears that Python has &lt;a href="http://mail.python.org/pipermail/python-dev/2009-March/087931.html"&gt;selected&lt;/a&gt; &lt;a href="http://www.selenic.com/mercurial/wiki/"&gt;Mercurial&lt;/a&gt; after doing this comparison.  I don't really have a comment on that but I do find it interesting how different communities gravitated in different directions.  With Ruby users firmly entrenched in the world of Git and now Python going with Mercurial.&lt;br /&gt;&lt;br /&gt;Still while reading through it I found at least one thing I wanted to share.  Towards the end of the comparison there's a section that evaluates &lt;a href="http://www.python.org/dev/peps/pep-0374/#updating-a-checkout"&gt;how long it takes to update a stale repository&lt;/a&gt;.  In that section there's a comment that indicates that git was not able to checkout a repository at a specific commit but I'm not sure how that effected that test?&lt;br /&gt;&lt;br /&gt;To perform this test I would have used this...&lt;br /&gt;&lt;pre&gt;# fetch a copy of the repository&lt;br /&gt;git clone [url]&lt;br /&gt;# roll everything back 700 commits&lt;br /&gt;git reset --hard HEAD~700&lt;br /&gt;# pull the head from remote master&lt;br /&gt;git pull&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-style: italic; color: rgb(0, 0, 102);"&gt;I think I misunderstood what they were trying to test.  It looks like they wanted to test the performance of the fetch, merge, and commit and what I described above doesn't re-fetch the 700 commits.&lt;/span&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=qYoCuyWauWQ:2LL5uwMERMU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/qYoCuyWauWQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/3161740964832950229/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=3161740964832950229" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/3161740964832950229?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/3161740964832950229?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/qYoCuyWauWQ/pythons-dvcs-comparison.html" title="Python's DVCS Comparison" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2009/04/pythons-dvcs-comparison.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkcFQHw-eip7ImA9WxJSEkU.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-4822036637449120471</id><published>2009-03-31T03:30:00.000-07:00</published><updated>2009-05-02T10:06:51.252-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-02T10:06:51.252-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="BDDBlog" /><category scheme="http://www.blogger.com/atom/ns#" term="Ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><category scheme="http://www.blogger.com/atom/ns#" term="cucumber" /><category scheme="http://www.blogger.com/atom/ns#" term="authlogic" /><title>Testing Rails Authlogic with Cucumber</title><content type="html">In early rails projects I rolled my own authentication system, later I used &lt;a href="http://github.com/technoweenie/restful-authentication/tree/master"&gt;restful-authentication&lt;/a&gt;.  This time I'm going to try out &lt;a href="http://wiki.github.com/binarylogic/authlogic"&gt;AuthLogic&lt;/a&gt; which seems to be fairly popular, cleanly packaged and actively developed.  I may walk through an AuthLogic &lt;a href="http://www.binarylogic.com/2008/11/3/tutorial-authlogic-basic-setup"&gt;installation&lt;/a&gt; in a future post but today I just want to make sure it can play nicely with cucumber.&lt;br /&gt;&lt;br /&gt;First I wrote a fairly basic login scenario.  You'll notice I stuck with the &lt;a href="http://http//www.benmabey.com/2008/05/19/imperative-vs-declarative-scenarios-in-user-stories/"&gt;declarative&lt;/a&gt; style in writing this and I followed the advice provided in &lt;a href="http://www.pragprog.com/titles/achbd/the-rspec-book"&gt;"The RSpec Book"&lt;/a&gt;.  I use direct model access to create the registered user in the 'Given' but then use simulated browser access to do the login and verify the actions success.&lt;pre&gt;Scenario: successful login&lt;br /&gt;Given I am the registered user John Doe&lt;br /&gt;And I am on the login page&lt;br /&gt;When I login with valid credentials&lt;br /&gt;Then I should be on the account page&lt;br /&gt;And I should see "Login successful!"&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This left me with three steps to implement:&lt;br /&gt;&lt;br /&gt;&lt;pre class="ruby"&gt;&lt;span class="constant"&gt;Given&lt;/span&gt; &lt;span class="punct"&gt;/^&lt;/span&gt;&lt;span class="constant"&gt;I&lt;/span&gt; &lt;span class="ident"&gt;am&lt;/span&gt; &lt;span class="ident"&gt;the&lt;/span&gt; &lt;span class="ident"&gt;registered&lt;/span&gt; &lt;span class="ident"&gt;user&lt;/span&gt; &lt;span class="punct"&gt;(.+)&lt;/span&gt;&lt;span class="global"&gt;$/&lt;/span&gt; &lt;span class="ident"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;login&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;&lt;br /&gt;&lt;span class="ident"&gt;  params&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class="punct"&gt;    "&lt;/span&gt;&lt;span class="string"&gt;login&lt;/span&gt;&lt;span class="punct"&gt;"=&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;login&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt;&lt;br /&gt;&lt;span class="punct"&gt;    "&lt;/span&gt;&lt;span class="string"&gt;password&lt;/span&gt;&lt;span class="punct"&gt;"=&amp;gt;"&lt;/span&gt;&lt;span class="string"&gt;password&lt;/span&gt;&lt;span class="punct"&gt;",&lt;/span&gt;&lt;br /&gt;&lt;span class="punct"&gt;    "&lt;/span&gt;&lt;span class="string"&gt;password_confirmation&lt;/span&gt;&lt;span class="punct"&gt;"=&amp;gt;"&lt;/span&gt;&lt;span class="string"&gt;password&lt;/span&gt;&lt;span class="punct"&gt;"&lt;/span&gt;&lt;br /&gt;&lt;span class="punct"&gt;  }&lt;/span&gt;&lt;br /&gt;&lt;span class="attribute"&gt;  @user&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;User&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;create&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;params&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="constant"&gt;When&lt;/span&gt; &lt;span class="punct"&gt;/^&lt;/span&gt;&lt;span class="constant"&gt;I&lt;/span&gt; &lt;span class="ident"&gt;login&lt;/span&gt; &lt;span class="ident"&gt;with&lt;/span&gt; &lt;span class="ident"&gt;valid&lt;/span&gt; &lt;span class="ident"&gt;credentials&lt;/span&gt;&lt;span class="global"&gt;$/&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;&lt;br /&gt;&lt;span class="ident"&gt;  fill_in&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;Login&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="symbol"&gt;:with&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="attribute"&gt;@user&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;login&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="ident"&gt;  fill_in&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;Password&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="symbol"&gt;:with&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;"&lt;/span&gt;&lt;span class="string"&gt;password&lt;/span&gt;&lt;span class="punct"&gt;")&lt;/span&gt;&lt;br /&gt;&lt;span class="ident"&gt;  click_button&lt;/span&gt;&lt;span class="punct"&gt;("&lt;/span&gt;&lt;span class="string"&gt;Login&lt;/span&gt;&lt;span class="punct"&gt;")&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="constant"&gt;Then&lt;/span&gt; &lt;span class="punct"&gt;/^&lt;/span&gt;&lt;span class="constant"&gt;I&lt;/span&gt; &lt;span class="ident"&gt;should&lt;/span&gt; &lt;span class="ident"&gt;be&lt;/span&gt; &lt;span class="ident"&gt;on&lt;/span&gt; &lt;span class="punct"&gt;([^\"&lt;/span&gt;&lt;span class="string"&gt;]*)$/ do |page_name|&lt;br /&gt;response.request.path.should == path_to(page_name)&lt;br /&gt;end&lt;span class="normal"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;All fairly straight forward.  I don't expect any problems using Cucumber with Authlogic.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=dhmHOLrBcbI:V14gXhBTQhE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/dhmHOLrBcbI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/4822036637449120471/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=4822036637449120471" title="10 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/4822036637449120471?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/4822036637449120471?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/dhmHOLrBcbI/rails-authentication.html" title="Testing Rails Authlogic with Cucumber" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>10</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2009/03/rails-authentication.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUACRHo8fCp7ImA9WxVbEkk.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-2720562326667495466</id><published>2009-03-27T11:23:00.000-07:00</published><updated>2009-03-28T06:42:45.474-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-28T06:42:45.474-07:00</app:edited><title>Herding Tigers</title><content type="html">I took the time last night to skim through most of the &lt;a href="http://mwrc2009.confreaks.com/"&gt;videos&lt;/a&gt; from the &lt;a href="http://www.mtnwestrubyconf.com/2009/index"&gt;Mountain West Ruby Conference&lt;/a&gt; on &lt;a href="http://www2.confreaks.com/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;Confreaks&lt;/span&gt;&lt;/a&gt;.  Without question my favorite in the bunch was &lt;a href="http://www.danielphilpott.com/about.htm"&gt;&lt;span class="caption"&gt;Daniel &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;Philpott&lt;/span&gt;&lt;/span&gt;'s&lt;/a&gt; - "&lt;a href="http://mwrc2009.confreaks.com/14-mar-2009-10-30-herding-tigers-software-development-and-the-art-of-war-daniel-philpott.html"&gt;Herding Tigers - Software Development and the Art of War&lt;/a&gt;".&lt;br /&gt;&lt;br /&gt;If agile project &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_2"&gt;management&lt;/span&gt; is something that interests you this video is worth watching.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=C6dVPTiXnS4:z9XvyIa7Q6w:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/C6dVPTiXnS4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/2720562326667495466/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=2720562326667495466" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/2720562326667495466?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/2720562326667495466?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/C6dVPTiXnS4/herding-tigers.html" title="Herding Tigers" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2009/03/herding-tigers.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ak8HRno6cCp7ImA9WxVbEUo.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-7637478821306712347</id><published>2009-03-26T12:56:00.000-07:00</published><updated>2009-03-27T11:33:57.418-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-27T11:33:57.418-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Facebook" /><title>The Facebook UI Changes</title><content type="html">Lots of people have been talking about the UI changes on Facebook but I wasn't &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_2"&gt;immediately&lt;/span&gt; sure of how I felt.  I was more than willing to give the new look a chance.    After all the old &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;UI&lt;/span&gt; really sucked.&lt;br /&gt;&lt;br /&gt;Well, I've decided.  The new &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;UI&lt;/span&gt; sucks even worse!&lt;br /&gt;&lt;br /&gt;Oddly it took this change for me to understand what I was using &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;Facebook&lt;/span&gt; for.  Which has primarily been to watch status changes, photo uploads and exchange private messages.&lt;br /&gt;&lt;br /&gt;The problem is that since the change everyone has started having much longer &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_6"&gt;conversations&lt;/span&gt; on the "what's on you mind" post and unlike wall-to-wall conversations you can't opt-out of them.&lt;br /&gt;&lt;br /&gt;I'm stuck reading them all!  It sucks!&lt;br /&gt;&lt;br /&gt;If I want to read through my updates to see things I'm interested in I have to wade through tons and tons of spam and it's not just conversation spam it's all the noise from the hundreds of absolutely retarded &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;facebook&lt;/span&gt; applications.&lt;br /&gt;&lt;br /&gt;The signal to noise ratio has dropped to the point where I've pretty much given up.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=C4ebKIGoHjQ:G4McRhixcSE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/C4ebKIGoHjQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/7637478821306712347/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=7637478821306712347" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/7637478821306712347?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/7637478821306712347?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/C4ebKIGoHjQ/facebook-ui-changes.html" title="The Facebook UI Changes" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2009/03/facebook-ui-changes.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkQFSH47eSp7ImA9WxJSEkU.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-1166781983872797365</id><published>2009-03-26T12:37:00.000-07:00</published><updated>2009-05-02T10:11:59.001-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-02T10:11:59.001-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="BDDBlog" /><title>A Project Within A Project</title><content type="html">So I've decided that I've learned what I need to from my &lt;a href="http://wiki.github.com/aslakhellesoy/cucumber"&gt;Cucumber&lt;/a&gt; experiments[&lt;a href="http://blog.michaelgreenly.com/2009/03/baby-step-1-with-rails-rspec-and.html"&gt;1&lt;/a&gt;,&lt;a href="http://blog.michaelgreenly.com/2009/03/baby-step-2-with-rails-rspec-and.html"&gt;2&lt;/a&gt;] and now it's time to dive in for real but to do that I need to be sure I understand my objective and of course it's complicated like an &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_0"&gt;onion&lt;/span&gt;.  So I'm going to&lt;a href="http://blog.michaelgreenly.com/2009/03/pop-why-stack.html"&gt; pop the why stack&lt;/a&gt; a few times.&lt;br /&gt;&lt;br /&gt;My outer goal is to provide myself with a realistic Rails project that I can apply Agile, Behavior Driven Development techniques to.  I'm writing the code so I can continue my education.  I'm blogging about it so that I can generate some self promotion.  I may benefit from the self promotion if I choose to pursue this career path again someday.&lt;br /&gt;&lt;br /&gt;Of course it's necessary for the inner project to have legitimate driving factors as well, otherwise I can't really practice managing an agile process. So, here's a bit of background on the goals of the inner project...&lt;br /&gt;&lt;br /&gt;The inner project is a &lt;a href="http://en.wikipedia.org/wiki/Do_it_yourself"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;DIY&lt;/span&gt;&lt;/a&gt;/&lt;a href="http://en.wikipedia.org/wiki/HOWTO"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;HOWTO&lt;/span&gt;&lt;/a&gt; blog that's also an online store.  The goal is to provide quality original content.  So that it drives traffic to the site.  So that related merchandise is exposed to reader traffic.  So that stuff can be sold.  So that I can make money.&lt;br /&gt;&lt;br /&gt;So now with the stake holder's position explained it's time to start planning the project!&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=H8y3u_uj7Qs:TQjovpCG4os:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/H8y3u_uj7Qs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/1166781983872797365/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=1166781983872797365" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/1166781983872797365?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/1166781983872797365?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/H8y3u_uj7Qs/project-within-project.html" title="A Project Within A Project" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2009/03/project-within-project.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DE8ESH45fip7ImA9WhdXF04.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-5262024372788154444</id><published>2009-03-26T10:29:00.000-07:00</published><updated>2011-08-30T13:40:09.026-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-30T13:40:09.026-07:00</app:edited><title>Pop The Why Stack</title><content type="html">I think one of the most important idea's in lean/agile development is the attention devoted to only doing work where it provides value.  One of the best expressions of this I've seen is on&lt;a href="https://github.com/cucumber/cucumber/wiki"&gt; Cucumber's wiki page&lt;/a&gt;.  Basically it says...
&lt;br /&gt;
&lt;br /&gt;Before doing something pop the why stack recursively until you end up with one of the following business values; protect revenue, increase revenue or manage cost.
&lt;br /&gt;
&lt;br /&gt;I think that's a powerful razor to cut things with!&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=F-loyX4UmOI:yYzWDQHNb-4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/F-loyX4UmOI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/5262024372788154444/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=5262024372788154444" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/5262024372788154444?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/5262024372788154444?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/F-loyX4UmOI/pop-why-stack.html" title="Pop The Why Stack" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2009/03/pop-why-stack.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkYEQHw4fyp7ImA9WxJSEkU.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-1352938684461231863</id><published>2009-03-25T14:37:00.000-07:00</published><updated>2009-05-02T10:08:21.237-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-02T10:08:21.237-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="BDDBlog" /><category scheme="http://www.blogger.com/atom/ns#" term="Ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><category scheme="http://www.blogger.com/atom/ns#" term="cucumber" /><title>Baby Step #2 with Rails, RSpec and Cucumber</title><content type="html">In my &lt;a href="http://blog.michaelgreenly.com/2009/03/baby-step-1-with-rails-rspec-and.html"&gt;previous post&lt;/a&gt; I took my first stab at Cucumber; first writing a failing Scenario, then getting it to pass, then writing a failing Spec and getting it to pass.  The scenario in the previous post was overly simple, in fact I was able to complete it without writing any code at all.  My goal this time is to continue my education with a slightly more realistic scenario.&lt;br /&gt;&lt;br /&gt;One way to attack an application is in the same order it's used.  In the case of a blog the author will need to add content before the site has any value, so that seems like a reasonable starting point.&lt;br /&gt;&lt;pre&gt;# RAILS_ROOT/features/author_publish.feature&lt;br /&gt;Feature: author publish&lt;br /&gt;As an author&lt;br /&gt;I want to publish a post&lt;br /&gt;So that it can be read&lt;br /&gt;&lt;br /&gt;Scenario: publish a post&lt;br /&gt;  Given I am on the post creation page&lt;br /&gt;  When I add a new post&lt;br /&gt;  Then I should see a page for the new post&lt;/pre&gt;&lt;br /&gt;The narrative for this feature was easy but deciding on how to approach the first scenario wasn't.  In the end after browsing around the web and reading tons of material it was another post from &lt;a href="http://www.benmabey.com/"&gt;Ben Maybe&lt;/a&gt; called &lt;a href="http://www.benmabey.com/2008/05/19/imperative-vs-declarative-scenarios-in-user-stories/"&gt;"Imperative vs Declarative Scenarios in User Stories"&lt;/a&gt; that seemed to help me decide.&lt;br /&gt;&lt;br /&gt;With that feature in place running cucumber:&lt;pre&gt;./script/cucumber features/author_publish.feature&lt;/pre&gt;&lt;br /&gt;Produces the following:&lt;pre&gt;Feature: author publish&lt;br /&gt;As an author&lt;br /&gt;I want to publish a post&lt;br /&gt;So that it can be read&lt;br /&gt;&lt;br /&gt;Scenario: publish a post                    # features/author_publish.feature:6&lt;br /&gt;  Given I am on the post creation page      # features/step_definitions/webrat_steps.rb:6&lt;br /&gt;    Can't find mapping from "the post creation page" to a path. (RuntimeError)&lt;br /&gt;    /home/mgreenly/Projects/blog/features/support/paths.rb:11:in `/^I am on (.+)$/'&lt;br /&gt;    features/author_publish.feature:7:in `Given I am on the post creation page'&lt;br /&gt;  When I add a new post                     # features/author_publish.feature:8&lt;br /&gt;  Then I should see a page for the new post # features/author_publish.feature:9&lt;br /&gt;&lt;br /&gt;1 scenario&lt;br /&gt;1 failed step&lt;br /&gt;2 undefined steps&lt;br /&gt;&lt;br /&gt;You can implement step definitions for missing steps with these snippets:&lt;br /&gt;&lt;br /&gt;When /^I add a new post$/ do&lt;br /&gt;pending&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;Then /^I should see a page for the new post$/ do&lt;br /&gt;pending&lt;br /&gt;end&lt;/pre&gt;&lt;br /&gt;The problem here is cucumber doesn't know what to map the phrase 'the post creation page' to.  This can be fixed by adding the following code to the navigation helper.&lt;pre class="ruby"&gt;&lt;span class="comment"&gt;# RAILS_ROOT/features/support/paths.rb&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;path_to&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;page_name&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;case&lt;/span&gt; &lt;span class="ident"&gt;page_name&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;when&lt;/span&gt; &lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="regex"&gt;the homepage&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;root_path&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;when&lt;/span&gt; &lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="regex"&gt;the post creation page&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;post_path&lt;/span&gt;&lt;span class="punct"&gt;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;else&lt;/span&gt;&lt;br /&gt;    &lt;span class="keyword"&gt;raise&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;Can't find mapping from &lt;span class="escape"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="expr"&gt;#{page_name}&lt;/span&gt;&lt;span class="escape"&gt;\&amp;quot;&lt;/span&gt; to a path.&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;Now we run cucumber again:&lt;pre&gt;./script/cucumber features/author_publish.feature&lt;/pre&gt;&lt;br /&gt;And it produces the following:&lt;br /&gt;&lt;pre&gt;Feature: author publish&lt;br /&gt;As an author&lt;br /&gt;I want to publish a post&lt;br /&gt;So that it can be read&lt;br /&gt;&lt;br /&gt;Scenario: publish a post                    # features/author_publish.feature:6&lt;br /&gt;  Given I am on the post creation page      # features/step_definitions/webrat_steps.rb:6&lt;br /&gt;    undefined method `post_path' for #&lt;actioncontroller::integration::session:0xb6d7b354&gt; (NoMethodError)&lt;br /&gt;    /home/mgreenly/Projects/blog/features/support/paths.rb:9:in `/^I am on (.+)$/'&lt;br /&gt;    features/author_publish.feature:7:in `Given I am on the post creation page'&lt;br /&gt;  When I add a new post                     # features/author_publish.feature:8&lt;br /&gt;  Then I should see a page for the new post # features/author_publish.feature:9&lt;br /&gt;&lt;br /&gt;1 scenario&lt;br /&gt;1 failed step&lt;br /&gt;2 undefined steps&lt;br /&gt;&lt;br /&gt;You can implement step definitions for missing steps with these snippets:&lt;br /&gt;&lt;br /&gt;When /^I add a new post$/ do&lt;br /&gt;pending&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;Then /^I should see a page for the new post$/ do&lt;br /&gt;pending&lt;br /&gt;end&lt;/actioncontroller::integration::session:0xb6d7b354&gt;&lt;/pre&gt;&lt;br /&gt;Now it's complaining that it can't find a mapping for the Post resource.  That makes sense since in my previous round I only created a controller.  Instead of laboring through the process to create the Post model why not cheat and use the built in generator.&lt;br /&gt;&lt;pre&gt;./script/generate rspec_scaffold -f Post title:string body:text&lt;/pre&gt;&lt;br /&gt;Obvious, going this route means I've broken my previously completed feature, so out of curiosity lets check it out.&lt;br /&gt;&lt;br /&gt;Running cucumber on the original feature:&lt;pre&gt;./script/cucumber features/reader_browse.feature&lt;/pre&gt;&lt;br /&gt;Produces the following:&lt;pre&gt;Feature: browsing&lt;br /&gt;As a reader&lt;br /&gt;I want to browse the site&lt;br /&gt;So that I can read it's content&lt;br /&gt;&lt;br /&gt; Scenario: visit the homepage       # features/reader_browse.feature:6&lt;br /&gt;   When I go to the homepage        # features/step_definitions/webrat_steps.rb:10&lt;br /&gt;   Then I should see "Hello world!" # features/step_definitions/webrat_steps.rb:93&lt;br /&gt;     expected the following element's content to include "Hello world!":&lt;br /&gt;     Posts: index&lt;br /&gt;     Listing posts&lt;br /&gt;     Title&lt;br /&gt;  Body&lt;br /&gt;New post&lt;br /&gt;      (Spec::Expectations::ExpectationNotMetError)&lt;br /&gt;     features/reader_browse.feature:8:in `Then I should see "Hello world!"'&lt;br /&gt;&lt;br /&gt;1 scenario&lt;br /&gt;1 failed step&lt;br /&gt;1 passed step&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Broken as expected.  The problem is that the index page no longer has the "Hello world!" text on it.  No problem we'll fix that later, for now lets keep going on the new feature.  &lt;br /&gt;&lt;br /&gt;When I run cucumber now:&lt;pre&gt;./script/cucumber features/author_publish.feature&lt;/pre&gt;&lt;br /&gt;I get:&lt;pre&gt;Feature: author publish&lt;br /&gt;As an author&lt;br /&gt;I want to publish a post&lt;br /&gt;So that it can be read&lt;br /&gt;&lt;br /&gt;Scenario: publish a post                    # features/author_publish.feature:6&lt;br /&gt;  Given I am on the post creation page      # features/step_definitions/webrat_steps.rb:6&lt;br /&gt;  When I add a new post                     # features/author_publish.feature:8&lt;br /&gt;  Then I should see a page for the new post # features/author_publish.feature:9&lt;br /&gt;&lt;br /&gt;1 scenario&lt;br /&gt;2 undefined steps&lt;br /&gt;1 passed step&lt;br /&gt;&lt;br /&gt;You can implement step definitions for missing steps with these snippets:&lt;br /&gt;&lt;br /&gt;When /^I add a new post$/ do&lt;br /&gt;pending&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;Then /^I should see a page for the new post$/ do&lt;br /&gt;pending&lt;br /&gt;end&lt;/pre&gt;&lt;br /&gt;So now the it's obviously finding the 'the post creation page' but the remaining When/Then are still pending.&lt;br /&gt;&lt;br /&gt;So now I add the following code:&lt;pre class="ruby"&gt;&lt;span class="comment"&gt;# RAILS_ROOT/features/step_definitions/publish_steps&lt;/span&gt;&lt;br /&gt;&lt;span class="constant"&gt;When&lt;/span&gt; &lt;span class="punct"&gt;/^&lt;/span&gt;&lt;span class="constant"&gt;I&lt;/span&gt; &lt;span class="ident"&gt;add&lt;/span&gt; &lt;span class="ident"&gt;a&lt;/span&gt; &lt;span class="ident"&gt;new&lt;/span&gt; &lt;span class="ident"&gt;post&lt;/span&gt;&lt;span class="global"&gt;$/&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;&lt;br /&gt;  &lt;span class="ident"&gt;fill_in&lt;/span&gt; &lt;span class="punct"&gt;"&lt;/span&gt;&lt;span class="string"&gt;Title&lt;/span&gt;&lt;span class="punct"&gt;"&lt;/span&gt; &lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:with&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;"&lt;/span&gt;&lt;span class="string"&gt;Some Title&lt;/span&gt;&lt;span class="punct"&gt;"&lt;/span&gt;&lt;br /&gt;  &lt;span class="ident"&gt;click_button&lt;/span&gt; &lt;span class="punct"&gt;"&lt;/span&gt;&lt;span class="string"&gt;Create&lt;/span&gt;&lt;span class="punct"&gt;"&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Then I run cucumber:&lt;pre&gt;./script/cucumber features/author_publish.feature&lt;/pre&gt;&lt;br /&gt;And get the following:&lt;pre&gt;Feature: author publish&lt;br /&gt;As an author&lt;br /&gt;I want to publish a post&lt;br /&gt;So that it can be read&lt;br /&gt;&lt;br /&gt; Scenario: publish a post                    # features/author_publish.feature:6&lt;br /&gt;   Given I am on the post creation page      # features/step_definitions/webrat_steps.rb:6&lt;br /&gt;   When I add a new post                     # features/step_definitions/posts_steps.rb:1&lt;br /&gt;   Then I should see a page for the new post # features/author_publish.feature:9&lt;br /&gt;&lt;br /&gt;1 scenario&lt;br /&gt;1 undefined step&lt;br /&gt;2 passed steps&lt;br /&gt;&lt;br /&gt;You can implement step definitions for missing steps with these snippets:&lt;br /&gt;&lt;br /&gt;Then /^I should see a page for the new post$/ do&lt;br /&gt; pending&lt;br /&gt;end&lt;/pre&gt;&lt;br /&gt;Now I just need to satisfy the 'Then'&lt;pre class="ruby"&gt;&lt;span class="comment"&gt;# RAILS_ROOT/features/step_definitions/publish_steps&lt;/span&gt;&lt;br /&gt;&lt;span class="constant"&gt;Then&lt;/span&gt; &lt;span class="punct"&gt;/^&lt;/span&gt;&lt;span class="constant"&gt;I&lt;/span&gt; &lt;span class="ident"&gt;should&lt;/span&gt; &lt;span class="ident"&gt;see&lt;/span&gt; &lt;span class="ident"&gt;a&lt;/span&gt; &lt;span class="ident"&gt;page&lt;/span&gt; &lt;span class="keyword"&gt;for&lt;/span&gt; &lt;span class="ident"&gt;the&lt;/span&gt; &lt;span class="ident"&gt;new&lt;/span&gt; &lt;span class="ident"&gt;post&lt;/span&gt;&lt;span class="global"&gt;$/&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;&lt;br /&gt;  &lt;span class="ident"&gt;response&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;should&lt;/span&gt; &lt;span class="ident"&gt;contain&lt;/span&gt;&lt;span class="punct"&gt;("&lt;/span&gt;&lt;span class="string"&gt;Post was successfully created&lt;/span&gt;&lt;span class="punct"&gt;")&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Then I run cucumber and get the following:&lt;pre&gt;Feature: author publish&lt;br /&gt;As an author&lt;br /&gt;I want to publish a post&lt;br /&gt;So that it can be read&lt;br /&gt;&lt;br /&gt;Scenario: publish a post                    # features/author_publish.feature:6&lt;br /&gt;  Given I am on the post creation page      # features/step_definitions/webrat_steps.rb:6&lt;br /&gt;  When I add a new post                     # features/step_definitions/publish_steps.rb:1&lt;br /&gt;  Then I should see a page for the new post # features/step_definitions/publish_steps.rb:6&lt;br /&gt;&lt;br /&gt;1 scenario&lt;br /&gt;3 passed steps&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Everything works, except the feature I broke, but I'll pick up there in the next post.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=DrxY6gtW8tk:TxsEY21bTXE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/DrxY6gtW8tk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/1352938684461231863/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=1352938684461231863" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/1352938684461231863?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/1352938684461231863?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/DrxY6gtW8tk/baby-step-2-with-rails-rspec-and.html" title="Baby Step #2 with Rails, RSpec and Cucumber" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2009/03/baby-step-2-with-rails-rspec-and.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0UERX06cCp7ImA9WxVUGU4.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-9102011676049797356</id><published>2009-03-24T13:18:00.000-07:00</published><updated>2009-03-24T14:46:44.318-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-24T14:46:44.318-07:00</app:edited><title>The Importance of Roles in BDD</title><content type="html">As I continue to try wrap my head around &lt;a href="http://wiki.github.com/aslakhellesoy/cucumber"&gt;Cucumber&lt;/a&gt;, &lt;a href="http://rspec.info/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;RSpec&lt;/span&gt;&lt;/a&gt; and &lt;a href="http://dannorth.net/introducing-bdd"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;BDD&lt;/span&gt;&lt;/a&gt; I found myself struggling  while trying to write stories.  Then I found this &lt;a href="http://blog.josephwilk.net/ruby/telling-a-good-story-rspec-stories-from-the-trenches.html#comment-570"&gt;comment&lt;/a&gt; from &lt;a href="http://www.benmabey.com/"&gt;Ben &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;Mabey&lt;/span&gt;&lt;/a&gt; on one of &lt;a href="http://blog.josephwilk.net/"&gt;Joseph &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;Wilk&lt;/span&gt;'&lt;/a&gt;s blog articles;  &lt;a href="http://blog.josephwilk.net/ruby/telling-a-good-story-rspec-stories-from-the-trenches.html"&gt;"Telling a good story - &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;respec&lt;/span&gt; stories from the trenches"&lt;/a&gt;.  It really helped to provide something I was missing, an undertstanding of how important the story tellers perspective is.&lt;br /&gt;&lt;br /&gt;After reading that I defined a very specific set of roles (Admin, Author, Editor, Hacker and  Reader) that I'll be using as I write my stories.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=TanNbP5yyrc:EC8MBrryPHo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/TanNbP5yyrc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/9102011676049797356/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=9102011676049797356" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/9102011676049797356?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/9102011676049797356?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/TanNbP5yyrc/importance-of-roles-in-bdd.html" title="The Importance of Roles in BDD" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2009/03/importance-of-roles-in-bdd.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkcARXc9eyp7ImA9WxJSEkU.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-6833817035142700885</id><published>2009-03-23T14:13:00.000-07:00</published><updated>2009-05-02T10:07:24.963-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-02T10:07:24.963-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="BDDBlog" /><category scheme="http://www.blogger.com/atom/ns#" term="Ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><category scheme="http://www.blogger.com/atom/ns#" term="cucumber" /><title>Baby Step #1 with Rails, RSpec and Cucumber</title><content type="html">There are lots of resources on the web to help get started with RSpec and Cucumber but there's still a learning curve that I think only experience will overcome.  So I decided just to dive in.  I don't claim what I've done here is right, or even a good idea, but it's where I started.&lt;br /&gt;&lt;br /&gt;My initial goal is just to walk through the 'outside in' &lt;a href="http://jamesshore.com/Blog/Red-Green-Refactor.html"&gt;red/green/refactor&lt;/a&gt; process of writing a feature then examples without spending to much time worrying if I selected the right story or if it's implemented it correctly.&lt;br /&gt;&lt;br /&gt;This initial cycle is mostly about learning what the tools can do for me.&lt;br /&gt;&lt;br /&gt;The simplest story that I can imagine goes like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;as a reader I want to browse the site so that I can read it's content.&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So with that story in hand It's time to write my first feature&lt;br /&gt;&lt;pre&gt; #  ./features/reader_browses.feature&lt;br /&gt;Feature: browsing&lt;br /&gt; As a reader&lt;br /&gt; I want to browse the site&lt;br /&gt; So that I can view it's content&lt;br /&gt;&lt;br /&gt;Scenario: visit the homepage&lt;br /&gt; When I go to the homepage&lt;br /&gt; Then I should see "Hello world!"&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Next I run Cucumber, 'rake features', and get the following....&lt;br /&gt;&lt;br /&gt;&lt;pre&gt; Feature: browsing&lt;br /&gt; As a reader&lt;br /&gt; I want to browse the site&lt;br /&gt; So that I can view it's content&lt;br /&gt;&lt;br /&gt;Scenario: visit the homepage       # features/reader_browses.feature:6&lt;br /&gt; When I go to the homepage        # features/step_definitions/webrat_steps.rb:10&lt;br /&gt;   undefined method `root_path' for #&lt;actioncontroller::integration::session:0xb6e35da8&gt; (NoMethodError)&lt;br /&gt;   /home/mgreenly/Projects/blog/features/support/paths.rb:6:in `/^I go to (.+)$/'&lt;br /&gt;   features/reader_browses.feature:7:in `When I go to the homepage'&lt;br /&gt; Then I should see "Hello world!" # features/step_definitions/webrat_steps.rb:93&lt;br /&gt;&lt;br /&gt;1 scenario&lt;br /&gt;1 failed step&lt;br /&gt;1 skipped step&lt;br /&gt;rake aborted!&lt;/actioncontroller::integration::session:0xb6e35da8&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So the first error I get is because we don't have a default route, so lets fix it by adding the following line in "./config/routes.rb"&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;map.root :controller =&gt; 'posts'&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Then I run Cucumber again, "rake features", and get the following....&lt;br /&gt;&lt;br /&gt;&lt;pre&gt; Feature: browsing&lt;br /&gt;As a reader&lt;br /&gt;I want to browse the site&lt;br /&gt;So that I can read it's content&lt;br /&gt;&lt;br /&gt;Scenario: visit the homepage       # features/reader_browse.feature:6&lt;br /&gt; When I go to the homepage        # features/step_definitions/webrat_steps.rb:10&lt;br /&gt;   uninitialized constant PostsController (NameError)&lt;br /&gt;   (eval):2:in `/^I go to (.+)$/'&lt;br /&gt;   features/reader_browse.feature:7:in `When I go to the homepage'&lt;br /&gt; Then I should see "Hello world!" # features/step_definitions/webrat_steps.rb:93&lt;br /&gt;&lt;br /&gt;1 scenario&lt;br /&gt;1 failed step&lt;br /&gt;1 skipped step&lt;br /&gt;rake aborted!&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So now it's telling me that the default route points to a PostsController and that controller doesn't exist.  So lets create both the controller and it's rspec framework with the built in generator.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;./script/generate rspec_controller posts&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now I'll run the spec, "rake spec", to see what I get&lt;br /&gt;&lt;pre&gt; ..&lt;br /&gt;&lt;br /&gt;Finished in 0.045209 seconds&lt;br /&gt;&lt;br /&gt;2 examples, 0 failures&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;It passes of course because the controller doesn't do anything and the spec doesn't make any requirements on it.&lt;br /&gt;&lt;br /&gt;So lets see what Cucumber says now, "rake features"&lt;br /&gt;&lt;pre&gt; Feature: browsing&lt;br /&gt; As a reader&lt;br /&gt; I want to browse the site&lt;br /&gt; So that I can view it's content&lt;br /&gt;&lt;br /&gt;Scenario: visit the homepage       # features/reader_browses.feature:6&lt;br /&gt; When I go to the homepage        # features/step_definitions/webrat_steps.rb:10&lt;br /&gt;   No action responded to index. Actions:  (ActionController::UnknownAction)&lt;br /&gt;   /usr/local/stow/ruby-1.8.7-p72/lib/ruby/1.8/benchmark.rb:308:in `realtime'&lt;br /&gt;   (eval):2:in `/^I go to (.+)$/'&lt;br /&gt;   features/reader_browses.feature:7:in `When I go to the homepage'&lt;br /&gt; Then I should see "Hello world!" # features/step_definitions/webrat_steps.rb:93&lt;br /&gt;&lt;br /&gt;1 scenario&lt;br /&gt;1 failed step&lt;br /&gt;1 skipped step&lt;br /&gt;rake aborted!&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;There's still an error but it's changed.  Now it's complaining because the there's no 'index' action on the Posts controller.  So lets drop back to the rspec example for the Posts controller and create a requirement for the index action.  Remember first I want it to fail, then pass.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;# in ./spec/controllers/posts_controller_spec.rb&lt;br /&gt;describe "GET 'index'" do&lt;br /&gt;it "should be successful" do&lt;br /&gt;get 'index'&lt;br /&gt;  response.should be_success&lt;br /&gt;end&lt;br /&gt;end&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So now when I run "rake spec" I get....&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;.F.&lt;br /&gt;&lt;br /&gt;1)&lt;br /&gt;ActionController::UnknownAction in 'PostsController GET 'index' should be successful'&lt;br /&gt;No action responded to index. Actions:&lt;br /&gt;./spec/controllers/posts_controller_spec.rb:12:&lt;br /&gt;&lt;br /&gt;Finished in 0.052123 seconds&lt;br /&gt;&lt;br /&gt;3 examples, 1 failure&lt;br /&gt;rake aborted!&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now that the spec is failing we can try to satisfy it.  To do that I just create an empty file at "app/views/posts/index.erb" and then rerun "rake spec"&lt;br /&gt;&lt;pre&gt; ...&lt;br /&gt;&lt;br /&gt;Finished in 0.049891 seconds&lt;br /&gt;&lt;br /&gt;3 examples, 0 failures&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So now that the spec passes I run Cucumber again, "rake features", and get ....&lt;br /&gt;&lt;pre&gt; Feature: browsing&lt;br /&gt; As a reader&lt;br /&gt; I want to browse the site&lt;br /&gt; So that I can view it's content&lt;br /&gt;&lt;br /&gt;Scenario: visit the homepage       # features/reader_browses.feature:6&lt;br /&gt; When I go to the homepage        # features/step_definitions/webrat_steps.rb:10&lt;br /&gt; Then I should see "Hello world!" # features/step_definitions/webrat_steps.rb:93&lt;br /&gt;   Could not parse document (RuntimeError)&lt;br /&gt;   features/reader_browses.feature:8:in `Then I should see "Hello world!"'&lt;br /&gt;&lt;br /&gt;1 scenario&lt;br /&gt;1 failed step&lt;br /&gt;1 passed step&lt;br /&gt;rake aborted!&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;It's still failing but now it's upset because it can't find the "Hello world!" text on the index page.  This is easy to fix, I just need to add the text to "app/views/posts/index.erb".  Now I  run "rake features".....&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Feature: browsing&lt;br /&gt; As a reader&lt;br /&gt; I want to browse the site&lt;br /&gt; So that I can view it's content&lt;br /&gt;&lt;br /&gt;Scenario: visit the homepage       # features/reader_browses.feature:6&lt;br /&gt; When I go to the homepage        # features/step_definitions/webrat_steps.rb:10&lt;br /&gt; Then I should see "Hello world!" # features/step_definitions/webrat_steps.rb:93&lt;br /&gt;&lt;br /&gt;1 scenario&lt;br /&gt;2 passed steps&lt;/pre&gt;&lt;br /&gt;It passes.  Just to make sure I didn't screw anything up I run "rake spec" on more time.&lt;br /&gt;&lt;pre&gt;...&lt;br /&gt;Finished in 0.049713 seconds&lt;br /&gt;3 examples, 0 failures&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;That makes one successfull pass through an outside-in red/green/refactor cycle using Cucumber and Rspec with Rails.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=Q4V2yM8q9A4:X-4mYlqjuZc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/Q4V2yM8q9A4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/6833817035142700885/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=6833817035142700885" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/6833817035142700885?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/6833817035142700885?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/Q4V2yM8q9A4/baby-step-1-with-rails-rspec-and.html" title="Baby Step #1 with Rails, RSpec and Cucumber" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2009/03/baby-step-1-with-rails-rspec-and.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUEDRHs9fyp7ImA9WxVUGEs.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-2479279133790238391</id><published>2009-03-23T11:36:00.000-07:00</published><updated>2009-03-23T20:01:15.567-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-23T20:01:15.567-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="RSpec" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><category scheme="http://www.blogger.com/atom/ns#" term="cucumber" /><title>Start a BDD Rails Project</title><content type="html">I was starting a new rails project today that I plan on developing with Cucumber and RSpec.  I quickly realized that even though there are tons of tutorials out there none seemed to really describe the process of initializing a new project.  So here it is in a nutshell.&lt;pre&gt;$ rails blog&lt;br /&gt;$ cd blog&lt;br /&gt;$ ./script/generate rspec&lt;br /&gt;$ ./script/generate cucumber&lt;br /&gt;$ rake db:migrate&lt;/pre&gt;&lt;br /&gt;At this point you should be able to do a 'rake', 'rake spec' or 'rake features' command and not get any errors.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=az__g3clWgc:Ki37GUjgH30:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/az__g3clWgc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/2479279133790238391/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=2479279133790238391" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/2479279133790238391?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/2479279133790238391?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/az__g3clWgc/start-bdd-rails-project.html" title="Start a BDD Rails Project" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2009/03/start-bdd-rails-project.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0ADQn04cSp7ImA9WxVaEk0.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-198132643554223990</id><published>2009-03-23T07:33:00.000-07:00</published><updated>2009-04-08T09:56:13.339-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-08T09:56:13.339-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><category scheme="http://www.blogger.com/atom/ns#" term="ubuntu" /><title>Rails Development On Ubuntu</title><content type="html">There's no shortage of posts on the web describing how to setup Ubuntu for Rails development but I'm going to add one more anyway.  I choose to write this because none of the posts I ran across were geared towards a current Rails, RSpec, Cucumber, Git setup.&lt;br /&gt;&lt;br /&gt;I'm using Ubuntu 9.04 (JauntyJackalope) during this installation.&lt;br /&gt;&lt;br /&gt;First install Ruby and it's associated packages.&lt;pre&gt;sudo apt-get install ruby-full&lt;/pre&gt;&lt;br /&gt;Next install the native SQlite3 libraries and command line tools.&lt;pre&gt;sudo apt-get install sqlite3 libsqlite3-dev&lt;/pre&gt;&lt;br /&gt;Next install some native xml processing libraries used by webrat.&lt;pre&gt;sudo apt-get install libxml2-dev libxslt-dev&lt;/pre&gt;&lt;br /&gt;Next install Git&lt;pre&gt;sudo apt-get install git-core&lt;/pre&gt;&lt;br /&gt;Next install the tools necessary to build native rubygem extensions.&lt;pre&gt;sudo apt-get install ruby-dev build-essential&lt;/pre&gt;&lt;br /&gt;Next install RubyGems from source because the Ubuntu packages are usually not current.  I also prefer to install RubyGems into my $HOME directory because mixing source packages in with distribution managed packages is generally a bad idea.&lt;pre&gt;wget -c http://rubyforge.org/frs/download.php/45905/rubygems-1.3.1.tgz&lt;br /&gt;tar xvzf rubygems-1.3.1&lt;br /&gt;cd rubygems-1.3.1&lt;br /&gt;ruby setup.rb --prefix=$HOME/.rubygems --no-format-executable&lt;/pre&gt;&lt;br /&gt;Once that's done you need to set some environment variables so that; Ruby can find the gems library, RubyGems can find the gem repository and executable gems will be in the $PATH.  Add the following to the file $HOME/.bashrc&lt;br /&gt;&lt;pre&gt;export RUBYLIB=$HOME/.rubygems/lib&lt;br /&gt;export GEM_HOME=$HOME/.rubygems/gems&lt;br /&gt;export PATH=$HOME/.rubygems/bin:$GEM_HOME/bin:$PATH&lt;/pre&gt;&lt;br /&gt;Then make sure the RubyGems library is up-to-date and install all the necessary gems.&lt;pre&gt;gem update --system&lt;br /&gt;gem install rake rails rspec-rails cucumber webrat sqlite3-ruby&lt;/pre&gt;&lt;br /&gt;If you want to double check your installation you can try the following...&lt;pre&gt;ruby --version&lt;br /&gt;gem --version&lt;br /&gt;rails --version&lt;br /&gt;spec --version&lt;br /&gt;cucumber --version&lt;br /&gt;&lt;/pre&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=VreirmzYiMg:2tUJH9EaASs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/VreirmzYiMg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/198132643554223990/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=198132643554223990" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/198132643554223990?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/198132643554223990?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/VreirmzYiMg/rails-development-on-ubuntu.html" title="Rails Development On Ubuntu" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>3</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2009/03/rails-development-on-ubuntu.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUIFQn04fip7ImA9WxVUGE4.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-6929315273890001470</id><published>2009-03-23T07:04:00.000-07:00</published><updated>2009-03-23T12:45:13.336-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-23T12:45:13.336-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Ruby" /><title>RubyGems Documentation Index</title><content type="html">In case there's anyone out there that isn't aware; running RubyGems server provides browseable documentation at http://localhost:8808/ for all the installed gems that have rdocs.  This morning I decided to automate the launching of the gem server at startup by adding it to my bash profile.&lt;br /&gt;&lt;pre&gt;# in $HOME/.profile&lt;br /&gt;gem server --daemon&lt;/pre&gt;&lt;br /&gt;If you've previously installed some gems without documentation you can regenerate them this way.&lt;br /&gt;&lt;pre&gt;gem rdoc --all&lt;/pre&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=Izh9IWsvdRM:GXIbNiXWpx4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/Izh9IWsvdRM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/6929315273890001470/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=6929315273890001470" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/6929315273890001470?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/6929315273890001470?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/Izh9IWsvdRM/rubygems-documentation-index.html" title="RubyGems Documentation Index" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2009/03/rubygems-documentation-index.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkcHQnc-eSp7ImA9WxVWFEo.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-7991220154417375491</id><published>2009-02-24T03:09:00.000-08:00</published><updated>2009-02-24T03:13:53.951-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-02-24T03:13:53.951-08:00</app:edited><title>Twitter Search</title><content type="html">For the first time ever I actually used Twitter for something productive today.  I was having trouble with GMail this morning and was trying to decided how to verify if it was something on my end or Googles.  So I decided to try &lt;a href="http://search.twitter.com/search?q=gmail"&gt;http://search.twitter.com&lt;/a&gt; which gave me my answer as I watched tweets pile in announcing GMail was down.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=Pqu5T8fAQcI:YFulcLZ32xU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/Pqu5T8fAQcI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/7991220154417375491/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=7991220154417375491" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/7991220154417375491?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/7991220154417375491?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/Pqu5T8fAQcI/twitter-search.html" title="Twitter Search" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2009/02/twitter-search.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0UDQ30-cSp7ImA9WxVWE0g.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-5117947627535314140</id><published>2009-02-22T18:10:00.000-08:00</published><updated>2009-02-22T18:14:32.359-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-02-22T18:14:32.359-08:00</app:edited><title>Determine What Version Of Ubuntu Your're Running #2</title><content type="html">A while back I wrote a post about determining which version of Ubuntu you're running &lt;a href="http://blog.michaelgreenly.com/2008/06/determine-what-version-of-ubuntu-youre.html"&gt;here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;They've since added the rather annoying -v option to lsb_release so now I prefer this&lt;br /&gt;&lt;pre&gt;$ sudo apt-get install lsb-release&lt;br /&gt;$ lsb_release -drci&lt;br /&gt;# Distributor ID: Ubuntu&lt;br /&gt;# Description: Ubuntu 8.10&lt;br /&gt;# Release: 8.10&lt;br /&gt;# Codename: intrepid&lt;/pre&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=9-ArY7LNYVg:xB-vPENyVso:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/9-ArY7LNYVg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/5117947627535314140/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=5117947627535314140" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/5117947627535314140?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/5117947627535314140?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/9-ArY7LNYVg/determine-what-version-of-ubuntu-yourre.html" title="Determine What Version Of Ubuntu Your're Running #2" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2009/02/determine-what-version-of-ubuntu-yourre.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0ICR3gycCp7ImA9WxRVEUo.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-9084925703217513414</id><published>2008-11-08T13:13:00.000-08:00</published><updated>2008-11-08T13:26:06.698-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-11-08T13:26:06.698-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Gnome" /><category scheme="http://www.blogger.com/atom/ns#" term="Linux" /><category scheme="http://www.blogger.com/atom/ns#" term="ubuntu" /><title>Upgrading to Ubuntu 8.10 (Intrepid Ibex)</title><content type="html">In the past I've usually chose to run the early releases and install from scratch but, both because I'm busy and because my Laptop is so well supported out of the box these days I decided to do an upgrade this time around.&lt;br /&gt;&lt;br /&gt;Here's a decent &lt;a href="http://www.ubuntugeek.com/upgrade-ubuntu-804-hardy-heron-to-ubuntu-810-intrepid-ibix.html"&gt;how-to&lt;/a&gt; if anyone is looking for directions.&lt;br /&gt;&lt;br /&gt;The upgrade nearly went perfect.  There was just one problem.  There seems to be a bug in the Gnome upgrade that changes the way the bookmarks in the Places menu behave.&lt;br /&gt;&lt;br /&gt;Here's the&lt;a href="https://bugs.launchpad.net/ubuntu/+source/nautilus/+bug/260492"&gt; bug in Launchpad&lt;/a&gt; and here's the &lt;a href="https://bugs.launchpad.net/ubuntu/+source/nautilus/+bug/260492/comments/18"&gt;specific post&lt;/a&gt; that provided me with the fix.&lt;br /&gt;&lt;br /&gt;&lt;a href="https://bugs.launchpad.net/ubuntu/+source/nautilus/+bug/260492"&gt;&lt;/a&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=YE4Tah7sr_w:ObxhQdS0OzM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/YE4Tah7sr_w" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/9084925703217513414/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=9084925703217513414" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/9084925703217513414?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/9084925703217513414?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/YE4Tah7sr_w/upgrading-to-ubuntu-810-intrepid-ibex.html" title="Upgrading to Ubuntu 8.10 (Intrepid Ibex)" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2008/11/upgrading-to-ubuntu-810-intrepid-ibex.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkcNRng-eyp7ImA9WhRbFU4.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-810598572735474809</id><published>2008-08-10T07:59:00.000-07:00</published><updated>2012-02-06T06:21:37.653-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-02-06T06:21:37.653-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="debian" /><category scheme="http://www.blogger.com/atom/ns#" term="apt" /><category scheme="http://www.blogger.com/atom/ns#" term="Ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="ubuntu" /><title>Multiple Versions of Ruby On Ubuntu #2</title><content type="html">&lt;br /&gt;
&lt;span style="color: #cc0000; font-style: italic;"&gt;This post is from a time before &lt;a href="http://beginrescueend.com/"&gt;RVM&lt;/a&gt; or &lt;a href="https://github.com/sstephenson/rbenv"&gt;rbenv&lt;/a&gt; you should check out those instead.&lt;/span&gt;&lt;span style="color: #cc0000; font-style: italic;"&gt;.&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;span style="color: #cc0000;"&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
I recently changed how I'm handling multiple simultaneous Ruby installations and I'd like to share.&lt;br /&gt;
&lt;br /&gt;
What I needed was to make it convenient to switch between the system provided packages and specific, from source, installations.  After some experiments I decided to use 'update-alternatives' to do it.&lt;br /&gt;
&lt;br /&gt;
Here's a quick walk through...&lt;br /&gt;
&lt;br /&gt;
First I removed all of my Ruby and RubyGem environment variables, they're not needed.&lt;br /&gt;
&lt;br /&gt;
Then I installed Ubuntu's default Ruby packages via apt-get.&lt;br /&gt;
&lt;pre&gt;$ sudo apt-get install ruby irb ri rdoc libruby-extras rubygems ruby1.8-dev&lt;/pre&gt;
&lt;br /&gt;
Next I downloaded and installed alternate versions of Ruby from source.  In this example I'm going to use two additional versions; the newest stable release and the newest development release.&lt;br /&gt;
&lt;pre&gt;$ cd /tmp
$ wget -c ftp://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.7-p71.tar.gz
$ tar -xvzf ruby-1.8.7-p71.tar.gz
$ cd ruby-1.8.7-p71
$ ./configure --prefix=/opt/ruby-1.8.7-p71
$ make
$ sudo make install
$ wget -c ftp://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.0-3.tar.gz
$ tar -xvzf ruby-1.9.0-3.tar.gz
$ ./configure --prefix=/opt/ruby-ruby-1.9.0-3
$ make
$ sudo make install&lt;/pre&gt;
&lt;br /&gt;
At this point I have three versions of Ruby installed and each can be accessed through it's full path.&lt;br /&gt;
&lt;pre&gt;$ /usr/bin/ruby --version
# ruby 1.8.6 (2007-09-24 patchlevel 111) [i486-linux]
$ /opt/ruby-1.8.7-p71/bin/ruby --version
# ruby 1.8.7 (2008-08-08 patchlevel 71) [i686-linux]
$ /opt/ruby-1.9.0-r18217/bin/ruby --version
# ruby 1.9.0 (2008-07-25 revision 18217) [i686-linux]&lt;/pre&gt;
&lt;br /&gt;
You'll also notice that the default installation is the one provided by Ubuntu.&lt;br /&gt;
&lt;pre&gt;$ ruby --version
# ruby 1.8.6 (2007-09-24 patchlevel 111) [i486-linux]&lt;/pre&gt;
&lt;br /&gt;
Next we'll use 'update-alternatives' to make it a bit easier to switch between them.  You could do this on the command line but it becomes a fairly long nasty command so I found it easier to write a quick shell script and run it.  The script:&lt;br /&gt;
&lt;pre&gt;update-alternatives --install \
/usr/local/bin/ruby ruby /usr/bin/ruby 100 \
--slave /usr/local/bin/erb erb /usr/bin/erb \
--slave /usr/local/bin/gem gem /usr/bin/gem \
--slave /usr/local/bin/irb irb /usr/bin/irb \
--slave /usr/local/bin/rdoc rdoc /usr/bin/rdoc \
--slave /usr/local/bin/ri ri /usr/bin/ri \
--slave /usr/local/bin/testrb testrb /usr/bin/testrb

update-alternatives --install \
/usr/local/bin/ruby   ruby /opt/ruby-1.8.7-p71/bin/ruby 50 \
--slave /usr/local/bin/erb erb /opt/ruby-1.8.7-p71/bin/erb \
--slave /usr/local/bin/gem gem /opt/ruby-1.8.7-p71/bin/gem \
--slave /usr/local/bin/irb irb /opt/ruby-1.8.7-p71/bin/irb \
--slave /usr/local/bin/rdoc rdoc /opt/ruby-1.8.7-p71/bin/rdoc \
--slave /usr/local/bin/ri ri /opt/ruby-1.8.7-p71/bin/ri \
--slave /usr/local/bin/testrb testrb /opt/ruby-1.8.7-p71/bin/testrb

update-alternatives --install \
/usr/local/bin/ruby   ruby /opt/ruby-1.9.0-r18217/bin/ruby 25 \
--slave /usr/local/bin/erb erb /opt/ruby-1.9.0-r18217/bin/erb \
--slave /usr/local/bin/gem gem /opt/ruby-1.9.0-r18217/bin/gem \
--slave /usr/local/bin/irb irb /opt/ruby-1.9.0-r18217//bin/irb \
--slave /usr/local/bin/rdoc rdoc /opt/ruby-1.9.0-r18217/bin/rdoc \
--slave /usr/local/bin/ri ri /opt/ruby-1.9.0-r18217/bin/ri \
--slave /usr/local/bin/testrb testrb /opt/ruby-1.9.0-r18217/bin/testrb&lt;/pre&gt;
&lt;br /&gt;
What that does is create a group of applications under the generic name Ruby.  In addition each application has several slave applications tied to it; erb, irb, etc...  In defining each application we specify what symbolic link it will be accessed through and where the application is actually installed.  In my case Ubuntu installed Ruby in /usr/bin and the source installed versions are in /opt.  All of the installations will be accessed through the generic name Ruby and will have there symbolic links created in /usr/local/bin.  I choose /usr/local/bin because it supercedes /usr/bin in the default path.&lt;br /&gt;
&lt;br /&gt;
Before moving on make sure that 'update-alternatives' sees all of our Ruby installations:&lt;br /&gt;
&lt;pre&gt;$ update-alternatives --list ruby
# /opt/ruby-1.9.0-r18217/bin/ruby
# /opt/ruby-1.8.7-p71/bin/ruby
# /usr/bin/ruby&lt;/pre&gt;
&lt;br /&gt;
Now switching between them is as easy as running the 'update-alternatives' command and selecting the number of the installation you'd like to use.  Example:&lt;br /&gt;
&lt;pre&gt;$ sudo update-alternatives --config ruby&lt;/pre&gt;
&lt;br /&gt;
It's important to keep in mind that each installation is separate.  So for example if you install RubyGems while using /usr/bin/ruby it will not be available to /opt/ruby-1.9.0-r18217/bin/ruby, or /opt/ruby-1.8.7-p71/bin/ruby, etc.... &lt;br /&gt;
&lt;br /&gt;
While it's probably possible to use a shared repository for RubyGems across multiple installations I haven't tried it and instead have choosen to use multiple separate RubyGem installs, one for each Ruby installation.&lt;br /&gt;
&lt;br /&gt;
Also RubyGem's bindir will most likely not be in your path.  To get around this I created a short script called 'gemexec' in /usr/local/bin&lt;br /&gt;
&lt;pre class="ruby"&gt;&lt;span class="comment"&gt;#!/usr/bin/env ruby&lt;/span&gt;

&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;rubygems&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;

&lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="constant"&gt;ARGV&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;size&lt;/span&gt; &lt;span class="punct"&gt;&amp;gt;&lt;/span&gt; &lt;span class="number"&gt;1&lt;/span&gt;
&lt;span class="ident"&gt;exec&lt;/span&gt; &lt;span class="punct"&gt;"&lt;/span&gt;&lt;span class="string"&gt;&lt;span class="expr"&gt;#{Gem.bindir}&lt;/span&gt;/&lt;span class="expr"&gt;#{ARGV.shift}&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;",&lt;/span&gt;&lt;span class="constant"&gt;ARGV&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;join&lt;/span&gt;&lt;span class="punct"&gt;("&lt;/span&gt;&lt;span class="string"&gt; &lt;/span&gt;&lt;span class="punct"&gt;")&lt;/span&gt;
&lt;span class="keyword"&gt;else&lt;/span&gt;
&lt;span class="ident"&gt;exec&lt;/span&gt; &lt;span class="punct"&gt;"&lt;/span&gt;&lt;span class="string"&gt;&lt;span class="expr"&gt;#{Gem.bindir}&lt;/span&gt;/&lt;span class="expr"&gt;#{ARGV.shift}&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;"&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/pre&gt;
&lt;br /&gt;
This script uses the RubyGems installation of the currently selected Ruby to determine where the executable gem should be found, then runs it with any additional command line arguments provided.  example:&lt;br /&gt;
&lt;pre&gt;$ gemexec rake --version
# rake, version 0.8.1&lt;/pre&gt;
&lt;br /&gt;
With all that in place the only thing to watch out for is other peoples scripts that hardcode the shebang line with something like "#!/usr/bin/ruby".  What I do myself, and prefer in general, is to use "#!/usr/bin/env ruby".&lt;br /&gt;
&lt;br /&gt;
The previous '&lt;a href="http://blog.michaelgreenly.com/2007/12/multiple-ruby-version-on-ubuntu.html"&gt;multiple versions of ruby on ubuntu&lt;/a&gt;'.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=rVdl8bV-PG4:-aFAYtaKBBg:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/rVdl8bV-PG4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/810598572735474809/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=810598572735474809" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/810598572735474809?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/810598572735474809?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/rVdl8bV-PG4/multiple-versions-of-ruby-on-ubuntu-2.html" title="Multiple Versions of Ruby On Ubuntu #2" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>4</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2008/08/multiple-versions-of-ruby-on-ubuntu-2.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkQGQXo8eip7ImA9WxdbE0Q.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-142420869849270312</id><published>2008-08-10T07:36:00.000-07:00</published><updated>2008-08-10T11:52:00.472-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-08-10T11:52:00.472-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="CFLAGS" /><category scheme="http://www.blogger.com/atom/ns#" term="Linux" /><category scheme="http://www.blogger.com/atom/ns#" term="ubuntu" /><title>Setting CFLAGS #2</title><content type="html">It turns out that with GCC 4.2.1 and later there is a new 'native' architecture flag for '-march' and '-mtune' that simplifies the setting of 'CFLAGS' greatly.  Now instead of having to manually determine the exact architecture you can let GCC do it for you.  If you trust it. Example:&lt;br /&gt;&lt;pre&gt;CFLAGS="-march=native"&lt;br /&gt;CXXFLAGS="${CFLAGS}"&lt;br /&gt;export CFLAGS CXXFLAGS&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;previous post: '&lt;a href="http://blog.michaelgreenly.com/2008/04/setting-cflags.html"&gt;Setting CFLAGS&lt;/a&gt;'&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=x_tjJXh96SQ:qWolbnhLJRs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/x_tjJXh96SQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/142420869849270312/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=142420869849270312" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/142420869849270312?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/142420869849270312?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/x_tjJXh96SQ/setting-cflags-2.html" title="Setting CFLAGS #2" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2008/08/setting-cflags-2.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUEDRXc6fyp7ImA9WxdbE0Q.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-5579686236733750075</id><published>2008-06-28T11:39:00.000-07:00</published><updated>2008-08-10T12:47:54.917-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-08-10T12:47:54.917-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Linux" /><category scheme="http://www.blogger.com/atom/ns#" term="ubuntu" /><title>Determine What Version of Ubuntu You're Running?</title><content type="html">The best way to determine the version of an Ubuntu (or any LSB compliant distribution) is to use the lsb-release command:&lt;br /&gt;&lt;pre&gt;$ sudo apt-get install lsb-release&lt;br /&gt;$ lsb_release -a&lt;br /&gt;# Distributor ID: Ubuntu&lt;br /&gt;# Description: Ubuntu 8.04&lt;br /&gt;# Release: 8.04&lt;br /&gt;# Codename: hardy&lt;/pre&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=yxt5r3NbgHQ:EioY9NpI3Mk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/yxt5r3NbgHQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/5579686236733750075/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=5579686236733750075" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/5579686236733750075?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/5579686236733750075?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/yxt5r3NbgHQ/determine-what-version-of-ubuntu-youre.html" title="Determine What Version of Ubuntu You're Running?" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2008/06/determine-what-version-of-ubuntu-youre.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEENQHk5fyp7ImA9WxZaGEo.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-6035256048112525307</id><published>2008-05-03T20:32:00.001-07:00</published><updated>2008-05-03T20:44:51.727-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-05-03T20:44:51.727-07:00</app:edited><title>Gemified S3Sync on GitHub</title><content type="html">I created a shallow fork of the &lt;a href="http://s3sync.net/wiki"&gt;S3Sync&lt;/a&gt; project specifically to wrap it as a gem.  My intention is most likely to hack on it but I haven't done that yet.  The code is at &lt;a href="http://github.com/mgreenly"&gt;http://github.com/mgreenly&lt;/a&gt; and can be installed via rubygems (gem install mgreenly-s3sync) but first you'll need to check out the instructions at &lt;a href="http://gems.github.com/"&gt;http://gems.github.com/&lt;/a&gt;.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=EQ2HCQxy4ek:yZrp5BCoRXk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/EQ2HCQxy4ek" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/6035256048112525307/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=6035256048112525307" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/6035256048112525307?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/6035256048112525307?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/EQ2HCQxy4ek/gemified-s3sync-on-github.html" title="Gemified S3Sync on GitHub" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2008/05/gemified-s3sync-on-github.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0ICQns6eyp7ImA9WxZUFE4.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-6585591933754322807</id><published>2008-04-05T13:32:00.001-07:00</published><updated>2008-04-05T15:46:03.513-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-04-05T15:46:03.513-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="ubuntu" /><category scheme="http://www.blogger.com/atom/ns#" term="NetBeans" /><title>NetBeans on Ubuntu</title><content type="html">I'm usually a hardcore &lt;a href="http://www.vim.org/"&gt;Vim&lt;/a&gt; fan but I've started to use &lt;a href="http://www.netbeans.org/index.html"&gt;NetBeans&lt;/a&gt; for my &lt;a href="http://www.ruby-lang.org/en/"&gt;Ruby&lt;/a&gt; work.  It's a fairly typical install but the one quirk is that $JAVAHOME has to be defined for the installer and Ubuntu's JDK package doesn't set it.&lt;br /&gt;&lt;br /&gt;That's easily remedied though; download NetBeans, install the JDK and pass --javahome to the installer as a command line option.&lt;pre&gt;#&gt; netbeans-6.0.1-ml-linux.sh --java-home /&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;usr&lt;/span&gt;/lib/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;jvm&lt;/span&gt;/java-6-sun&lt;/pre&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=BVz07z3KX0Y:XtScos1JUNU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/BVz07z3KX0Y" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/6585591933754322807/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=6585591933754322807" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/6585591933754322807?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/6585591933754322807?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/BVz07z3KX0Y/netbeans-on-ubuntu.html" title="NetBeans on Ubuntu" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2008/04/netbeans-on-ubuntu.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEQFQHY7cSp7ImA9WxZUFEQ.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-333897334706228607</id><published>2008-04-05T09:08:00.000-07:00</published><updated>2008-04-06T07:31:51.809-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-04-06T07:31:51.809-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Linux" /><category scheme="http://www.blogger.com/atom/ns#" term="ubuntu" /><title>Ubuntu 8.04 "Hardy Heron"</title><content type="html">The new &lt;a href="http://www.ubuntu.com/"&gt;Ubuntu release, 8.04 "Hardy Heron"&lt;/a&gt;, is nearly out so I thought I'd take a few minutes to do a fresh 'from scratch' install on to my laptop, a &lt;a href="https://wiki.ubuntu.com/LaptopTestingTeam/DellLatitudeD830"&gt;Dell Latitude D830&lt;/a&gt;, &lt;span style="text-decoration: underline;"&gt;&lt;/span&gt; this weekend.  I was pleasently suprised that almost everything worked exactly as expected out of the box, including; wireless networking, dual head monitor support, suspend, hibernate, compiz, etc....&lt;br /&gt;&lt;br /&gt;There was one small but very critical change I had to make.  It appears that the &lt;a href="https://bugs.launchpad.net/ubuntu/+source/acpi-support/+bug/59695"&gt;ACPI hard drive load/unload bug&lt;/a&gt; has still not been fixed.  It's critically important that you apply &lt;a href="https://bugs.launchpad.net/ubuntu/+source/acpi-support/+bug/59695/comments/14"&gt;this work around&lt;/a&gt; unless you want your hard drive to die prematurely.&lt;br /&gt;&lt;br /&gt;There was one other non-critical change I made.  I didn't dig into the issue to understand it but for what ever reason the default ALSA settings don't support the audio pass through in the docking station.  Fortunately the fix is extremely simple.  You just need to install the "Gnome Alsa Mixer" and select the IEC958 check box.&lt;pre&gt;#&gt; sudo apt-get install gnome-alsamixer&lt;/pre&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://picasaweb.google.com/mgreenly/PublicImages/photo#5185793414446116418"&gt;&lt;img src="http://lh4.google.com/mgreenly/R_ejooqe7kI/AAAAAAAAAR8/OWy347hnQVI/s400/Screenshot-GNOME%20ALSA%20Mixer.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;I've been running Ubuntu on this laptop since the &lt;a href="http://releases.ubuntu.com/7.04/"&gt;7.04 Feisty Fawn&lt;/a&gt; release and this is by far the smoothest install yet.  In the past I've been reluctant to declare Ubuntu's desktop experience to be better than Windows but I think I'm finally convinced.&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=4nyprF36TXA:xRkhu3f78ys:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/4nyprF36TXA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/333897334706228607/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=333897334706228607" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/333897334706228607?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/333897334706228607?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/4nyprF36TXA/ubuntu-804-hardy-heron.html" title="Ubuntu 8.04 &quot;Hardy Heron&quot;" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>4</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2008/04/ubuntu-804-hardy-heron.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C04HRnc8fCp7ImA9WxVbEEo.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-1821924751414011201</id><published>2008-04-05T06:18:00.000-07:00</published><updated>2009-03-26T05:52:17.974-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-26T05:52:17.974-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="CFLAGS" /><category scheme="http://www.blogger.com/atom/ns#" term="Linux" /><category scheme="http://www.blogger.com/atom/ns#" term="ubuntu" /><title>Setting CFLAGS</title><content type="html">It turns out the&lt;a href="http://en.gentoo-wiki.com/wiki/Main_Page"&gt; &lt;/a&gt;&lt;a href="http://en.gentoo-wiki.com/wiki/Main_Page"&gt;gento-wiki&lt;/a&gt; has a great page indicating which GCC -march flag should be set for which CPUs.  To determine which CPU you have, run the following at a command prompt:&lt;br /&gt;&lt;pre&gt;#&gt; cat /proc/cpuinfo&lt;/pre&gt;&lt;br /&gt;It will yield a page of output.  The first few lines of output from my laptop are below:&lt;br /&gt;&lt;pre&gt;processor : 0&lt;br /&gt;vendor_id : GenuineIntel&lt;br /&gt;cpu family : 6&lt;br /&gt;model  : 15&lt;br /&gt;model name : Intel(R) Core(TM)2 Duo CPU     T7500  @ 2.20GHz&lt;br /&gt;stepping : 10&lt;/pre&gt;&lt;br /&gt;The part you're interested in is the 'cpu family' and 'model'.  Once you know those find the corresponding entries on&lt;a href="http://en.gentoo-wiki.com/wiki/Safe_Cflags"&gt; &lt;/a&gt;&lt;a href="http://en.gentoo-wiki.com/wiki/Safe_Cflags"&gt;http://gentoo-wiki.com/Safe_Cflags&lt;/a&gt;.  Then create an entry in $HOME/.bashrc file that looks something like this:&lt;br /&gt;&lt;pre&gt;CFLAGS="-march=prescott -O3"&lt;br /&gt;CXXFLAGS="${CFLAGS}"&lt;br /&gt;export CFLAGS CXXFLAGS&lt;/pre&gt;&lt;br /&gt;Of course substitute the -march value for the one you found on the wiki.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=K8JyQTiUjJE:3i_o4nnquZQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/K8JyQTiUjJE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/1821924751414011201/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=1821924751414011201" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/1821924751414011201?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/1821924751414011201?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/K8JyQTiUjJE/setting-cflags.html" title="Setting CFLAGS" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2008/04/setting-cflags.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0EBQX47eip7ImA9WxZVGU8.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-9073871677046592451</id><published>2008-03-30T18:36:00.000-07:00</published><updated>2008-03-30T19:14:10.002-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-03-30T19:14:10.002-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Bazaar" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><title>Cleaning Up Revision Histories</title><content type="html">A &lt;a href="https://lists.ubuntu.com/archives/bazaar/2008q1/039687.html"&gt;post&lt;/a&gt; in the the &lt;a href="https://lists.ubuntu.com/mailman/listinfo/bazaar"&gt;bazaar&lt;/a&gt; email group described a better approach (than I had been using) to manage merges from personal working branches.  For example; If I wanted to commit a change to the project 'Foo', according to the post, I'd do something like this...&lt;pre&gt;$&gt; bzr init-repo foo-branches&lt;br /&gt;$&gt; cd foo-branches&lt;br /&gt;$&gt; bzr branch http://example.com/foo-trunk trunk&lt;br /&gt;$&gt; bzr branch trunk workbranch&lt;br /&gt;$&gt; cd mybranch&lt;br /&gt;$&gt; # hack, commit, hack commit, repeat as necessary&lt;br /&gt;$&gt; cd ../trunk&lt;br /&gt;$&gt; bzr pull&lt;br /&gt;$&gt; bzr merge ../workbranch&lt;br /&gt;$&gt; bzr commit&lt;br /&gt;$&gt; bzr push&lt;br /&gt;&lt;/pre&gt;What I've done above is to first create a shared repository.  I do this because I'm going to be working with multiple branches of the same project.  Then I branch Foo's trunk into my new shared repository. Next I branch the trunk (that's in the repository) to my personal working branch, make all the changes and as many commits as I want.  When I'm done I go back to the trunk.  Pull it to make sure it's up to date.  Then merge in my changes.  Once I've done that I commit them and push them up to the server.&lt;br /&gt;&lt;br /&gt;If you're worried about disk space you can remove the working trees for any branch you're not currently working in.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=rhx-Z49XPoQ:B_aK_wFcuq4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/rhx-Z49XPoQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/9073871677046592451/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=9073871677046592451" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/9073871677046592451?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/9073871677046592451?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/rhx-Z49XPoQ/cleaning-up-revision-histories.html" title="Cleaning Up Revision Histories" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2008/03/cleaning-up-revision-histories.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0YFQHk_eCp7ImA9WxZVGU0.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-1196143929733324489</id><published>2008-03-30T11:00:00.000-07:00</published><updated>2008-03-30T11:18:31.740-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-03-30T11:18:31.740-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="personal" /><title>Inspirational Speeches</title><content type="html">My feeds contained a &lt;a href="http://www.scrollinondubs.com/2008/03/27/inspirational-speeches/"&gt;blog post from Sean Tierney&lt;/a&gt; in which he links to a couple of excellent speeches, both very much worth taking the time to watch.  He also mentions an &lt;a href="http://www.scrollinondubs.com/2006/03/03/opensource-goals-meme-a-social-experiment-in-becoming-write-brained/"&gt;older post of his about publicly sharing your goals&lt;/a&gt;.  Which I agree is an excellent idea and easily done with &lt;a href="http://www.43things.com"&gt;43Things.com&lt;/a&gt;.  You can find my recently started list &lt;a href="http://www.43things.com/person/mgreenly"&gt;here&lt;/a&gt;.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=_1_FHKiLrsc:97GFbNdtDFo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/_1_FHKiLrsc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/1196143929733324489/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=1196143929733324489" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/1196143929733324489?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/1196143929733324489?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/_1_FHKiLrsc/inspirational-speeches.html" title="Inspirational Speeches" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2008/03/inspirational-speeches.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0YAQ34zeCp7ImA9WxZVFEQ.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-6363659599252495594</id><published>2008-03-25T17:46:00.001-07:00</published><updated>2008-03-25T19:39:02.080-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-03-25T19:39:02.080-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="business" /><title>Modeling Magic</title><content type="html">I never dreamed I'd ever come to find business software an interesting domain to study but that's exactly what's happened.&lt;br /&gt;&lt;br /&gt;Like it was for many people, I first got interested in programming because of games.  In fact I can trace my interest to a specific event; I was about 10 and I was playing a game on an &lt;a href="http://en.wikipedia.org/wiki/Atari_8-bit_family"&gt;Atari 400&lt;/a&gt; computer and realized I had absolutely no understanding of how it worked.  Prior to that moment I thought there was nothing in the world more complex than a light switch but after that moment I wasn't so sure.  I had to learn how it worked; was it magic or a light switch?&lt;br /&gt;&lt;br /&gt;Well of course it was a light switch, a gazillion of them all packed on to a chip in fact, but while I was learning that I came to a realization, apparently one all programmers make; The only way to demonstrate your understanding of something was to model it in software.&lt;br /&gt;&lt;br /&gt;So now I find myself trying to model business processes but I'm not 100% sure there's not a bit of magic in this light switch.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=11W7MHqAi4c:9qPuAMMU_B0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/11W7MHqAi4c" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/6363659599252495594/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=6363659599252495594" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/6363659599252495594?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/6363659599252495594?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/11W7MHqAi4c/modeling-magic.html" title="Modeling Magic" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2008/03/modeling-magic.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEUBQ3cyfSp7ImA9WxZVFEQ.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-4356073822121685382</id><published>2008-03-25T17:28:00.000-07:00</published><updated>2008-03-25T17:44:12.995-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-03-25T17:44:12.995-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><title>Before Filtering HTTP Method Types</title><content type="html">Previously I wrote the post '&lt;a href="http://blog.michaelgreenly.com/2008/02/method-not-allowed.html"&gt;Method Not Allowed&lt;/a&gt;' which is about how I decided to handle unsupported HTTP &lt;a href="http://en.wikipedia.org/wiki/HTTP#Request_methods"&gt;request method types&lt;/a&gt; in my actions.  Today I realized I should &lt;a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself"&gt;DRY&lt;/a&gt; up my code and put this logic into a &lt;a href="http://api.rubyonrails.org/classes/ActionController/Filters/ClassMethods.html"&gt;before filter&lt;/a&gt;.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=D3BmikEUb1w:qtaWQ3YSPSs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/D3BmikEUb1w" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/4356073822121685382/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=4356073822121685382" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/4356073822121685382?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/4356073822121685382?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/D3BmikEUb1w/before-filtering-http-method-types.html" title="Before Filtering HTTP Method Types" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2008/03/before-filtering-http-method-types.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEQEQ3w5cCp7ImA9WxZVFEQ.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-5567915686597716708</id><published>2008-03-23T16:30:00.000-07:00</published><updated>2008-03-25T17:45:02.228-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-03-25T17:45:02.228-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Git" /><category scheme="http://www.blogger.com/atom/ns#" term="Bazaar" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><title>Bzr to Git</title><content type="html">I think it's safe to say that the Rails community has decided &lt;a href="http://git.or.cz/"&gt;git&lt;/a&gt; is the distributed revision control tool of choice.  Unfortunately for me I've been using &lt;a href="http://bazaar-vcs.org/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;bzr&lt;/span&gt;&lt;/a&gt; for the last year or so.  Lucky for me it's easy migrate from &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;bzr&lt;/span&gt; to git using &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;svn&lt;/span&gt; as an intermediary.&lt;br /&gt;&lt;pre&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;svnadmin&lt;/span&gt; create --&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;fs&lt;/span&gt;-type &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;fsfs&lt;/span&gt; /path/to/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;svn&lt;/span&gt;/project&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;cd&lt;/span&gt; /path/to/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;bzr&lt;/span&gt;/project&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;bzr&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;svn&lt;/span&gt;-push /path/to/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;svn&lt;/span&gt;/project/trunk&lt;br /&gt;git-&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;svn&lt;/span&gt; clone  -T /path/to/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;svn&lt;/span&gt;/project/trunk /path/to/git/project&lt;br /&gt;&lt;/pre&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=h_7bzFpT_Xg:13QHzXgfXQs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/h_7bzFpT_Xg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/5567915686597716708/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=5567915686597716708" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/5567915686597716708?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/5567915686597716708?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/h_7bzFpT_Xg/bzr-to-git.html" title="Bzr to Git" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2008/03/bzr-to-git.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C08DQHY5eSp7ImA9WxZXEUs.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-6961813378345430591</id><published>2008-02-27T16:12:00.000-08:00</published><updated>2008-02-27T17:24:31.821-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-02-27T17:24:31.821-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="GNU" /><category scheme="http://www.blogger.com/atom/ns#" term="Microsoft" /><title>GNU Apps On Windows?</title><content type="html">There's a &lt;a href="http://www.royalidea.com/site/?q=node/12"&gt;story circulating&lt;/a&gt; that Microsoft is going to provide a GNU compatible tool chain for Windows.  This would in theory allow pretty much any *nix application to run on Windows with very little or no change.&lt;br /&gt;&lt;br /&gt;I seriously doubt there's any truth in this mostly because it would create a horrible rift with their third party developers who'd they'd be throwing to the wolfs, but you never know, anythings possible.  There is no technical reason it can't be done.  Hell, from Microsoft's perspective, I'd think it would actually be easy.  After all both &lt;a href="http://www.mingw.org/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;MinGW&lt;/span&gt;&lt;/a&gt; and &lt;a href="http://cygwin.com/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;Cygwin&lt;/span&gt;&lt;/a&gt; already provide this functionality.  In fact all they'd really have to do is provide a standard re-distributable C library and compiler.&lt;br /&gt;&lt;br /&gt;Even though I think it's a bogus rumor I really do hope Microsoft does this.  I've always thought it was the one thing they could do that would guarantee them another 25 years of market dominance.  In fact it's the only thing I can think of that could buy them enough time to switch away from the "Software As A Product" business model.&lt;br /&gt;&lt;br /&gt;They just better hope other people are more forgiving than I am.  While I really want this to be true, it makes it easier for software I write to run on Windows, I have no personal interest in ever doing business with them again.  Any vendor who doesn't always try and do the right thing for their customers is not some one I want to give money to. &lt;br /&gt;&lt;br /&gt;After a decade of bullying everyone in the sandbox it's a bit hard to accept they really want to share there toys now and even worse for them I've come to realize most of the alternatives are significantly better.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=05G4yVP2enU:KKfnbn3e5Vk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/05G4yVP2enU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/6961813378345430591/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=6961813378345430591" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/6961813378345430591?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/6961813378345430591?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/05G4yVP2enU/gnu-apps-on-windows.html" title="GNU Apps On Windows?" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2008/02/gnu-apps-on-windows.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkcNRXgyfSp7ImA9WxZQGUk.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-3736296896659949003</id><published>2008-02-24T20:56:00.000-08:00</published><updated>2008-02-25T03:48:14.695-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-02-25T03:48:14.695-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Mongrel" /><category scheme="http://www.blogger.com/atom/ns#" term="Ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><category scheme="http://www.blogger.com/atom/ns#" term="Free Software" /><title>Marketing Open Source</title><content type="html">&lt;a href="http://www.zedshaw.com/"&gt;Zed Shaw&lt;/a&gt; gives a talk about &lt;a href="http://mongrel.rubyforge.org/"&gt;Mongrel&lt;/a&gt; where he touches heavily on how to market an Open Source project. It's worth watching if these things interest you at all, at the very least you'll learn what yak shaving is.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.infoq.com/presentations/zed-shaw-mongrel-loc-economics"&gt;http://www.infoq.com/presentations/zed-shaw-mongrel-loc-economics&lt;/a&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=s9XBT7imiZc:iAv-dCP8ZVU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/s9XBT7imiZc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/3736296896659949003/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=3736296896659949003" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/3736296896659949003?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/3736296896659949003?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/s9XBT7imiZc/marketing-open-source.html" title="Marketing Open Source" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2008/02/marketing-open-source.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D08NSXwyeyp7ImA9WxZQGUw.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-5559278470241677482</id><published>2008-02-23T11:03:00.000-08:00</published><updated>2008-02-24T21:04:58.293-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-02-24T21:04:58.293-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Refactoring" /><category scheme="http://www.blogger.com/atom/ns#" term="Git" /><category scheme="http://www.blogger.com/atom/ns#" term="Bazaar" /><title>Patch Bombing and Change Stashing</title><content type="html">I ran across the term &lt;span style="font-weight: bold;"&gt;'patch bombing'&lt;/span&gt; today, which could be defined as; &lt;span style="font-style: italic;"&gt;"multiple application logic changes all rolled into a single source code commit"&lt;/span&gt;, it's the opposite of an &lt;span style="font-weight: bold;"&gt;'atomic change'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I found the term relevant to a background thought I've been pickling over lately....&lt;br /&gt;&lt;br /&gt;It's not uncommon for me to be in the middle of adding a new feature when I run across a bit of crufty code that needs to be &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;refactored&lt;/span&gt;&lt;/span&gt;.  Which poses the problem; How do I do the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;refactoring&lt;/span&gt;&lt;/span&gt; with out mixing the change sets?&lt;br /&gt;&lt;br /&gt;In the past I'd just make both changes and write one fat commit message explaining everything but I always thought this approach &lt;a href="http://en.wikipedia.org/wiki/Code_smell"&gt;smelled bad&lt;/a&gt;.  Then, Jay Fields blogged about '&lt;a href="http://blog.jayfields.com/2008/02/using-patch-as-subversion-stash.html"&gt;using patch as subversion's stash&lt;/a&gt;' and turned me on to &lt;a href="http://kurt.karmalab.org/articles/2008/02/18/the-power-of-git-git-stash"&gt;'the power of git-stash&lt;/a&gt;'.&lt;br /&gt;&lt;br /&gt;It turns out that &lt;a href="http://bazaar-vcs.org/"&gt;Bazaar&lt;/a&gt;, which I'm using for my current project, doesn't directly support this operation either but Jay's patch-stashing approach works just as well for &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;bzr&lt;/span&gt;&lt;/span&gt; as it does for &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;svn&lt;/span&gt;&lt;/span&gt;.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=fDVUyt0Cfdk:hT-9_WiUg2M:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/fDVUyt0Cfdk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/5559278470241677482/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=5559278470241677482" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/5559278470241677482?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/5559278470241677482?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/fDVUyt0Cfdk/patch-bombing-and-change-stashing.html" title="Patch Bombing and Change Stashing" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2008/02/patch-bombing-and-change-stashing.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkMMQXwyfCp7ImA9WxZQF0Q.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-6836235485656198852</id><published>2008-02-22T19:30:00.000-08:00</published><updated>2008-02-23T11:21:20.294-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-02-23T11:21:20.294-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><title>Method Not Allowed</title><content type="html">Quite a bit of my old code just redirects when an action gets a request with an unsupported method, for example; &lt;span style="font-weight: bold;"&gt;'get&lt;/span&gt;' requests to &lt;span style="font-weight: bold;"&gt;'destroy'&lt;/span&gt; actions.  While my old approach prevented anything bad from happening it always seemed wrong.  It also made maintaining my tests a tiny bit more complicated because each seemed to have a different location they redirected to.&lt;br /&gt;&lt;br /&gt;So I decided to clean up the code in my current project today.  The obvious choice was to render an error template and return the proper status code.&lt;pre class="ruby"&gt;&lt;br /&gt; &lt;span class="comment"&gt;# file: app/controllers/parts_controller.rb&lt;/span&gt;&lt;br /&gt; &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;destroy&lt;/span&gt;&lt;br /&gt;   &lt;span class="keyword"&gt;unless&lt;/span&gt; &lt;span class="ident"&gt;request&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;delete?&lt;/span&gt;&lt;br /&gt;     &lt;span class="ident"&gt;render&lt;/span&gt; &lt;span class="symbol"&gt;:layout&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="constant"&gt;false&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:template&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;"&lt;/span&gt;&lt;span class="string"&gt;errors/405&lt;/span&gt;&lt;span class="punct"&gt;",&lt;/span&gt; &lt;span class="symbol"&gt;:status&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="number"&gt;405&lt;/span&gt;&lt;br /&gt;     &lt;span class="keyword"&gt;return&lt;/span&gt;&lt;br /&gt;   &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;   &lt;span class="keyword"&gt;begin&lt;/span&gt;&lt;br /&gt;     &lt;span class="constant"&gt;Part&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;find&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;params&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:id&lt;/span&gt;&lt;span class="punct"&gt;]).&lt;/span&gt;&lt;span class="ident"&gt;destroy&lt;/span&gt;&lt;br /&gt;     &lt;span class="ident"&gt;flash&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;now&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:success&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;"&lt;/span&gt;&lt;span class="string"&gt;The part has been successfully deleted.&lt;/span&gt;&lt;span class="punct"&gt;"&lt;/span&gt;&lt;br /&gt;   &lt;span class="keyword"&gt;rescue&lt;/span&gt;&lt;br /&gt;     &lt;span class="ident"&gt;flash&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:failure&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;"&lt;/span&gt;&lt;span class="string"&gt;Unable to delete part.&lt;/span&gt;&lt;span class="punct"&gt;"&lt;/span&gt;&lt;br /&gt;   &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt; &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;This also simplified my tests.&lt;pre class="ruby"&gt;&lt;br /&gt; &lt;span class="comment"&gt;# file: test/functional/parts_controller_test.rb&lt;/span&gt;&lt;br /&gt; &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;test_destroy_get&lt;/span&gt;&lt;br /&gt;   &lt;span class="ident"&gt;get&lt;/span&gt; &lt;span class="symbol"&gt;:destroy&lt;/span&gt;&lt;br /&gt;   &lt;span class="ident"&gt;assert_response&lt;/span&gt; &lt;span class="number"&gt;405&lt;/span&gt;&lt;br /&gt;   &lt;span class="ident"&gt;assert_template&lt;/span&gt;&lt;span class="punct"&gt;("&lt;/span&gt;&lt;span class="string"&gt;errors/405&lt;/span&gt;&lt;span class="punct"&gt;")&lt;/span&gt;&lt;br /&gt; &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=X0GVXcPYkys:4vYd6xWeBZU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/X0GVXcPYkys" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/6836235485656198852/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=6836235485656198852" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/6836235485656198852?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/6836235485656198852?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/X0GVXcPYkys/method-not-allowed.html" title="Method Not Allowed" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2008/02/method-not-allowed.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcCQX8yfCp7ImA9WxZRFks.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-6682054592903269920</id><published>2008-02-10T07:42:00.000-08:00</published><updated>2008-02-10T09:04:20.194-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-02-10T09:04:20.194-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="appserver" /><category scheme="http://www.blogger.com/atom/ns#" term="appliance" /><category scheme="http://www.blogger.com/atom/ns#" term="business" /><title>The Application Appliance</title><content type="html">&lt;span style="font-style: italic; color: rgb(51, 0, 51);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;This post is the continuation of a thread that started with:&lt;/span&gt;&lt;span style="color: rgb(51, 102, 255);"&gt; &lt;/span&gt;&lt;/span&gt;&lt;a style="font-style: italic; color: rgb(51, 102, 255);" href="http://blog.michaelgreenly.com/2008/02/opportunities.html"&gt;Opportunities&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The hardware it's self would not be remarkable in anyway and since I'm really only interested in the software stack the logical choice is to resell some other vendors machines preconfigured to meet my needs.&lt;br /&gt;&lt;br /&gt;At this point I'm not exactly sure who's machines I'll use but I'd prefer it to be a vendor that sees Ubuntu (or maybe Debian) as a first class target.  My short list at the moment really only contains &lt;a href="http://system76.com/"&gt;System76&lt;/a&gt; so if anyone has any other suggestions I'd love to hear from you?&lt;br /&gt;&lt;br /&gt;The software on the other hand is much more interesting.  The software will be delivered through a private apt repository as customized packages and include specifically configured base tools such as Apache, Postgres and Ruby as well as management tools for deployment, monitoring, replication and backup.&lt;br /&gt;&lt;br /&gt;Now obviously there's nothing special about this approach, in fact that's kind of the point.  I don't want to have to re-think the simple standard parts I want to focus on the newer more unique parts.  The management tools, replication and fail over to cloud services, etc...&lt;br /&gt;&lt;br /&gt;More later....&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=bq8ZNlzS0fM:H_C2nWwciuY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/bq8ZNlzS0fM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/6682054592903269920/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=6682054592903269920" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/6682054592903269920?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/6682054592903269920?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/bq8ZNlzS0fM/application-appliance.html" title="The Application Appliance" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2008/02/application-appliance.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CE4ASHs5fCp7ImA9WxZRFks.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-3159825341127052524</id><published>2008-02-02T06:41:00.001-08:00</published><updated>2008-02-10T09:02:29.524-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-02-10T09:02:29.524-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="appserver" /><category scheme="http://www.blogger.com/atom/ns#" term="appliance" /><category scheme="http://www.blogger.com/atom/ns#" term="business" /><title>My Opinionated Application Stack</title><content type="html">&lt;span style="font-style: italic; color: rgb(51, 0, 51);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;This post is the continuation of a thread that started with:&lt;/span&gt;&lt;span style="color: rgb(51, 102, 255);"&gt; &lt;/span&gt;&lt;/span&gt;&lt;a style="font-style: italic; color: rgb(51, 102, 255);" href="http://blog.michaelgreenly.com/2008/02/opportunities.html"&gt;Opportunities&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Recently I've been thinking a lot about different ways to minimize duplication of work.  Many of my projects have similar requirements, how best can I reuse the effort from one to the next?&lt;br /&gt;&lt;br /&gt;I've also been puzzling over another problem; How do I provide businesses with reliable application  when they don't have the necessary I.T. support to manage it and they don't have a reliable enough internet connection to go the "software as a service" route?&lt;br /&gt;&lt;br /&gt;It turns out that both questions may have the same answer.  An application appliance!  A low cost plug and play application server that's configured with a well defined software stack and the ability to backup to a remote service that is able to double as a warm standby in a pinch.&lt;br /&gt;&lt;br /&gt;In future posts I'll explain in more detail.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=GWYzDWvRQVU:bDhSEhFRl_k:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/GWYzDWvRQVU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/3159825341127052524/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=3159825341127052524" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/3159825341127052524?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/3159825341127052524?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/GWYzDWvRQVU/my-opinionated-application-stacks.html" title="My Opinionated Application Stack" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>3</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2008/02/my-opinionated-application-stacks.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CE8DRno_fSp7ImA9WxZRFks.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-7330974839958726677</id><published>2008-02-02T05:41:00.000-08:00</published><updated>2008-02-10T09:01:17.445-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-02-10T09:01:17.445-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="agile" /><category scheme="http://www.blogger.com/atom/ns#" term="appliance" /><category scheme="http://www.blogger.com/atom/ns#" term="tdd" /><category scheme="http://www.blogger.com/atom/ns#" term="opinionated" /><category scheme="http://www.blogger.com/atom/ns#" term="business" /><title>Opportunities</title><content type="html">A driving belief of mine is that there's an enormous &lt;a href="http://en.wikipedia.org/wiki/The_Long_Tail"&gt;long tail&lt;/a&gt; associated with the custom business software market.  It exists because software development is difficult and in the past only the deepest pockets have typically tried to tackle the problem but I think this has already began to change!   Things like agile test driven development methodologies, the use of free software, and opinionated design are going to make it a reality.&lt;br /&gt;&lt;br /&gt;I'd like to share my recipe for this but you'll need to keep in mind I'm focusing on the really (really) small business that just doesn't register on the radar of more established custom software providers.&lt;br /&gt;&lt;br /&gt;It's really simple and goes something like this...&lt;br /&gt;&lt;br /&gt;Stick to the small projects that can be completed quickly.  Every business has itches that need to be scratched.  Keep the customer involved, which should be easy if you're focusing on a real itches and provide a turn key (nearly) zero administration solution.&lt;br /&gt;&lt;br /&gt;Which gets me to what I wanted to talk about, &lt;a href="http://blog.michaelgreenly.com/2008/02/my-opinionated-application-stacks.html"&gt;my opinionated application stack&lt;/a&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=rRmIl2l4HSU:xNLHB9Bl1-Y:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/rRmIl2l4HSU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/7330974839958726677/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=7330974839958726677" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/7330974839958726677?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/7330974839958726677?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/rRmIl2l4HSU/opportunities.html" title="Opportunities" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2008/02/opportunities.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkAER3w5fip7ImA9WxZSGUQ.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-1414146856189645833</id><published>2008-02-01T17:23:00.000-08:00</published><updated>2008-02-02T14:18:26.226-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-02-02T14:18:26.226-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="fcgid" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><category scheme="http://www.blogger.com/atom/ns#" term="apache" /><title>My Apache Setup</title><content type="html">I've been using Apache2 with mod_fcgid for quite a while because it's good enough.  I use it primarily because it's really simple to administer and I'm hosting internal business applications with very little load on them.  Here's my setup...&lt;br /&gt;&lt;br /&gt;Installation is really straight forward&lt;pre&gt;$&gt; sudo apt-get install apache2 libapache2-mod-fcgid&lt;br /&gt;$&gt; a2enmod fcgid&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;default config&lt;br /&gt;&lt;pre&gt;# serve everything from /var/www/ and use /var/www/default as the document root&lt;br /&gt;&lt;br /&gt;ServerAdmin webmaster@hostname&lt;br /&gt;&lt;br /&gt;# setup logs&lt;br /&gt;ErrorLog /var/log/apache2/error.log&lt;br /&gt;CustomLog /var/log/apache2/access.log combined&lt;br /&gt;LogLevel warn\&lt;br /&gt;&lt;br /&gt;# limit the amount of info about server&lt;br /&gt;ServerSignature Off&lt;br /&gt;&lt;br /&gt;# default permissions to all files&lt;br /&gt;&amp;lt;Directory /&amp;gt;&lt;br /&gt;  Options FollowSymLinks&lt;br /&gt;  AllowOverride None&lt;br /&gt;&amp;lt;/Directory&amp;gtp;&lt;br /&gt;&lt;br /&gt;# setup document root and permissions&lt;br /&gt;DocumentRoot /var/www/default&lt;br /&gt;&amp;lt;Directory /var/www/default&amp;gt;&lt;br /&gt;  Options +FollowSymLinks +MultiViews&lt;br /&gt;  AllowOverride None&lt;br /&gt;  Order allow,deny&lt;br /&gt;  allow from all&lt;br /&gt;&amp;lt;/Directory&amp;gt;&lt;br /&gt;&lt;br /&gt;# define environment for fcgid processes&lt;br /&gt;DefaultInitEnv PATH "/opt/ruby/bin"&lt;br /&gt;DefaultInitEnv RAILS_ENV "production"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;per application config&lt;pre&gt;# run the app from /var/www/appname and serve it aliased as http://hostname/appname&lt;br /&gt;&lt;br /&gt;Alias /appname "/var/www/appname/current/public"&lt;br /&gt;&amp;lt;Directory /var/www/appname/current/public/&amp;gt;&lt;br /&gt;&lt;br /&gt;  Options -Indexes +MultiViews +FollowSymLinks +ExecCGI&lt;br /&gt;  AllowOverride None&lt;br /&gt;  Order deny,allow&lt;br /&gt;  Allow from all&lt;br /&gt;&lt;br /&gt;  RewriteEngine On&lt;br /&gt;&lt;br /&gt;  # provide support for cap deploy:web:disable&lt;br /&gt;  RewriteCond /var/www/appname/current/public/system/maintenance.html -f&lt;br /&gt;  RewriteCond %{SCRIPT_FILENAME} !maintenance.html&lt;br /&gt;  RewriteRule ^.*$ /appname/system/maintenance.html [L]&lt;br /&gt;&lt;br /&gt;  # standard rails rewrite with support for alias directory&lt;br /&gt;  RewriteBase /appname&lt;br /&gt;  RewriteRule ^$ index.html [QSA]&lt;br /&gt;  RewriteRule ^([^.]+)$ $1.html [QSA]&lt;br /&gt;  RewriteCond %{REQUEST_FILENAME} !-f&lt;br /&gt;  RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]&lt;br /&gt;&lt;br /&gt;  # define error documents&lt;br /&gt;  ErrorDocument 500 500.html&lt;br /&gt;&amp;lt;/Directory&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=eLLGcWSwUCQ:x9Mc59tLhLM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/eLLGcWSwUCQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/1414146856189645833/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=1414146856189645833" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/1414146856189645833?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/1414146856189645833?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/eLLGcWSwUCQ/my-apache-setup.html" title="My Apache Setup" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2008/02/my-apache-setup.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C04BQXY-eSp7ImA9WxZSGU8.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-3457143825468856457</id><published>2008-01-26T19:20:00.000-08:00</published><updated>2008-02-01T19:12:30.851-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-02-01T19:12:30.851-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Bazaar" /><category scheme="http://www.blogger.com/atom/ns#" term="apache" /><title>Setting Up A Shared Bazaar Repository</title><content type="html">Currently I'm using a &lt;a href="http://bazaar-vcs.org/Workflows#head-ca3ccf73574776b36453b2213789731549e54167"&gt;Decentralized Shared Mainline Repository&lt;/a&gt;.  Here's my recipe...&lt;br /&gt;&lt;br /&gt;You will of course need a server that's accessible to everyone.&lt;br /&gt;&lt;br /&gt;Create a group for project.&lt;br /&gt;&lt;pre&gt;$&gt; groupadd projectname&lt;/pre&gt;&lt;br /&gt;Create an login for each of the users who will have commit access to the shared mainline.&lt;br /&gt;&lt;pre&gt;$&gt; adduser --ingroup projectname username&lt;/pre&gt;&lt;br /&gt;Create a directory for the repostitory inside the web servers document root&lt;br /&gt;&lt;pre&gt;$&gt; mkdir /var/bzr/projectname&lt;/pre&gt;&lt;br /&gt;Set the project folders group to the project groups name&lt;br /&gt;&lt;pre&gt;$&gt; chown :projectname /var/bzr/projectname&lt;/pre&gt;&lt;br /&gt;Set the project folders permissions&lt;br /&gt;&lt;pre&gt;$&gt; chmod ug+rwx,g+s,o+rx,o-w projectname&lt;/pre&gt;&lt;br /&gt;Now you can push updates&lt;br /&gt;&lt;pre&gt;$&gt; bzr push bzr+ssh://hostname/var/bzr/projectname&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;If you need to provide anonymous access to the repository one way would be to serve it with Apache.&lt;br /&gt;&lt;pre&gt;Alias /bzr "/var/bzr"&lt;br /&gt;&amp;lt;Directory "/var/bzr"&amp;gt;&lt;br /&gt; Options +Indexes +MultiViews +FollowSymLinks&lt;br /&gt;  AllowOverride None&lt;br /&gt;  Order deny,allow&lt;br /&gt;  Allow from all&lt;br /&gt;&amp;lt;/Directory&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This would allow you to do something like this&lt;br /&gt;&lt;pre&gt;$&gt; bzr branch http://hostname/bzr/projectname&lt;/pre&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=qdBnmHNBRnA:hHBu317ePYs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/qdBnmHNBRnA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/3457143825468856457/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=3457143825468856457" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/3457143825468856457?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/3457143825468856457?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/qdBnmHNBRnA/setting-up-shared-bazaar-repository.html" title="Setting Up A Shared Bazaar Repository" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2008/01/setting-up-shared-bazaar-repository.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C08ESHg9cSp7ImA9WxZSGU8.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-1228696805400579405</id><published>2008-01-18T17:47:00.000-08:00</published><updated>2008-02-01T19:10:09.669-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-02-01T19:10:09.669-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><title>Obfuscating IDs in URLs with Rails</title><content type="html">There are a number of valid reasons to obfuscate IDs in URLs but it's not a replacement for authentication!&lt;br /&gt;&lt;br /&gt;My approach to this problem is to allow the database to assign a normal serial ID, which means I don't have to maintain any extra state or use special database features.  Then after it's created I save the obfuscated value of the id which I can use on later lookups.&lt;br /&gt;&lt;br /&gt;I use Knuth's integer hash because it ensures there will be no collisions and the full range of values will be used.&lt;br /&gt;&lt;br /&gt;In this example I'm using a signed 32 bit integer for the hashed_id because it's supported by all common Rails databases.  You could however adjust MAXID to any number of bits you want but then you may have to deal with storage and conversion issues.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Model:&lt;/span&gt;&lt;br /&gt;&lt;pre class="ruby"&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;Part&lt;/span&gt; &lt; &lt;span class="constant"&gt;ActiveRecord&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Base&lt;/span&gt;&lt;br /&gt;&lt;span class="constant"&gt;  PRIME&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="number"&gt;2654435761&lt;/span&gt;&lt;br /&gt;&lt;span class="constant"&gt;  MAXID&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="number"&gt;2&lt;/span&gt;&lt;span class="punct"&gt;**&lt;/span&gt;&lt;span class="number"&gt;31&lt;/span&gt;&lt;span class="punct"&gt;-&lt;/span&gt;&lt;span class="number"&gt;1&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;  def &lt;/span&gt;&lt;span class="method"&gt;after_create&lt;/span&gt;&lt;br /&gt;&lt;span class="constant"&gt;    self&lt;/span&gt;&lt;span class="punct"&gt;.hashed_id&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="constant"&gt;self&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;id&lt;/span&gt; &lt;span class="punct"&gt;*&lt;/span&gt; &lt;span class="constant"&gt;PRIME&lt;/span&gt; &lt;span class="punct"&gt;&amp;amp;&lt;/span&gt; &lt;span class="constant"&gt;MAXID&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="constant"&gt;    self&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;save&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;  end&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Controller:&lt;/span&gt;&lt;br /&gt;&lt;pre class="ruby"&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;PartsController&lt;/span&gt; &lt; &lt;span class="constant"&gt;ApplicationController&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;  def &lt;/span&gt;&lt;span class="method"&gt;show&lt;/span&gt;&lt;br /&gt;&lt;span class="attribute"&gt;    @part&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Part&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;find_by_hashed_id&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;params&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:id&lt;/span&gt;&lt;span class="punct"&gt;])&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;  end&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=CsEdgQj6QEM:ONnvVz5gkPI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/CsEdgQj6QEM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/1228696805400579405/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=1228696805400579405" title="9 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/1228696805400579405?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/1228696805400579405?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/CsEdgQj6QEM/obsificating-ids-in-urls.html" title="Obfuscating IDs in URLs with Rails" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>9</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2008/01/obsificating-ids-in-urls.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0AFR3g_fyp7ImA9WxZSGU8.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-1929135661620027760</id><published>2008-01-04T13:12:00.000-08:00</published><updated>2008-02-01T19:08:36.647-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-02-01T19:08:36.647-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Launchpad" /><title>Useful Launchpad Tips</title><content type="html">I ran across a useful &lt;a href="http://www.bryceharrington.org/drupal/node/18"&gt;blog post&lt;/a&gt; today that included some useful tips for for using &lt;a href="http://launchpad.net/"&gt;Launchpad&lt;/a&gt; that's worth sharing.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://article.gmane.org/gmane.comp.graphics.inkscape.devel/23326/match=launchpad+tips+tricks"&gt;basic of triaging&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://article.gmane.org/gmane.comp.graphics.inkscape.devel/23327/match=launchpad+tips+tricks"&gt;tags&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://article.gmane.org/gmane.comp.graphics.inkscape.devel/23413/match=launchpad+tips+tricks"&gt;duping bugs&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://article.gmane.org/gmane.comp.graphics.inkscape.devel/23415/match=launchpad+tips+tricks"&gt;tracking upstream bugs&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://thread.gmane.org/gmane.comp.graphics.inkscape.devel/23333/focus=23341"&gt;email managment&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://article.gmane.org/gmane.comp.graphics.inkscape.devel/23380/match=launchpad+tips+tricks"&gt;graphing bug metrics&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=V37AJJs6ElA:eTVuLvOePow:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/V37AJJs6ElA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/1929135661620027760/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=1929135661620027760" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/1929135661620027760?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/1929135661620027760?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/V37AJJs6ElA/useful-launchpad-tips.html" title="Useful Launchpad Tips" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2008/01/useful-launchpad-tips.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkUFSXwzeCp7ImA9WhRbFU4.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-925192477314217119</id><published>2007-12-27T19:36:00.000-08:00</published><updated>2012-02-06T06:23:38.280-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-02-06T06:23:38.280-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="debian" /><category scheme="http://www.blogger.com/atom/ns#" term="apt" /><category scheme="http://www.blogger.com/atom/ns#" term="Ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="ubuntu" /><title>Multiple Versions of Ruby On Ubuntu</title><content type="html">&lt;span style="font-size: 85%;"&gt;&lt;span style="color: #cc0000; font-size: small; font-style: italic;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: 85%;"&gt;&lt;span style="color: #cc0000; font-size: small; font-style: italic;"&gt;This post is from a time before&amp;nbsp;&lt;a href="http://beginrescueend.com/"&gt;RVM&lt;/a&gt;&amp;nbsp;or&amp;nbsp;&lt;a href="https://github.com/sstephenson/rbenv"&gt;rbenv&lt;/a&gt;&amp;nbsp;you should check out those instead.&lt;/span&gt;&lt;span style="color: #cc0000; font-size: small; font-style: italic;"&gt;.&lt;/span&gt;&lt;span style="color: #000099; font-style: italic; font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
With Ruby 1.9 out there's the obvious possiblitity some people will want to run multiple versions of Ruby so I thought I'd share this.&lt;br /&gt;
&lt;br /&gt;
My goal is to have the Ubuntu Ruby packages installed along side the most current releases of 1.8 and 1.9&lt;br /&gt;
&lt;br /&gt;
First I'll install using apt to create my default ruby install.&lt;br /&gt;
&lt;pre&gt;$&amp;gt; sudo apt-get install ruby irb ri rdoc libruby-extras rubygems ruby1.8-dev
$&amp;gt; sudo gem install rake&lt;/pre&gt;
&lt;br /&gt;
Next I'll install the most current release packages of 1.8 and 1.9 in to /opt/ruby1.8.6 and /opt/ruby1.9.0 respectively.&lt;br /&gt;
&lt;br /&gt;
Before doing that I'll make sure I have all the necessary build dependencies for both packages&lt;br /&gt;
&lt;pre&gt;$&amp;gt; sudo apt-get build-dep ruby1.8 ruby1.9&lt;/pre&gt;
&lt;br /&gt;
Next I downloaded both packages into a working directory and decompress them&lt;br /&gt;
&lt;pre&gt;$&amp;gt;mkdir temp; cd temp
$&amp;gt;wget ftp://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.6-p111.tar.gz
$&amp;gt;tar -xvzf ruby-1.8.6-p111.tar.gz
$&amp;gt;wget ftp://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.0-0.tar.gz
$&amp;gt;tar -xvzf ruby-1.9.0-0.tar.gz&lt;/pre&gt;
&lt;br /&gt;
Next I build each of the packages.&lt;br /&gt;
&lt;pre&gt;$&amp;gt; cd ruby-1.8*
$&amp;gt; ./configure --prefix=/opt/ruby1.8 --program-suffix=1.8.6
$&amp;gt; sudo make &amp;amp;&amp;amp; make install
$&amp;gt; cd ../ruby-1.9*
$&amp;gt; ./configure --prefix=/opt/ruby1.9 --program-suffix=1.9.0
$&amp;gt; sudo make &amp;amp;&amp;amp; make install
&lt;/pre&gt;
Ruby 1.8 doesn't have built in support for gems like Ruby 1.9 so we'll have to install it.&lt;br /&gt;
&lt;pre&gt;$&amp;gt; wget http://rubyforge.org/frs/download.php/29548/rubygems-1.0.1.tgz
$&amp;gt; tar -xvzf rubygems-1.0.1.tgz
$&amp;gt; cd rubygems*
$&amp;gt; sudo /opt/ruby1.8.6/bin/ruby1.8.6 setup.rb&lt;/pre&gt;
Notice that I specified the entire path to the ruby executable while installing RubyGems for 1.8.6&lt;br /&gt;
&lt;br /&gt;
The next thing I do is create some symbolic links to make life a little bit easier.&lt;br /&gt;
&lt;pre&gt;$&amp;gt; sudo ln -s /opt/ruby1.8.6/bin/* /usr/local/bin
$&amp;gt; sudo ln -s /opt/ruby1.9.0/bin/* /usr/local/bin&lt;/pre&gt;
Now test things a bit to make sure everything makes sense&lt;br /&gt;
&lt;pre&gt;$&amp;gt; which ruby
# /usr/bin/ruby
$&amp;gt; gem env
# ....
# GEM PATH: /var/lib/gems/1.8
# ....

$&amp;gt; which ruby1.8.6
# /usr/local/bin/ruby1.8.6
$&amp;gt; gem1.8.6 env
# ....
# GEM PATH: /opt/ruby1.8.6/lib/ruby/gems/1.8
# ....

$&amp;gt; which ruby1.9.0
# /usr/local/bin/ruby1.9.0
$&amp;gt; gem1.9.0 env
# ....
# GEM PATH: /opt/ruby1.9.0/lib/ruby/gems/1.8
# ....&lt;/pre&gt;
&lt;br /&gt;
A couple of things to watch out for:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Make sure you don't have any RubyGems environment variables set.  They're not needed for any of this and most likley will mess something up.&lt;/li&gt;
&lt;li&gt;Don't install any gems until after you create your symbolic links or the executable commands may clobber each other.&lt;/li&gt;
&lt;li&gt;You have to specify the full path to an executable gem because they don't play nicely with program suffixes.  So for example '/opt/ruby1.8.6/bin/rake' will do what you expect but just typing 'rake' may not.&lt;/li&gt;
&lt;/ul&gt;
One last little tidbit.  I'm not sure if the Ubuntu RubyGems packages deal with fixing up the $PATH yet? Regardless the fix is easy; add this little bit of code to the bottom of your ~/.bashrc file&lt;br /&gt;
&lt;pre&gt;if [ -d /var/lib/gems/1.8/bin ]; then
PATH=/var/lib/gems/1.8/bin:"${PATH}"
fi
export PATH&lt;/pre&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=d5BpMDONHe0:7gPvATNOp_Y:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/d5BpMDONHe0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/925192477314217119/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=925192477314217119" title="7 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/925192477314217119?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/925192477314217119?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/d5BpMDONHe0/multiple-ruby-version-on-ubuntu.html" title="Multiple Versions of Ruby On Ubuntu" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>7</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2007/12/multiple-ruby-version-on-ubuntu.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUINR3o-fSp7ImA9WB9bGEw.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-5353750479301943772</id><published>2007-12-27T17:04:00.001-08:00</published><updated>2007-12-27T20:53:16.455-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-12-27T20:53:16.455-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ffmpeg" /><category scheme="http://www.blogger.com/atom/ns#" term="debian" /><category scheme="http://www.blogger.com/atom/ns#" term="apt" /><title>Customizing Debian Packages</title><content type="html">Debian's packaging system makes it really easy to modify packages if you want to.  In this little howto I modify ffmpeg to add MP3 support but the process can easily be adapted to any package.&lt;br /&gt;&lt;br /&gt;First create a work directory and drop down into it.   This is just to make cleanup easy.&lt;br /&gt;&lt;pre&gt;$&gt; mkdir temp; cd temp&lt;/pre&gt;&lt;br /&gt;Then make sure the ffmpeg build dependencies are installed&lt;br /&gt;&lt;pre&gt;$&gt; sudo apt-get build-dep ffmpeg&lt;/pre&gt;&lt;br /&gt;Then download the source package&lt;br /&gt;&lt;pre&gt;$&gt; apt-get source ffmpeg&lt;/pre&gt;&lt;br /&gt;Then install the extra (codec) libraries we're adding support for&lt;br /&gt;&lt;pre&gt;$&gt; sudo apt-get install liblame-dev libfaad2-dev libfaac-dev libxvidcore4-dev&lt;/pre&gt;&lt;br /&gt;Then drop down into the ffmpeg source directory&lt;br /&gt;&lt;pre&gt;$&gt; cd ffmpeg*&lt;/pre&gt;&lt;br /&gt;Now you will have to edit the first line of the the debian/changelog and modify the package version.  If you don't system updates will want to 'replace' your modified package.  The first line should look something like this:&lt;br /&gt;&lt;pre&gt;ffmpeg (3:0.cvs20070307-5ubuntu4) gutsy; urgency=low&lt;/pre&gt;.  You will want append something at the end of the part in parentheses.  In my case I use:&lt;br /&gt;&lt;pre&gt;ffmpeg (3:0.cvs20070307-5ubuntu4-mg1) gutsy; urgency=low&lt;/pre&gt;&lt;br /&gt;It's my initials followed by a revision number.&lt;br /&gt;&lt;br /&gt;Once you've modified the change log you can build the package but before we do we set an environment variable used by the build scripts that indicates we want the 'risky' libraries included.&lt;br /&gt;&lt;pre&gt;$&gt; DEB_BUILD_OPTIONS=risky &amp;amp;&amp;amp; fakeroot debian/rules binary&lt;/pre&gt;&lt;br /&gt;Now we just need to install the packages.  The packages were placed up one directory during the build process so we just move up and install.&lt;br /&gt;&lt;pre&gt;$&gt; cd .. &amp;amp;&amp;amp; sudo dpkg -i *.deb&lt;/pre&gt;&lt;br /&gt;Now we just clean up after ourselves&lt;br /&gt;&lt;pre&gt;$&gt; cd .. &amp;amp;&amp;amp; rm -rf temp&lt;/pre&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=HkZ8jtc9CE4:8Ma6UIWSD5A:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/HkZ8jtc9CE4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/5353750479301943772/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=5353750479301943772" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/5353750479301943772?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/5353750479301943772?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/HkZ8jtc9CE4/customizing-debian-packages.html" title="Customizing Debian Packages" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2007/12/customizing-debian-packages.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0YDR38_eSp7ImA9WB9bGE8.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-8348579126879555662</id><published>2007-12-24T20:03:00.000-08:00</published><updated>2007-12-27T21:52:56.141-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-12-27T21:52:56.141-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="p2p" /><category scheme="http://www.blogger.com/atom/ns#" term="music" /><category scheme="http://www.blogger.com/atom/ns#" term="free culture" /><title>The Generational Divide in Copyright Morality</title><content type="html">There's an interesting (but not surprising) &lt;a href="http://pogue.blogs.nytimes.com/2007/12/20/the-generational-divide-in-copyright-morality/"&gt;article&lt;/a&gt; in the New York Times about differences in perspective between the coming generation and the current in regards to intellectual property.&lt;br /&gt;&lt;br /&gt;This of course created plenty of &lt;a href="http://yro.slashdot.org/yro/07/12/24/2138202.shtml"&gt;conversation on Slashdot&lt;/a&gt; (most of it half baked) but still enough motivation to get me to post this....&lt;br /&gt;&lt;br /&gt;It's simply impossible to prevent sharing of media.  I mean literally impossible!  There's nothing you can do to stop it (unless you have a dooms day device in your garage?).&lt;br /&gt;&lt;br /&gt;All the effort spent trying to stop it is literally wasted!&lt;br /&gt;&lt;br /&gt;It seemed to me from both the NYT article and Slashdot comments people felt these kids should feel guilty, like they're doing something wrong?  The reality is these kids realize our outdated views on Copyright have NO (you read that right 'NO' ) value in today's world.&lt;br /&gt;&lt;br /&gt;They understand that we're all better off when information is shared freely and they also understand there's no practical way to differentiate media from other types of information.  They are correctly choosing to accept shared media as a consequence of free information exchange.&lt;br /&gt;&lt;br /&gt;They also I'm sure realize the impact this will have on their futures.  I'm sure they understand that the media industry is a service industry and that they will have to live off the work they do (not the work they've already done) in the future.&lt;br /&gt;&lt;br /&gt;So even though everyone from the article and Slashdot seemed to imply these kids just don't get it.  I think it's just the opposite.  They are the ones that really do get it!&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=F7DEWlUCRzM:E3sxcR8lVnI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/F7DEWlUCRzM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/8348579126879555662/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=8348579126879555662" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/8348579126879555662?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/8348579126879555662?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/F7DEWlUCRzM/generational-divide-in-copyright.html" title="The Generational Divide in Copyright Morality" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2007/12/generational-divide-in-copyright.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUEDRng7eSp7ImA9WB9aEkw.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-2242548775692305197</id><published>2007-12-24T14:32:00.001-08:00</published><updated>2008-01-01T12:01:17.601-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-01-01T12:01:17.601-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Blogger" /><category scheme="http://www.blogger.com/atom/ns#" term="Syntax" /><category scheme="http://www.blogger.com/atom/ns#" term="Ruby" /><title>Ruby Syntax Highlighting On Blogger</title><content type="html">&lt;div class="ruby"&gt;It turns out that creating syntax highlighted source in blogger is not difficult even if it's not convenient&lt;br /&gt;&lt;br /&gt;The first step is to find an application that can syntax highlight and convert your code to HTML.  I choose to hack together a quick little script on top of the &lt;a href="http://syntax.rubyforge.org/"&gt;Syntax&lt;/a&gt; library (the code's below)&lt;br /&gt;&lt;pre class="ruby"&gt;&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;rubygems&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;&lt;br /&gt;&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;syntax/convertors/html&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;&lt;br /&gt;&lt;span class="ident"&gt;convertor&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Syntax&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Convertors&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;HTML&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;for_syntax&lt;/span&gt; &lt;span class="punct"&gt;"&lt;/span&gt;&lt;span class="string"&gt;ruby&lt;/span&gt;&lt;span class="punct"&gt;"&lt;/span&gt;&lt;br /&gt;&lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="ident"&gt;convertor&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;convert&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="constant"&gt;File&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;read&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="constant"&gt;ARGV&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;]))&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;Now when ever you want to make a post just choose 'Edit Html' in the composer and insert the output from your formatter application.&lt;br /&gt;&lt;br /&gt;Depending on on your formatter you may need to add it's CSS to your Blogger template.&lt;br /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=LTsDuqB2hi0:eIKOJg14-3Y:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/LTsDuqB2hi0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/2242548775692305197/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=2242548775692305197" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/2242548775692305197?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/2242548775692305197?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/LTsDuqB2hi0/blog-post.html" title="Ruby Syntax Highlighting On Blogger" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2007/12/blog-post.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C08HQng4cSp7ImA9WxZSGU8.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-4045631561919709305</id><published>2007-12-23T19:32:00.000-08:00</published><updated>2008-02-01T19:10:33.639-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-02-01T19:10:33.639-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><title>A Caching Current User Method Call</title><content type="html">Quite a while back when I first seen &lt;a href="http://railscasts.com/episodes/1"&gt;RailsCast Episode #1&lt;/a&gt;, I implemented a &lt;span style="font-weight: bold; font-style: italic;"&gt;current_user&lt;/span&gt; method exactly as it's presented in the video.  The problem with this method is that it assumes that the &lt;span style="font-weight: bold;"&gt;user_id&lt;/span&gt; session variable is always set, obviously this is not always the case.&lt;br /&gt;&lt;br /&gt;This snippet addresses the problem&lt;br /&gt;&lt;pre class="ruby"&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;ApplicationController&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt; &lt;span class="constant"&gt;ActionController&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Base&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;current_user&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;session&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:user_id&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt; &lt;span class="punct"&gt;?&lt;/span&gt; &lt;span class="attribute"&gt;@current_user&lt;/span&gt; &lt;span class="punct"&gt;||=&lt;/span&gt; &lt;span class="constant"&gt;User&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;find&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;session&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:user_id&lt;/span&gt;&lt;span class="punct"&gt;])&lt;/span&gt; &lt;span class="punct"&gt;:&lt;/span&gt; &lt;span class="constant"&gt;nil&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=BtVkF4IVmZ8:2_J90wNUCxo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/BtVkF4IVmZ8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/4045631561919709305/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=4045631561919709305" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/4045631561919709305?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/4045631561919709305?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/BtVkF4IVmZ8/caching-current-user-method-call.html" title="A Caching Current User Method Call" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2007/12/caching-current-user-method-call.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C08MRX09fSp7ImA9WxZSGU8.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-881302549953721468</id><published>2007-12-23T19:02:00.000-08:00</published><updated>2008-02-01T19:11:24.365-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-02-01T19:11:24.365-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Blogger" /><title>Sharing Code...</title><content type="html">&lt;span style="font-style: italic; font-weight: bold;"&gt;Edit: I've since changed my mind about this.  See &lt;a href="http://blog.michaelgreenly.com/2007/12/blog-post.html"&gt;this&lt;/a&gt; post.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;I was spending time refactoring some of the crufty code in KanbanOnRails and got stuck thinking about the best way for me to share code?  Clearly Blogger is not it!&lt;br /&gt;&lt;br /&gt;I think for the time being I'll just use a snippet service like &lt;a href="http://snippets.dzone.com/"&gt;http://snippets.dzone.com/&lt;/a&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=qR0gXOtzSME:yBvfqxUu6HM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/qR0gXOtzSME" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/881302549953721468/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=881302549953721468" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/881302549953721468?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/881302549953721468?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/qR0gXOtzSME/sharing-code.html" title="Sharing Code..." /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2007/12/sharing-code.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEABQX48fSp7ImA9WB9UEkg.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-771707143506943871</id><published>2007-11-24T10:31:00.000-08:00</published><updated>2007-12-09T18:12:30.075-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-12-09T18:12:30.075-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="DVCS" /><category scheme="http://www.blogger.com/atom/ns#" term="Bazaar" /><title>Bazaar Workflow Examples</title><content type="html">I was poking around the Internet and found an excellent article describing various &lt;a href="http://bazaar-vcs.org/Workflows"&gt;workflows using Bazaar&lt;/a&gt; (or any distributed VCS really) and thought it was worth sharing.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=jGE-RGefxlw:-E17qSLfuS8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/jGE-RGefxlw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/771707143506943871/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=771707143506943871" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/771707143506943871?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/771707143506943871?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/jGE-RGefxlw/bazaar-workflow-examples.html" title="Bazaar Workflow Examples" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2007/11/bazaar-workflow-examples.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkYNQHs5eip7ImA9WB9WFU4.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-8352697068428810206</id><published>2007-11-04T18:11:00.000-08:00</published><updated>2007-11-19T21:56:31.522-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-11-19T21:56:31.522-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Git" /><category scheme="http://www.blogger.com/atom/ns#" term="Bazaar" /><category scheme="http://www.blogger.com/atom/ns#" term="Launchpad" /><category scheme="http://www.blogger.com/atom/ns#" term="KanbanOnRails" /><category scheme="http://www.blogger.com/atom/ns#" term="Google Docs" /><title>KanbanOnRails' Meta-Project</title><content type="html">My current work related project is &lt;a href="http://docs.google.com/View?docID=ddkbcd62_3fqnd6b&amp;amp;revision=_latest"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;KanbanOnRails&lt;/span&gt;&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;It's home page contains pretty much every thing you could want to know about the project but doesn't explain the meta-project at all.  So I thought I'd do that here...&lt;br /&gt;&lt;br /&gt;It turns out that I've stumbled into using a rather odd assortment of tools and services to manage this project, but it's working well, so I thought I'd share the recipe here.&lt;br /&gt;&lt;br /&gt;I'm using &lt;a href="http://bazaar-vcs.org/"&gt;Bazaar&lt;/a&gt; for revision control, &lt;a href="https://launchpad.net/"&gt;Launchpad&lt;/a&gt; for project &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;managment&lt;/span&gt; and &lt;a href="http://docs.google.com/"&gt;Google Docs&lt;/a&gt; for most of the actual content.&lt;br /&gt;&lt;br /&gt;There's really only two &lt;a href="http://en.wikipedia.org/wiki/Source_Code_Management"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;SCM&lt;/span&gt;&lt;/a&gt; tools out there that I would consider using right now; &lt;a href="http://bazaar-vcs.org/"&gt;Bazaar&lt;/a&gt; and &lt;a href="http://git.or.cz/"&gt;Git&lt;/a&gt;.  I'm firmly sold on &lt;a href="http://en.wikipedia.org/wiki/Revision_control#Distributed_revision_control"&gt;distributed &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;SCM&lt;/span&gt;&lt;/a&gt; and from what I've seen so far these two have the brightest future.&lt;br /&gt;&lt;br /&gt;I've decided to use Bazaar for this project and to try Git out on the next.&lt;br /&gt;&lt;br /&gt;Distributed &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;SCMs&lt;/span&gt; work best if you have some public web space available to share branches, with, mine's &lt;a href="http://michaelgreenly.com/branches/"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I've generally preferred using &lt;a href="http://trac.edgewall.org/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;Trac&lt;/span&gt;&lt;/a&gt; for project management in the past, it's a fabulous tool, but this time I wanted a third party host that could provide a permanent home for the project.  That really only left me with one choice, &lt;a href="http://launchpad.net/"&gt;Launchpad&lt;/a&gt;, which &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;natively&lt;/span&gt; uses Bazaar.  Currently none of the other project hosting services; &lt;a href="http://sourceforge.net/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;SourceForge&lt;/span&gt;,&lt;/a&gt; &lt;a href="http://rubyforge.org/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;RubyForge&lt;/span&gt;&lt;/a&gt;, &lt;a href="http://code.google.com/"&gt;Google Code&lt;/a&gt;, etc... support any form of distributed &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;SCM&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;I would of &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;prefered&lt;/span&gt; a good reliable (free) public wiki for content hosting but wasn't immediately aware of one so I decided to use &lt;a href="http://docs.google.com/"&gt;Google Docs&lt;/a&gt;.  This is the most likely part of the recipe to change if &lt;a href="http://www.jotspot.com/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;Google's&lt;/span&gt; Wiki&lt;/a&gt; is ever released or I find a good alternative.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=21weiFXgV_k:dNxuxEwhJPI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/21weiFXgV_k" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/8352697068428810206/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=8352697068428810206" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/8352697068428810206?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/8352697068428810206?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/21weiFXgV_k/kanban-on-rails.html" title="KanbanOnRails' Meta-Project" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2007/11/kanban-on-rails.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0UEQXwyfyp7ImA9WB9bGE8.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-2035170216937469134</id><published>2007-11-03T08:50:00.000-07:00</published><updated>2007-12-27T21:53:20.297-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-12-27T21:53:20.297-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="p2p" /><category scheme="http://www.blogger.com/atom/ns#" term="music" /><category scheme="http://www.blogger.com/atom/ns#" term="free culture" /><title>The end is really, really near</title><content type="html">A lot of people have been predicting the demise of the major record labels for a long time and of course we all new it was inevitable but I've never thought the time had arrived, until now!&lt;br /&gt;&lt;br /&gt;Big name backed independent distribution efforts like the one at  &lt;a href="http://niggytardust.com/"&gt;http://niggytardust.com&lt;/a&gt; will be huge financial successes and convince all the fence sitting artists that this is the right way to go.&lt;br /&gt;&lt;br /&gt;This of course will starve the big labels of talent, not that they could &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_0"&gt;recognize&lt;/span&gt; it even when they did find it, and slowly drive them out of business.&lt;br /&gt;&lt;br /&gt;It's about time!&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=DSV-eYzVRcw:JiXNIxFe2vk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/DSV-eYzVRcw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/2035170216937469134/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=2035170216937469134" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/2035170216937469134?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/2035170216937469134?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/DSV-eYzVRcw/end-is-really-really-near.html" title="The end is really, really near" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2007/11/end-is-really-really-near.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUUHSXs7eSp7ImA9WB9XEUQ.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-1581303126873492271</id><published>2007-11-01T20:21:00.001-07:00</published><updated>2007-11-04T09:27:18.501-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-11-04T09:27:18.501-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Open Source" /><category scheme="http://www.blogger.com/atom/ns#" term="Free Software" /><title>Why Participate?</title><content type="html">Today I was asked a question that went something like this....&lt;br /&gt;&lt;br /&gt;&lt;blockquote style="font-style: italic;"&gt; “Why should we participate in a Free Software project if it's possible for our competitors to benefit from our efforts?”&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;I wasn't really comfortable with the answer I provided at the time so I'm going to take a second stab at it....&lt;br /&gt;&lt;br /&gt;&lt;blockquote style="font-style: italic;"&gt;"You'll get better results at less cost choosing Free Software than you will from proprietary software and maximizing the benefits of Free Software can only be achieved through participation in the community."&lt;br /&gt;&lt;/blockquote&gt;Of course you can choose not to do this and stick with proprietary solutions or maybe even sit on the fence and be a passive Free Software consumer but that doesn't stop your competitors from doing the smart thing and maximizing the potential of Free Software.&lt;br /&gt;&lt;br /&gt;The right choice is to use the best tools at your disposal in the most effective manner you know how and hope that your competitors are not smart enough to do the same.&lt;br /&gt;&lt;br /&gt;Of course in most cases, today, it's unlikely that your competition will have come to understand the benefits of Free Software yet,  so you'll have a considerable head start in learning how to effectively participate in the Free Software community.&lt;br /&gt;&lt;br /&gt;In fact I'll even go out on a limb and say that the concept of Free Software is so foreign to most businesses and the benefits of using it so great that it could be a decisive advantage to any business able to &lt;a href="http://en.wikipedia.org/wiki/Grok"&gt;grok&lt;/a&gt; it.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=YMyhSYFpVMY:PM5McvahabY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/YMyhSYFpVMY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/1581303126873492271/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=1581303126873492271" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/1581303126873492271?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/1581303126873492271?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/YMyhSYFpVMY/why-you-should-participate.html" title="Why Participate?" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2007/11/why-you-should-participate.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A08CQHs5eCp7ImA9WB9QGUg.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-2487586449617922409</id><published>2007-11-01T16:19:00.000-07:00</published><updated>2007-11-01T16:31:01.520-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-11-01T16:31:01.520-07:00</app:edited><title>Something New</title><content type="html">I've just recently started a new project, &lt;a href="http://launchpad.net/kanbanonrails"&gt;Kanban On Rails&lt;/a&gt;.  This application is an electronic implementation of the &lt;a href="http://en.wikipedia.org/wiki/Kanban"&gt;kanban&lt;/a&gt; process.  It's written in &lt;a href="http://www.ruby-lang.org/"&gt;Ruby&lt;/a&gt; built on &lt;a href="http://www.rubyonrails.org/"&gt;Rails&lt;/a&gt; and will be released under the &lt;a href="http://www.gnu.org/copyleft/gpl.html"&gt;GPLv3&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Like all of my project the best way to find it will be through my &lt;a href="https://launchpad.net/%7Emgreenly"&gt;Launchpad&lt;/a&gt; page.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=vTi59yvH2MM:6S9JIfAC8Yo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/vTi59yvH2MM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/2487586449617922409/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=2487586449617922409" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/2487586449617922409?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/2487586449617922409?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/vTi59yvH2MM/something-new.html" title="Something New" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2007/11/something-new.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0YCQ347eyp7ImA9WB9QGUg.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-8255827148882271573</id><published>2007-10-27T08:42:00.000-07:00</published><updated>2007-11-01T16:19:22.003-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-11-01T16:19:22.003-07:00</app:edited><title>Getting Organized...</title><content type="html">I spent a little time trying to get my online existence organized this morning.&lt;br /&gt;&lt;br /&gt;I've had the domain &lt;a href="http://michaelgreenly.com/"&gt;michaelgreenly.com&lt;/a&gt; for quite a while but really have not put it to good use before now.  Today I've decided to make a change and that I was going to use this domain as the root of my Internet presence.&lt;br /&gt;&lt;br /&gt;I'm currently using  &lt;a href="http://blogger.com/"&gt;Blogger&lt;/a&gt; to host this site but I'm  not all that impressed.  We'll see if it grows on me over time.&lt;br /&gt;&lt;br /&gt;To the right you can find links to my other stuff.  The most notable link will most likely be the one to my Launchpad page.  That's the place you'll be able to find all of my source code and links to the project I'm involved in.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=2RCSmYqxV6o:Eh7VGjEpLZQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/2RCSmYqxV6o" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/8255827148882271573/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=8255827148882271573" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/8255827148882271573?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/8255827148882271573?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/2RCSmYqxV6o/getting-organized.html" title="Getting Organized..." /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2007/10/getting-organized.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEIDRX49eCp7ImA9WhJSFEg.&quot;"><id>tag:blogger.com,1999:blog-1539046083268926117.post-8371819984171095988</id><published>2007-10-26T18:21:00.000-07:00</published><updated>2012-07-04T18:42:54.060-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-07-04T18:42:54.060-07:00</app:edited><title>Hello World</title><content type="html">&lt;span style="font-family: arial; font-size: 180%;"&gt;&lt;span style="font-size: 85%;"&gt;Being a  programmer I feel obligated to start out with...&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div style="text-align: center;"&gt;
&lt;span style="font-family: arial; font-size: 180%; font-weight: bold;"&gt;Hello world!&lt;/span&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/MichaelGreenly?a=ttrwkk3nzkY:Xd0ovN3WEKc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/MichaelGreenly?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MichaelGreenly/~4/ttrwkk3nzkY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.michaelgreenly.com/feeds/8371819984171095988/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1539046083268926117&amp;postID=8371819984171095988" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/8371819984171095988?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1539046083268926117/posts/default/8371819984171095988?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MichaelGreenly/~3/ttrwkk3nzkY/being-programmer-i-feel-obligated-to.html" title="Hello World" /><author><name>Mike Greenly</name><uri>https://plus.google.com/118145172612811800326</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-x-ZfgMUJC14/AAAAAAAAAAI/AAAAAAAABgw/xJu8_Na9ddg/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.michaelgreenly.com/2007/10/being-programmer-i-feel-obligated-to.html</feedburner:origLink></entry></feed>
