<?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:feedburner="http://rssnamespace.org/feedburner/ext/1.0" xml:lang="en-US">
  <id>tag:tammersaleh.com,2005:/posts</id>
  <link type="text/html" href="http://tammersaleh.com" rel="alternate" />
  
  <title>Tammer Saleh</title>
  
  <updated>2009-04-30T23:29:24Z</updated>
  <link rel="self" href="http://feeds.feedburner.com/TammerSaleh" type="application/atom+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><entry>
    <id>tag:tammersaleh.com,2005:Post/115</id>
    <published>2009-04-28T18:52:09Z</published>
    <updated>2009-04-30T23:29:24Z</updated>
    <link type="text/html" href="http://feedproxy.google.com/~r/TammerSaleh/~3/QhkHRDk5WZ8/changes" rel="alternate" />
    <title>Changes</title>
    <content type="html">&lt;div class="post published" id="post_115"&gt;&lt;div class='body'&gt;
  &lt;p&gt;&lt;a href="http://www.flickr.com/photos/konklone/2642562963/"&gt;&lt;img alt="Thoughtbot Christmas, 2007" class="float-right" src="/system/images/large/thoughtbot-2007.jpg"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;
  &lt;p&gt;I&amp;#8217;ve worked in a few different types of environments in my career (&lt;a href="http://www.seismolab.caltech.edu/earthquakes.html"&gt;academia&lt;/a&gt;, &lt;a href="http://citysearch.com"&gt;start-ups&lt;/a&gt;, &lt;a href="http://www.jetprogramme.org/"&gt;Japan&lt;/a&gt;, &lt;a href="http://www.ladhs.org/wps/portal/"&gt;doing good&lt;/a&gt;, &lt;a href="http://www.ncsa.uiuc.edu/"&gt;working for the man&lt;/a&gt;, etc), but I can honestly say that I&amp;#8217;ve never enjoyed my work, or my coworkers, as much as I have while I&amp;#8217;ve been working with the team at &lt;a href="http://thoughtbot.com"&gt;Thoughtbot&lt;/a&gt;.&lt;/p&gt;
  &lt;p&gt;Thoughtbot understands the Ruby on Rails culture in a way that I&amp;#8217;ve always respected.  As a company, they focus on producing good work for both the clients and for the community.  As a team, they foster an incredible amount of camaraderie and team spirit, without needing to stifle differences of opinion.&lt;/p&gt;
  &lt;h2&gt;Setting out&lt;/h2&gt;
  &lt;p&gt;All of this has made my recent decision to leave the company incredibly difficult.  While Thoughtbot has been the best environment I could have hoped for, the need to set out on my own and build something for myself was just too strong.&lt;/p&gt;
  &lt;p&gt;I will be doing agile Ruby on Rails consulting for a few clients, and will soon focus on developing my own suite of products.  While I&amp;#8217;m currently fully committed, I&amp;#8217;d be happy to &lt;a href="mailto:tsaleh@gmail.com"&gt;discuss new opportunities&lt;/a&gt; and give referrals.  I will also be posting my journey, and my development thoughts here, so &lt;a href="http://feeds2.feedburner.com/TammerSaleh" rel="alternate" type="application/rss+xml"&gt;stay tuned&lt;/a&gt;.&lt;/p&gt;
  &lt;p&gt;&lt;em&gt;If you&amp;#8217;re an incredible developer, and interested in living in the Boston or &lt;span class="caps"&gt;NYC&lt;/span&gt; areas, then I cannot recommend a better company &lt;a href="http://thoughtbot.com/jobs"&gt;to work for&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class='extended'&gt;
  
&lt;/div&gt;
&lt;div class='clear'&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/TammerSaleh?a=QhkHRDk5WZ8:GKlt5XBRS1w:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TammerSaleh?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TammerSaleh?a=QhkHRDk5WZ8:GKlt5XBRS1w:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TammerSaleh?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TammerSaleh/~4/QhkHRDk5WZ8" height="1" width="1"/&gt;</content>
    <author>
      <name>Tammer Saleh</name>
    </author>
  <feedburner:origLink>http://tammersaleh.com/posts/changes</feedburner:origLink></entry>
  <entry>
    <id>tag:tammersaleh.com,2005:Post/114</id>
    <published>2009-04-22T16:32:51Z</published>
    <updated>2009-04-22T20:40:58Z</updated>
    <link type="text/html" href="http://feedproxy.google.com/~r/TammerSaleh/~3/YvH_y5G9glA/vegas-baby" rel="alternate" />
    <title>Vegas, Baby!</title>
    <content type="html">&lt;div class="post published" id="post_114"&gt;&lt;div class='body'&gt;
  &lt;p&gt;I&amp;#8217;ll be at &lt;a href="http://en.oreilly.com/rails2009/"&gt;RailsConf&lt;/a&gt; for the week of May 4th, so &lt;a href="http://en.oreilly.com/rails2009/profile/2714"&gt;buy me a beer&lt;/a&gt; if you&amp;#8217;re in town.&lt;/p&gt;
  &lt;p&gt;Here are some of the presentations I&amp;#8217;m looking forward to in particular:&lt;/p&gt;
  &lt;ul&gt;
  	&lt;li&gt;&lt;a href="http://en.oreilly.com/rails2009/public/schedule/detail/8474"&gt;Don&amp;#8217;t Mock Yourself Out&lt;/a&gt; by &lt;a href="http://en.oreilly.com/rails2009/public/schedule/speaker/2864"&gt;David Chelimsky&lt;/a&gt;&lt;/li&gt;
  	&lt;li&gt;&lt;a href="http://en.oreilly.com/rails2009/public/schedule/detail/8772"&gt;Discussion Panel: Women In Rails&lt;/a&gt; which will include two of my friends from hashrocket, &lt;a href="http://en.oreilly.com/rails2009/public/schedule/speaker/5610"&gt;Desi McAdam&lt;/a&gt; and &lt;a href="http://en.oreilly.com/rails2009/public/schedule/speaker/24802"&gt;Jacqui Maher&lt;/a&gt;&lt;/li&gt;
  	&lt;li&gt;&lt;a href="http://en.oreilly.com/rails2009/public/schedule/detail/8565"&gt;iPhone On Rails&lt;/a&gt; by &lt;a href="http://en.oreilly.com/rails2009/public/schedule/speaker/24823"&gt;Mike Clark&lt;/a&gt; (&amp;#8216;cause who&amp;#8217;s not on the iPhone bandwagon these days?)&lt;/li&gt;
  	&lt;li&gt;&lt;a href="http://en.oreilly.com/rails2009/public/schedule/detail/7721"&gt;Blood, Sweat and Rails&lt;/a&gt; by &lt;a href="http://en.oreilly.com/rails2009/public/schedule/speaker/2747"&gt;Obie Fernandez&lt;/a&gt; &amp;#8211; possibly the best business mind in our community.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p&gt;And a quick shout out to my friend &lt;a href="http://mill-industries.com/"&gt;Eric Mill&lt;/a&gt;, from &lt;a href="http://sunlightfoundation.com/"&gt;The Sunlight Foundation&lt;/a&gt;, who&amp;#8217;s hosting the &lt;a href="http://en.oreilly.com/rails2009/public/schedule/detail/9020"&gt;Open Government Hackathon&lt;/a&gt;.  (And I think they&amp;#8217;re still hiring, by the way.)&lt;/p&gt;
&lt;/div&gt;
&lt;div class='extended'&gt;
  
&lt;/div&gt;
&lt;div class='clear'&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/TammerSaleh?a=YvH_y5G9glA:185bF8M8zZk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TammerSaleh?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TammerSaleh?a=YvH_y5G9glA:185bF8M8zZk:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TammerSaleh?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TammerSaleh/~4/YvH_y5G9glA" height="1" width="1"/&gt;</content>
    <author>
      <name>Tammer Saleh</name>
    </author>
  <feedburner:origLink>http://tammersaleh.com/posts/vegas-baby</feedburner:origLink></entry>
  <entry>
    <id>tag:tammersaleh.com,2005:Post/112</id>
    <published>2009-04-17T21:11:29Z</published>
    <updated>2009-04-17T21:14:44Z</updated>
    <link type="text/html" href="http://feedproxy.google.com/~r/TammerSaleh/~3/JNjaHKjpFcM/introspection" rel="alternate" />
    <title>Introspection</title>
    <content type="html">&lt;div class="post published" id="post_112"&gt;&lt;div class='body'&gt;
  &lt;p&gt;We give &lt;a href="http://thoughtbot.com/services/training"&gt;training classes&lt;/a&gt; at &lt;a href="http://thoughtbot.com"&gt;Thoughtbot&lt;/a&gt;, and one of the common issues I&amp;#8217;ve seen is that there are many more examples of good ruby library code than there are of decent Ruby on Rails applications.  A Rails application follows conventions and best practices that aren&amp;#8217;t relevant to writing library code.&lt;/p&gt;
  &lt;p&gt;To that end, I&amp;#8217;ve released the &lt;a href="http://github.com/tsaleh/tammersaleh"&gt;source to this blog&lt;/a&gt; on github.&lt;/p&gt;
  &lt;h3&gt;Here be Dragons&lt;/h3&gt;
  &lt;p&gt;I spent a little bit of time cleaning the code up, but here is the big disclaimer:&lt;/p&gt;
  &lt;p&gt;&lt;em&gt;This is my playground.  I try to keep the code somewhat clean, but I also experiment quite a bit.  &lt;strong&gt;Not everything in here exemplifies best practices.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class='extended'&gt;
  
&lt;/div&gt;
&lt;div class='clear'&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/TammerSaleh?a=JNjaHKjpFcM:j1_yG01ukCQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TammerSaleh?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TammerSaleh?a=JNjaHKjpFcM:j1_yG01ukCQ:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TammerSaleh?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TammerSaleh/~4/JNjaHKjpFcM" height="1" width="1"/&gt;</content>
    <author>
      <name>Tammer Saleh</name>
    </author>
  <feedburner:origLink>http://tammersaleh.com/posts/introspection</feedburner:origLink></entry>
  <entry>
    <id>tag:tammersaleh.com,2005:Post/111</id>
    <published>2009-04-15T03:12:31Z</published>
    <updated>2009-04-15T04:20:15Z</updated>
    <link type="text/html" href="http://feedproxy.google.com/~r/TammerSaleh/~3/Lddl1Cx6JhI/domain-explosion" rel="alternate" />
    <title>Domain Explosion</title>
    <content type="html">&lt;div class="post published" id="post_111"&gt;&lt;div class='body'&gt;
  &lt;p&gt;There&amp;#8217;s an AntiPattern that I still see in the wild far too often: the overly normalized domain.  It&amp;#8217;s easy to spot &amp;#8211; you find over 50 files staring you down after opening the &lt;code&gt;app/models&lt;/code&gt; directory in what should have been a basic Rails application.&lt;/p&gt;
  &lt;p&gt;A simple example is the following domain snippet, showing a Product model with all the trappings that surround it.&lt;/p&gt;
  &lt;p&gt;&lt;img src="/system/images/original/Untitled.jpg" alt="" /&gt;&lt;/p&gt;
  &lt;p&gt;Each of &lt;code&gt;Condition&lt;/code&gt;, &lt;code&gt;Color&lt;/code&gt;, &lt;code&gt;ProductState&lt;/code&gt; and &lt;code&gt;ShippingType&lt;/code&gt; are separate models, with separate tables, separate factory definitions, unit tests, RESTful controllers, migrations, etc.&lt;/p&gt;
  &lt;p&gt;&lt;em&gt;And each is responsible for a single &lt;code&gt;name&lt;/code&gt; column.&lt;/em&gt;&lt;/p&gt;
  &lt;p&gt;That&amp;#8217;s a lot of code.  The more code I see in an application, the sorrier I feel for the client.  &lt;strong&gt;Code is a liability&lt;/strong&gt;.  Like a pack mule, the development process becomes bogged down, cumbersome, and eventually comes to a halt due to an overburden of code.&lt;/p&gt;
  &lt;p&gt;A much simpler solution is to reduce each of those models into columns on &lt;code&gt;Product&lt;/code&gt;, using validations and named scopes to give all the benefits of the domain above:&lt;/p&gt;
  &lt;pre&gt;&lt;code class="ruby"&gt;&amp;#x000A;class Product &amp;lt; ActiveRecord::Base&amp;#x000A;  COLORS = %w(Red White Blue)&amp;#x000A;&amp;#x000A;  named_scope :colored, lambda {|c| {:conditions =&amp;gt; {:color =&amp;gt; c}}}&amp;#x000A;  validates_inclusion_of :color, :in =&amp;gt; COLORS&amp;#x000A;end&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;
  &lt;p&gt;Even the &lt;code&gt;Photo&lt;/code&gt; model can be reimplemented this way, if you use the fantastic &lt;a href="http://github.com/thoughtbot/paperclip"&gt;Paperclip&lt;/a&gt; plugin.&lt;/p&gt;
  &lt;h2&gt;Developers, not coders.&lt;/h2&gt;
  &lt;p&gt;It sounds absurd and even self defeating, but our job as developers isn&amp;#8217;t to write code.  Our job is to produce value for the client, and more often than not that means removing code.&lt;/p&gt;
  &lt;p&gt;That requires a whole lot of judgment, which translates to a whole lot of experience.&lt;/p&gt;
  &lt;h2&gt;Behavior, not nouns.&lt;/h2&gt;
  &lt;p&gt;The idea of removing classes in favor of values doesn&amp;#8217;t fly in the face of good Object Oriented practices.  The important distinction is that the classes above have essentially no behavior.  A class without behavior is just a glorified value wrapped in maintenance costs.&lt;/p&gt;
  &lt;p&gt;&lt;em&gt;Behavior, not vocabulary, dictates normalization.&lt;/em&gt;  The moment you add a &lt;code&gt;shipping_rate&lt;/code&gt; method to the &lt;code&gt;Product&lt;/code&gt; model, you know you should migrate to a &lt;code&gt;ShippingType&lt;/code&gt; class.  The moment you have to be able to modify that price at runtime, you move to a model.&lt;/p&gt;
  &lt;h2&gt;Simplest thing possible.&lt;/h2&gt;
  &lt;p&gt;That&amp;#8217;s the beauty of the &lt;a href="http://behaviour-driven.org/"&gt;&lt;span class="caps"&gt;BDD&lt;/span&gt;&lt;/a&gt; way.  &lt;span class="caps"&gt;BDD&lt;/span&gt; teaches you to write your specs first, and produce the &lt;em&gt;simplest thing possible&lt;/em&gt; in order to get them to pass.  It also keeps you focused on producing business value for your client &amp;#8211; something a domain explosion definitely doesn&amp;#8217;t do.&lt;/p&gt;
  &lt;h2&gt;The Plug&lt;/h2&gt;
  &lt;p&gt;&lt;a href="http://thoughtbot.com/about/people#cpytel"&gt;Chad Pytel&lt;/a&gt; and I delve into issues just like this in our upcoming Addison Wesley book, &lt;a href="http://my.safaribooksonline.com/9780321620293"&gt;Rails AntiPatterns&lt;/a&gt;.  &lt;a href="http://feeds.feedburner.com/TammerSaleh"&gt;Stay tuned&lt;/a&gt; for more information on the book, or for more posts like this.&lt;/p&gt;
&lt;/div&gt;
&lt;div class='extended'&gt;
  
&lt;/div&gt;
&lt;div class='clear'&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/TammerSaleh?a=Lddl1Cx6JhI:OjZC_IGkmj0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TammerSaleh?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TammerSaleh?a=Lddl1Cx6JhI:OjZC_IGkmj0:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TammerSaleh?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TammerSaleh/~4/Lddl1Cx6JhI" height="1" width="1"/&gt;</content>
    <author>
      <name>Tammer Saleh</name>
    </author>
  <feedburner:origLink>http://tammersaleh.com/posts/domain-explosion</feedburner:origLink></entry>
  <entry>
    <id>tag:tammersaleh.com,2005:Post/110</id>
    <published>2008-10-17T13:11:24Z</published>
    <updated>2008-10-17T13:16:24Z</updated>
    <link type="text/html" href="http://feedproxy.google.com/~r/TammerSaleh/~3/H2xgymKYEnc/rockin-jax-with-hashrocket" rel="alternate" />
    <title>Rockin' JAX with Hashrocket</title>
    <content type="html">&lt;div class="post published" id="post_110"&gt;&lt;div class='body'&gt;
  &lt;div style="clear:both"&gt;&lt;/div&gt;
  &lt;p&gt;&lt;a href="http://www.hashrocket.com/products"&gt;&lt;/p&gt;
  &lt;p style="float:right;"&gt;&lt;img src="/system/images/original/hr_guest_star_225x225.png" alt="" /&gt;&lt;/p&gt;
  &lt;p&gt;&lt;/a&gt;&lt;/p&gt;
  &lt;p&gt;&lt;a href="http://hashrocket.com"&gt;Hashrocket&lt;/a&gt; recently honored Joe Ferris (&lt;a href="http://www.jferris.com/"&gt;no relation&lt;/a&gt;) and I by an invitation to come down to Jacksonville Beach, Florida to work on one of their 321 Launch projects as guest star programmers.&lt;/p&gt;
  &lt;p&gt;Chris O&amp;#8217;Sullivan actually did an amazingly accurate job of describing the project from a technical point of view by doing an &lt;a href="http://www.thechrisoshow.com/2008/10/2/a-peek-at-the-inner-workings-of-hashrocket"&gt;impressively detailed analysis of our github commits and tweets&lt;/a&gt;.&lt;/p&gt;
  &lt;p&gt;We had a lot of things going for us in this project:  The clients were a breeze to work with; Desi and Lark were both great developers, and a lot of fun to pair with; and the end product, &lt;a href="http://github.com/spot-us/spot-us/tree/master"&gt;Spot.us&lt;/a&gt; was going open-source &amp;#8211; meaning there was no room for &amp;#8220;cowboy antics&amp;#8221; (Desi&amp;#8217;s words).&lt;/p&gt;
  &lt;div style="clear:both"&gt;&lt;/div&gt;
  &lt;p&gt;&lt;a href="http://www.flickr.com/photos/obie/2897533324/"&gt;&lt;/p&gt;
  &lt;p&gt;&lt;img src="/system/images/original/2897533324_0eb1e6cff7.jpg" alt="" /&gt;&lt;/p&gt;
  &lt;p&gt;&lt;/a&gt;&lt;/p&gt;
  &lt;p&gt;The client was very impressed with the progress we had made, and with the overall polish of the site.  You can read more about the reaction &lt;a href="http://blog.spot.us/2008/09/26/first-look-at-spotus-in-action/"&gt;here&lt;/a&gt;, and the demo video is below.&lt;/p&gt;
  &lt;script type='text/javascript' src='http://blip.tv/syndication/write_player?skin=js&amp;#038;posts_id=1304232&amp;#038;cross_post_destination=-1&amp;#038;view=full_js'&gt;&lt;/script&gt;&lt;p&gt;Working at Hashrocket was a lot of fun, and in many ways was the perfect vacation.  You&amp;#8217;re surrounded by talented coders (which fends off the normal vacation boredom), and you get to wake up to beautiful beach views every morning.&lt;/p&gt;
  &lt;p&gt;&lt;a href="http://www.flickr.com/photos/tsaleh/sets/72157607823206763/"&gt;&lt;/p&gt;
  &lt;p&gt;&lt;img src="/system/images/original/2921710942_ec9a246759.jpg" alt="" /&gt;&lt;/p&gt;
  &lt;p&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class='extended'&gt;
  
&lt;/div&gt;
&lt;div class='clear'&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/TammerSaleh?a=H2xgymKYEnc:PYy9snE-Gw4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TammerSaleh?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TammerSaleh?a=H2xgymKYEnc:PYy9snE-Gw4:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TammerSaleh?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TammerSaleh/~4/H2xgymKYEnc" height="1" width="1"/&gt;</content>
    <author>
      <name>Tammer Saleh</name>
    </author>
  <feedburner:origLink>http://tammersaleh.com/posts/rockin-jax-with-hashrocket</feedburner:origLink></entry>
  <entry>
    <id>tag:tammersaleh.com,2005:Post/109</id>
    <published>2008-10-03T20:30:30Z</published>
    <updated>2008-10-03T20:33:08Z</updated>
    <link type="text/html" href="http://feedproxy.google.com/~r/TammerSaleh/~3/OFeVAXTjcs0/mememe" rel="alternate" />
    <title>Mememe</title>
    <content type="html">&lt;div class="post published" id="post_109"&gt;&lt;div class='body'&gt;
  &lt;p&gt;&lt;img src="/system/images/original/Photo_8.jpg" alt="" /&gt;&lt;/p&gt;
  &lt;ul&gt;
  	&lt;li&gt;Take a picture of yourself right now.&lt;/li&gt;
  	&lt;li&gt;Don’t change your clothes, don’t fix your hair…just take a picture. (should be super-easy with Photobooth)&lt;/li&gt;
  	&lt;li&gt;Post that picture with NO editing.&lt;/li&gt;
  	&lt;li&gt;Post these instructions with your picture.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p&gt;(It&amp;#8217;s &amp;#8220;formal friday&amp;#8221;)&lt;/p&gt;
&lt;/div&gt;
&lt;div class='extended'&gt;
  
&lt;/div&gt;
&lt;div class='clear'&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/TammerSaleh?a=OFeVAXTjcs0:3K3UmQSG1WI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TammerSaleh?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TammerSaleh?a=OFeVAXTjcs0:3K3UmQSG1WI:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TammerSaleh?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TammerSaleh/~4/OFeVAXTjcs0" height="1" width="1"/&gt;</content>
    <author>
      <name>Tammer Saleh</name>
    </author>
  <feedburner:origLink>http://tammersaleh.com/posts/mememe</feedburner:origLink></entry>
  <entry>
    <id>tag:tammersaleh.com,2005:Post/108</id>
    <published>2008-07-29T18:11:42Z</published>
    <updated>2008-07-29T18:20:09Z</updated>
    <link type="text/html" href="http://feedproxy.google.com/~r/TammerSaleh/~3/RBYpAUvBix0/testing-named_scope" rel="alternate" />
    <title>Testing named_scope</title>
    <content type="html">&lt;div class="post published" id="post_108"&gt;&lt;div class='body'&gt;
  &lt;p&gt;We&amp;#8217;re huge fans of &lt;code&gt;NamedScope&lt;/code&gt; here at Thoughtbot.  It does wonders for finder reuse and clarity.  Unfortunately, it also creates a large number of finders that all must be tested, where the old method may have only created one.&lt;/p&gt;
  &lt;p&gt;To help out with the testing of simple &lt;code&gt;named_scope&lt;/code&gt; definitions, we added a helper to &lt;a href="http://thoughtbot.com/projects/shoulda"&gt;Shoulda&lt;/a&gt;, &lt;code&gt;should_have_named_scope&lt;/code&gt;:&lt;/p&gt;
  &lt;pre&gt;&lt;code class="ruby"&gt;&amp;#x000A;class User &amp;lt; ActiveRecord::Base&amp;#x000A;  named_scope :old,      :conditions =&amp;gt; "age &amp;gt; 50"&amp;#x000A;  named_scope :eighteen, :conditions =&amp;gt; { :age =&amp;gt; 18 }&amp;#x000A;  named_scope :recent,   lambda {|count| { :limit =&amp;gt; count } }&amp;#x000A;end&amp;#x000A;&amp;#x000A;class UserTest &amp;lt; Test::Unit::TestCase&amp;#x000A;  should_have_named_scope :old,       :conditions =&amp;gt; "age &amp;gt; 50"&amp;#x000A;  should_have_named_scope :eighteen,  :conditions =&amp;gt; { :age =&amp;gt; 18 }&amp;#x000A;  should_have_named_scope 'recent(5)', :limit =&amp;gt; 5&amp;#x000A;  should_have_named_scope 'recent(1)', :limit =&amp;gt; 1&amp;#x000A;end&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;
  &lt;p&gt;Now for complex methods, where the options returned by the &lt;code&gt;has_finder&lt;/code&gt; are hairier than a simple limit or a single column condition, we would also write black box tests.  But this helper is great for those simpler calls.&lt;/p&gt;
&lt;/div&gt;
&lt;div class='extended'&gt;
  
&lt;/div&gt;
&lt;div class='clear'&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/TammerSaleh?a=RBYpAUvBix0:SWzeJ3lvnAE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TammerSaleh?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TammerSaleh?a=RBYpAUvBix0:SWzeJ3lvnAE:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TammerSaleh?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TammerSaleh/~4/RBYpAUvBix0" height="1" width="1"/&gt;</content>
    <author>
      <name>Tammer Saleh</name>
    </author>
  <feedburner:origLink>http://tammersaleh.com/posts/testing-named_scope</feedburner:origLink></entry>
  <entry>
    <id>tag:tammersaleh.com,2005:Post/107</id>
    <published>2008-06-22T14:23:11Z</published>
    <updated>2008-06-22T14:25:29Z</updated>
    <link type="text/html" href="http://feedproxy.google.com/~r/TammerSaleh/~3/Qwf8MaolCx8/quick-vim-svn-blame-snippet" rel="alternate" />
    <title>Quick vim svn blame snippet</title>
    <content type="html">&lt;div class="post published" id="post_107"&gt;&lt;div class='body'&gt;
  &lt;p&gt;Just to prove the theory that every incredibly incomprehensible piece of code you come across is probably your own, I penned a quick &lt;code&gt;svn blame&lt;/code&gt; vim command.&lt;/p&gt;
  &lt;pre&gt;&lt;code class="vim"&gt;&amp;#x000A;vmap gl :&amp;lt;C-U&amp;gt;!svn blame &amp;lt;C-R&amp;gt;=expand("%:p") &amp;lt;CR&amp;gt; \| sed -n &amp;lt;C-R&amp;gt;=line("'&amp;lt;") &amp;lt;CR&amp;gt;,&amp;lt;C-R&amp;gt;=line("'&amp;gt;") &amp;lt;CR&amp;gt;p &amp;lt;CR&amp;gt;&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;
  &lt;p&gt;Just &lt;a href="http://www.vim.org/htmldoc/visual.html"&gt;highlight&lt;/a&gt; the disgusting code in question, and bask in your own shame!&lt;/p&gt;
  &lt;p&gt;&lt;img src="/system/images/original/post.rb____code_tammersaleh_trunk_app_models____VIM.jpg" alt="" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class='extended'&gt;
  
&lt;/div&gt;
&lt;div class='clear'&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/TammerSaleh?a=Qwf8MaolCx8:kJA4mFUKPCE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TammerSaleh?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TammerSaleh?a=Qwf8MaolCx8:kJA4mFUKPCE:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TammerSaleh?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TammerSaleh/~4/Qwf8MaolCx8" height="1" width="1"/&gt;</content>
    <author>
      <name>Tammer Saleh</name>
    </author>
  <feedburner:origLink>http://tammersaleh.com/posts/quick-vim-svn-blame-snippet</feedburner:origLink></entry>
  <entry>
    <id>tag:tammersaleh.com,2005:Post/106</id>
    <published>2008-04-15T11:20:38Z</published>
    <updated>2008-05-06T17:57:29Z</updated>
    <link type="text/html" href="http://feedproxy.google.com/~r/TammerSaleh/~3/WraXfPlVQ20/getting-back-into-the-swing-of-things" rel="alternate" />
    <title>Getting back into the swing of things.</title>
    <content type="html">&lt;div class="post published" id="post_106"&gt;&lt;div class='body'&gt;
  &lt;p&gt;The past three weeks have been a total whirlwind of excitement, glamour, drinking, more glamour, sickness, boredom, and a bit more glamour.&lt;/p&gt;
  &lt;p&gt;&lt;a href="http://mtnwestrubyconf2008.confreaks.com/12saleh.html"&gt;&lt;img src="/system/images/original/Confreaks__MountainWest_Ruby_Conference_2008_1.jpg"&gt;&lt;/a&gt;&lt;/p&gt;
  &lt;p&gt;I gave a presentation on &lt;a href="/system/assets/bdd_with_shoulda.pdf"&gt;&lt;span class="caps"&gt;BDD&lt;/span&gt; with shoulda&lt;/a&gt; for &lt;a href="http://mtnwestrubyconf.org"&gt;Mountain West Ruby Conf&lt;/a&gt; in Salt Lake City (video above).&lt;/p&gt;
  &lt;p&gt;&lt;span style="clear:both"/&gt;&lt;/p&gt;
  &lt;p style="float:left;"&gt;&lt;img src="/system/images/original/slc_library.jpg" alt="" /&gt;&lt;/p&gt;
  &lt;p&gt;It must be nice to live in a city completely surrounded by gorgeous snow capped mountains.  And the library where the conference was held was an incredible example of architecture.  Lots of sweeping curves and generous amounts of glass.&lt;/p&gt;
  &lt;p&gt;After that, it was off to present at Scotland on Rails.  I&amp;#8217;ve never been to a city as thoroughly beautiful as Edinburgh.  It seemed like every street was lined with buildings older than my own country.&lt;/p&gt;
  &lt;p&gt;I&amp;#8217;ll be putting the shots I took for both of these trips up on my flickr account as soon as I have time to unload them.&lt;/p&gt;
  &lt;p&gt;Unfortunately, I fell under the grips of a serious cold at the end of that trip, and just finished recovering last weekend.  So now it&amp;#8217;s time to get back up to speed.&lt;/p&gt;
  &lt;p&gt;I&amp;#8217;ll be in New York next weekend for &lt;a href="http://2008.goruco.com/"&gt;GoRuCo&lt;/a&gt;, Brisbane on the 9th for some personal time, San Diego on the 23rd for more of the same, Portland on the 29th for &lt;a href="http://en.oreilly.com/rails2008/"&gt;RailsConf&lt;/a&gt;, and Portland again in July for &lt;a href="http://en.oreilly.com/oscon2008/public/content/home"&gt;&lt;span class="caps"&gt;OSCON&lt;/span&gt;&lt;/a&gt;, where I&amp;#8217;ll be giving a 3 hour tutorial on advanced ruby metaprogramming.&lt;/p&gt;
  &lt;p&gt;In fact, I&amp;#8217;ve got so many trips planned this season, that I&amp;#8217;ve started using Dopplr to keep track of them.  Check out my profile and itinerary in the sidebar, stage left.&lt;/p&gt;
  &lt;p&gt;And I promise to get back to more technical posts as soon as the dust settles.&lt;/p&gt;
&lt;/div&gt;
&lt;div class='extended'&gt;
  
&lt;/div&gt;
&lt;div class='clear'&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/TammerSaleh?a=WraXfPlVQ20:VbEbaphjkOc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TammerSaleh?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TammerSaleh?a=WraXfPlVQ20:VbEbaphjkOc:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TammerSaleh?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TammerSaleh/~4/WraXfPlVQ20" height="1" width="1"/&gt;</content>
    <author>
      <name>Tammer Saleh</name>
    </author>
  <feedburner:origLink>http://tammersaleh.com/posts/getting-back-into-the-swing-of-things</feedburner:origLink></entry>
  <entry>
    <id>tag:tammersaleh.com,2005:Post/105</id>
    <published>2008-03-20T07:01:17Z</published>
    <updated>2008-03-20T07:04:11Z</updated>
    <link type="text/html" href="http://feedproxy.google.com/~r/TammerSaleh/~3/O0_8mXSSh64/email-your-backpack-gtd-items" rel="alternate" />
    <title>Email your Backpack GTD items</title>
    <content type="html">&lt;div class="post published" id="post_105"&gt;&lt;div class='body'&gt;
  &lt;p&gt;Like most kids out there, I&amp;#8217;m a follower of the &lt;a href="http://en.wikipedia.org/wiki/GTD"&gt;&lt;span class="caps"&gt;GTD&lt;/span&gt; system&lt;/a&gt;.  I&amp;#8217;ve gone through a bunch of &lt;span class="caps"&gt;GTD&lt;/span&gt; software and have boiled it down to a combination of &lt;a href="http://www.backpackit.com/"&gt;Backpack&lt;/a&gt; and a pad of paper in my hip pocket.&lt;/p&gt;
  &lt;p&gt;I thought I&amp;#8217;d share a script I wrote that emails me my list of todo items every morning.&lt;/p&gt;
&lt;/div&gt;
&lt;div class='extended'&gt;
  &lt;p&gt;First off, my backpack &lt;span class="caps"&gt;GTD&lt;/span&gt; system is pretty straight forward:&lt;/p&gt;
  &lt;ol&gt;
  	&lt;li&gt;A page for each context, the names of which start with &amp;#8216;@&amp;#8217; &amp;#8211; so @work, @phone, @online, @zipcar, @home, @blog, etc.&lt;/li&gt;
  	&lt;li&gt;Each context page includes a single list named &amp;#8220;Tasks&amp;#8221;&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p&gt;That&amp;#8217;s about it.  I&amp;#8217;ve also got a someday/maybe page, and a page for each major project, but those don&amp;#8217;t get emailed to me.&lt;/p&gt;
  &lt;p&gt;Download &lt;a href="/system/assets/email_todos.rb"&gt;this script&lt;/a&gt;, change the constants at the top, and plop it on a server somewhere.  You should test it on the server it will live on by running &lt;code&gt;/usr/local/bin/ruby /home/tsaleh/bin/email_todos.rb&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;Then setup your crontab to run that sucker every morning.  My crontab looks like this:&lt;/p&gt;
  &lt;pre&gt;&lt;code class="crontab"&gt;&amp;#x000A;@daily /usr/local/bin/ruby /home/tsaleh/bin/email_todos.rb &amp;#x000A;&lt;/code&gt;&lt;/pre&gt;
  &lt;p&gt;That should be it.  The next morning you&amp;#8217;ll get a list of the tasks you have to complete for each context.&lt;/p&gt;
&lt;/div&gt;
&lt;div class='clear'&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/TammerSaleh?a=O0_8mXSSh64:fHzQ7fRaamU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TammerSaleh?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TammerSaleh?a=O0_8mXSSh64:fHzQ7fRaamU:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TammerSaleh?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TammerSaleh/~4/O0_8mXSSh64" height="1" width="1"/&gt;</content>
    <author>
      <name>Tammer Saleh</name>
    </author>
  <feedburner:origLink>http://tammersaleh.com/posts/email-your-backpack-gtd-items</feedburner:origLink></entry>
  <entry>
    <id>tag:tammersaleh.com,2005:Post/104</id>
    <published>2008-03-07T09:39:36Z</published>
    <updated>2008-03-07T09:44:48Z</updated>
    <link type="text/html" href="http://feedproxy.google.com/~r/TammerSaleh/~3/gSbebNXBRJY/politiquotes-who-said-what-when-and-where" rel="alternate" />
    <title>Politiquotes - Who said what, when, and where</title>
    <content type="html">&lt;div class="post published" id="post_104"&gt;&lt;div class='body'&gt;
  &lt;p&gt;I&amp;#8217;d like to announce the launching of a small side project of mine:&lt;/p&gt;
  &lt;p&gt;&lt;a href="http://politiquotes.org"&gt;&lt;br /&gt;
  &lt;img src="/system/images/original/politiquotes.jpg" alt="" /&gt;&lt;br /&gt;
  &lt;/a&gt;&lt;/p&gt;
  &lt;h2&gt;&lt;a href="http://politiquotes.org"&gt;Politiquotes&lt;/a&gt;&lt;/h2&gt;
  &lt;p&gt;A political awareness app where you can post, vote on, and discuss quotes from your favorite candidates.&lt;/p&gt;
  &lt;p&gt;So &lt;a href="http://politiquotes.org/users/new"&gt;join up&lt;/a&gt; and get your quote on!&lt;/p&gt;
&lt;/div&gt;
&lt;div class='extended'&gt;
  
&lt;/div&gt;
&lt;div class='clear'&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/TammerSaleh?a=gSbebNXBRJY:_e5Jk5SvpPk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TammerSaleh?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TammerSaleh?a=gSbebNXBRJY:_e5Jk5SvpPk:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TammerSaleh?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TammerSaleh/~4/gSbebNXBRJY" height="1" width="1"/&gt;</content>
    <author>
      <name>Tammer Saleh</name>
    </author>
  <feedburner:origLink>http://tammersaleh.com/posts/politiquotes-who-said-what-when-and-where</feedburner:origLink></entry>
  <entry>
    <id>tag:tammersaleh.com,2005:Post/103</id>
    <published>2008-03-04T08:31:16Z</published>
    <updated>2008-03-04T08:37:08Z</updated>
    <link type="text/html" href="http://feedproxy.google.com/~r/TammerSaleh/~3/kPhYkixPfEk/shoulda-4-0-1-the-lean-and-mean-release" rel="alternate" />
    <title>Shoulda 4.0.1 - the lean and mean release</title>
    <content type="html">&lt;div class="post published" id="post_103"&gt;&lt;div class='body'&gt;
  &lt;p&gt;&lt;i&gt;Crossposted from &lt;a href="http://giantrobots.thoughtbot.com/2008/3/3/shoulda-the-lean-and-mean-release"&gt;GiantRobots&lt;/a&gt;&lt;/i&gt;&lt;/p&gt;
  &lt;p&gt;&lt;a href="http://flickr.com/photos/robillardfamily/119635448/"&gt;&lt;br /&gt;
  &lt;img src="/system/images/original/baby.jpg" title="look at that drool" alt="look at that drool" /&gt;&lt;br /&gt;
  &lt;/a&gt;&lt;/p&gt;
  &lt;p&gt;Shoulda is a great tool for cleaning up your tests, but there was always some&lt;br /&gt;
  dirt under the hood that was keeping me up at night.  I don&amp;#8217;t want to just&lt;br /&gt;
  &lt;a href="http://www.klankboomklang.com/2007/10/26/class-methods-part-ii-annotations/"&gt;move complexity around&lt;/a&gt; &amp;#8211; I want to remove it entirely.&lt;/p&gt;
  &lt;p&gt;A &lt;a href="http://tammer.lighthouseapp.com/projects/5807/tickets/12-rails-2-0-change-breaks-shoulda"&gt;recent change&lt;/a&gt; in edge rails forced me to get off my butt and do that.&lt;/p&gt;
  &lt;p&gt;So everyone give a warm hello to the latest &lt;a href="http://rubyforge.org/projects/shoulda"&gt;Shoulda gem&lt;/a&gt;.  It now uses a Context class in the backend, prints out &lt;code&gt;should_eventually&lt;/code&gt; tests in a clear way, names the bare shouldas nicely, and fixes a few small bugs.&lt;/p&gt;
  &lt;p&gt;I also took the opportunity to fix some of the outstanding issues in the &lt;a href="http://thoughtbot.com/projects/shoulda"&gt;shoulda rails plugin&lt;/a&gt; (with a lot of great help from the community).&lt;/p&gt;
  &lt;p&gt;So grab the latest plugin and have some fun:&lt;/p&gt;
  &lt;pre&gt;&lt;code class="bash"&gt;&amp;#x000A;piston install https://svn.thoughtbot.com/plugins/shoulda/tags/rel-4.0.1 vendor/plugins/shoulda&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;
  &lt;p&gt;Also, &lt;a href="http://tammer.lighthouseapp.com/projects/5807-shoulda/tickets"&gt;please let me know&lt;/a&gt; if you find any bugs or issues.&lt;/p&gt;
&lt;/div&gt;
&lt;div class='extended'&gt;
  
&lt;/div&gt;
&lt;div class='clear'&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/TammerSaleh?a=kPhYkixPfEk:F-vC2gGGafM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TammerSaleh?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TammerSaleh?a=kPhYkixPfEk:F-vC2gGGafM:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TammerSaleh?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TammerSaleh/~4/kPhYkixPfEk" height="1" width="1"/&gt;</content>
    <author>
      <name>Tammer Saleh</name>
    </author>
  <feedburner:origLink>http://tammersaleh.com/posts/shoulda-4-0-1-the-lean-and-mean-release</feedburner:origLink></entry>
  <entry>
    <id>tag:tammersaleh.com,2005:Post/102</id>
    <published>2008-02-23T09:02:34Z</published>
    <updated>2008-02-23T09:10:35Z</updated>
    <link type="text/html" href="http://feedproxy.google.com/~r/TammerSaleh/~3/FNRYqr323-4/scotland-on-rails" rel="alternate" />
    <title>Upcoming conferences</title>
    <content type="html">&lt;div class="post published" id="post_102"&gt;&lt;div class='body'&gt;
  &lt;p&gt;I&amp;#8217;m totally psyched to say that I&amp;#8217;ve been invited to speak at &lt;a href="http://scotlandonrails.com"&gt;Scotland on Rails&lt;/a&gt;.  I&amp;#8217;ll be in the company of some &lt;a href="http://scotlandonrails.com/speakers"&gt;truly amazing ruby developers&lt;/a&gt;, and I highly recommend that you reserve your ticket now.  Who can resist a conference in site of an &lt;a href="http://en.wikipedia.org/wiki/Edinburgh_Castle"&gt;ancient scottish stronghold&lt;/a&gt;?  Or, more to the point, who can resist the scotch?&lt;/p&gt;
  &lt;p&gt;I&amp;#8217;ve also been invited to speak at the &lt;a href="http://mtnwestrubyconf.org/"&gt;Mountain West Ruby conference&lt;/a&gt; alongside speakers like &lt;a href="http://ph7spot.com/"&gt;Philippe Hanrigou&lt;/a&gt; and &lt;a href="http://www.jeremymcanally.com/" title="Mr. Neighborly"&gt;Jeremy McAnally&lt;/a&gt;.  There are a lot of talks at this one that I&amp;#8217;m excited about seeing &amp;#8211; especially the ones on Datamapper and CouchDB.&lt;/p&gt;
  &lt;p&gt;So if you&amp;#8217;re at either of those conferences, then please drop by and say hi.  And, yes, I&amp;#8217;m just as fuzzy as my picture in real life.&lt;/p&gt;
&lt;/div&gt;
&lt;div class='extended'&gt;
  
&lt;/div&gt;
&lt;div class='clear'&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/TammerSaleh?a=FNRYqr323-4:feHY9O7WbRE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TammerSaleh?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TammerSaleh?a=FNRYqr323-4:feHY9O7WbRE:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TammerSaleh?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TammerSaleh/~4/FNRYqr323-4" height="1" width="1"/&gt;</content>
    <author>
      <name>Tammer Saleh</name>
    </author>
  <feedburner:origLink>http://tammersaleh.com/posts/scotland-on-rails</feedburner:origLink></entry>
  <entry>
    <id>tag:tammersaleh.com,2005:Post/101</id>
    <published>2008-02-08T08:49:10Z</published>
    <updated>2008-02-08T08:49:34Z</updated>
    <link type="text/html" href="http://feedproxy.google.com/~r/TammerSaleh/~3/iVLyMqHv2Cg/rails-rumours" rel="alternate" />
    <title>Rails Rumours</title>
    <content type="html">&lt;div class="post published" id="post_101"&gt;&lt;div class='body'&gt;
  &lt;blockquote&gt;
  &lt;p&gt;Topfunky founder discloses origins of company name: &amp;#8220;I was high.&amp;#8221; &amp;#8211; &lt;a href="http://www.railsrumours.com/"&gt;Rails Rumours&lt;/a&gt;&lt;/p&gt;
  &lt;/blockquote&gt;
&lt;/div&gt;
&lt;div class='extended'&gt;
  
&lt;/div&gt;
&lt;div class='clear'&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/TammerSaleh?a=iVLyMqHv2Cg:2DtLgw0bEX0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TammerSaleh?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TammerSaleh?a=iVLyMqHv2Cg:2DtLgw0bEX0:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TammerSaleh?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TammerSaleh/~4/iVLyMqHv2Cg" height="1" width="1"/&gt;</content>
    <author>
      <name>Tammer Saleh</name>
    </author>
  <feedburner:origLink>http://tammersaleh.com/posts/rails-rumours</feedburner:origLink></entry>
  <entry>
    <id>tag:tammersaleh.com,2005:Post/100</id>
    <published>2008-02-04T15:42:47Z</published>
    <updated>2008-02-04T15:43:16Z</updated>
    <link type="text/html" href="http://feedproxy.google.com/~r/TammerSaleh/~3/t4Pr9fi6Lr4/fake-steve-on-microsoft-s-bid-for-yahoo" rel="alternate" />
    <title>Elephants</title>
    <content type="html">&lt;div class="post published" id="post_100"&gt;&lt;div class='body'&gt;
  &lt;blockquote&gt;
  &lt;p&gt;Imagine a circus act in which two enormous, clumsy, awkward elephants that don&amp;#8217;t really like each other are supposed to mate while riding on skateboards. Now imagine that it is your job, you lucky bastard, to be one of the little circus clowns standing alongside trying to make this extremely unnatural and unholy act take place.  &amp;#8212; &lt;a href="http://fakesteve.blogspot.com/2008/02/ballmer-im-completely-out-of-ideas.html"&gt;Fake Steve on Microsoft&amp;#8217;s bid for Yahoo&lt;/a&gt;&lt;/p&gt;
  &lt;/blockquote&gt;
&lt;/div&gt;
&lt;div class='extended'&gt;
  
&lt;/div&gt;
&lt;div class='clear'&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/TammerSaleh?a=t4Pr9fi6Lr4:dLwxPaxaCAI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TammerSaleh?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TammerSaleh?a=t4Pr9fi6Lr4:dLwxPaxaCAI:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TammerSaleh?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TammerSaleh/~4/t4Pr9fi6Lr4" height="1" width="1"/&gt;</content>
    <author>
      <name>Tammer Saleh</name>
    </author>
  <feedburner:origLink>http://tammersaleh.com/posts/fake-steve-on-microsoft-s-bid-for-yahoo</feedburner:origLink></entry>
  <entry>
    <id>tag:tammersaleh.com,2005:Post/99</id>
    <published>2008-02-01T19:12:14Z</published>
    <updated>2008-02-01T19:15:33Z</updated>
    <link type="text/html" href="http://feedproxy.google.com/~r/TammerSaleh/~3/DiegA5Q-WIU/switchpipe-2" rel="alternate" />
    <title>Switchpipe</title>
    <content type="html">&lt;div class="post published" id="post_99"&gt;&lt;div class='body'&gt;
  &lt;blockquote&gt;
  &lt;p&gt;&lt;a href="http://switchpipe.org/"&gt;SwitchPipe manages and forwards &lt;span class="caps"&gt;HTTP&lt;/span&gt; requests to Web application processes, automatically managing balancing, port numbers, monitoring and timeouts.&lt;/a&gt;&lt;/p&gt;
  &lt;/blockquote&gt;
  &lt;p&gt;&lt;img src="/system/images/original/diagram.jpg" alt="" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class='extended'&gt;
  
&lt;/div&gt;
&lt;div class='clear'&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/TammerSaleh?a=DiegA5Q-WIU:5_dTZFXrKbA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TammerSaleh?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TammerSaleh?a=DiegA5Q-WIU:5_dTZFXrKbA:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TammerSaleh?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TammerSaleh/~4/DiegA5Q-WIU" height="1" width="1"/&gt;</content>
    <author>
      <name>Tammer Saleh</name>
    </author>
  <feedburner:origLink>http://tammersaleh.com/posts/switchpipe-2</feedburner:origLink></entry>
  <entry>
    <id>tag:tammersaleh.com,2005:Post/97</id>
    <published>2008-01-31T11:26:06Z</published>
    <updated>2008-01-31T11:26:47Z</updated>
    <link type="text/html" href="http://feedproxy.google.com/~r/TammerSaleh/~3/bBWCHMR0z_8/37-signals-introduces-line-breaks" rel="alternate" />
    <title>37 Signals introduces line breaks</title>
    <content type="html">&lt;div class="post published" id="post_97"&gt;&lt;div class='body'&gt;
  &lt;blockquote&gt;
  &lt;h4&gt;Linebreaks!&lt;/h4&gt;
  &lt;p&gt;&lt;a href="http://www.37signals.com/svn/posts/824-new-job-board-features"&gt;Job postings uses to be single paragraphs but now you can enter multiple paragraphs. We’ve also relaxed the 1000 character limit so you can post longer job ads if you’d like (although we believe concise, to-the-point job ads are more effective).&lt;/a&gt;&lt;/p&gt;
  &lt;/blockquote&gt;
&lt;/div&gt;
&lt;div class='extended'&gt;
  
&lt;/div&gt;
&lt;div class='clear'&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/TammerSaleh?a=bBWCHMR0z_8:f2jtX-edbv0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TammerSaleh?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TammerSaleh?a=bBWCHMR0z_8:f2jtX-edbv0:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TammerSaleh?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TammerSaleh/~4/bBWCHMR0z_8" height="1" width="1"/&gt;</content>
    <author>
      <name>Tammer Saleh</name>
    </author>
  <feedburner:origLink>http://tammersaleh.com/posts/37-signals-introduces-line-breaks</feedburner:origLink></entry>
  <entry>
    <id>tag:tammersaleh.com,2005:Post/96</id>
    <published>2008-01-30T10:03:25Z</published>
    <updated>2008-01-30T10:06:11Z</updated>
    <link type="text/html" href="http://feedproxy.google.com/~r/TammerSaleh/~3/6dDga0lxjfo/a-couple-small-but-totally-useful-plugins" rel="alternate" />
    <title>A couple of small, but totally useful plugins</title>
    <content type="html">&lt;div class="post published" id="post_96"&gt;&lt;div class='body'&gt;
  &lt;p&gt;There are two plugins (well, one&amp;#8217;s a gem) that I&amp;#8217;ve been using lately which are so small that it seems silly to post about them.&lt;/p&gt;
  &lt;p&gt;&amp;#8230;except for the fact that they&amp;#8217;re incredibly useful.&lt;/p&gt;
&lt;/div&gt;
&lt;div class='extended'&gt;
  &lt;p&gt;&lt;strong&gt;disclaimer&lt;/strong&gt;:  these were written by friends of mine.  In fact one of them was written by my boss, so this is nothing more than an obvious attempt to garner a raise.&lt;/p&gt;
  &lt;h3&gt;&lt;a href="http://thoughtbot.com/projects/mile_marker"&gt;mile_marker&lt;/a&gt;&lt;/h3&gt;
  &lt;p&gt;&lt;img src="/system/images/original/Politiquotes.jpg" alt="" /&gt;&lt;/p&gt;
  &lt;p&gt;We use this at thoughtbot to manage client expectations, but I use it for my own sites to visually remind myself when I haven&amp;#8217;t completed part of a page.&lt;/p&gt;
  &lt;h3&gt;&lt;a href="http://thoughtbot.com/projects/quietbacktrace"&gt;Quiet Backtrace&lt;/a&gt;&lt;/h3&gt;
  &lt;p&gt;Install this gem, configure it in your test_helper.rb, and watch as your failure backtraces shrink to just the information you need.  If you&amp;#8217;re following &lt;span class="caps"&gt;BDD&lt;/span&gt;, and trying to achieve 1 assertion per test, then this really helps unclutter your failures.&lt;/p&gt;
&lt;/div&gt;
&lt;div class='clear'&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/TammerSaleh?a=6dDga0lxjfo:dmrDsWiOWIM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TammerSaleh?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TammerSaleh?a=6dDga0lxjfo:dmrDsWiOWIM:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TammerSaleh?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TammerSaleh/~4/6dDga0lxjfo" height="1" width="1"/&gt;</content>
    <author>
      <name>Tammer Saleh</name>
    </author>
  <feedburner:origLink>http://tammersaleh.com/posts/a-couple-small-but-totally-useful-plugins</feedburner:origLink></entry>
  <entry>
    <id>tag:tammersaleh.com,2005:Post/95</id>
    <published>2008-01-29T20:19:14Z</published>
    <updated>2008-01-29T20:19:38Z</updated>
    <link type="text/html" href="http://feedproxy.google.com/~r/TammerSaleh/~3/vkjA3v4D99c/rescuing-net-http-exceptions" rel="alternate" />
    <title>Rescuing Net::HTTP exceptions</title>
    <content type="html">&lt;div class="post published" id="post_95"&gt;&lt;div class='body'&gt;
  &lt;p&gt;Working with &lt;a href="http://www.ruby-doc.org/stdlib/libdoc/net/http/rdoc/index.html"&gt;Net::&lt;span class="caps"&gt;HTTP&lt;/span&gt;&lt;/a&gt; can be a pain.  It&amp;#8217;s got about 40 different ways to do any one task, and about 50 exceptions it can throw.&lt;/p&gt;
  &lt;p&gt;Just for the love of google, here&amp;#8217;s what I&amp;#8217;ve got for the &amp;#8220;right way&amp;#8221; of catching any exception that Net::&lt;span class="caps"&gt;HTTP&lt;/span&gt; can throw at you:&lt;/p&gt;
  &lt;pre&gt;&lt;code class="ruby"&gt;&amp;#x000A;begin&amp;#x000A;  response = Net::HTTP.post_form(...) # or any Net::HTTP call&amp;#x000A;rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError,&amp;#x000A;       Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError =&amp;gt; e&amp;#x000A;  ...&amp;#x000A;end&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;
  &lt;p&gt;Why not just &lt;code&gt;rescue Exception =&amp;gt; e&lt;/code&gt;?  That&amp;#8217;s a bad habit to get into, as it hides any problems in your actual code (like SyntaxErrors, whiny nils, etc).  Of course, this would all be much easier if the possible errors had a common ancestor.&lt;/p&gt;
  &lt;p&gt;The issues I&amp;#8217;ve been seeing in dealing with Net::&lt;span class="caps"&gt;HTTP&lt;/span&gt; have made me wonder if it wouldn&amp;#8217;t be worth it to write a new &lt;span class="caps"&gt;HTTP&lt;/span&gt; client library.  One that was easier to mock out in tests, and didn&amp;#8217;t have all these ugly little facets.&lt;/p&gt;
  &lt;p&gt;Comment below if you know of more exceptions it should catch, or of an easier way to get this done.&lt;/p&gt;
&lt;/div&gt;
&lt;div class='extended'&gt;
  
&lt;/div&gt;
&lt;div class='clear'&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/TammerSaleh?a=vkjA3v4D99c:QvodmJBNAtA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TammerSaleh?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TammerSaleh?a=vkjA3v4D99c:QvodmJBNAtA:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TammerSaleh?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TammerSaleh/~4/vkjA3v4D99c" height="1" width="1"/&gt;</content>
    <author>
      <name>Tammer Saleh</name>
    </author>
  <feedburner:origLink>http://tammersaleh.com/posts/rescuing-net-http-exceptions</feedburner:origLink></entry>
  <entry>
    <id>tag:tammersaleh.com,2005:Post/93</id>
    <published>2007-12-11T01:32:00Z</published>
    <updated>2008-01-29T20:17:16Z</updated>
    <link type="text/html" href="http://feedproxy.google.com/~r/TammerSaleh/~3/IPdABUvfO0g/shoulda-in-advanced-rails-recipes" rel="alternate" />
    <title>Shoulda in Advanced Rails Recipes</title>
    <content type="html">&lt;div class="post published" id="post_93"&gt;&lt;div class='body'&gt;
  &lt;p&gt;&lt;i&gt;Cross posted from &lt;a href="http://giantrobots.thoughtbot.com/2007/12/10/shoulda-in-advanced-rails-recipes"&gt;Giant Robots&lt;/a&gt;&lt;/i&gt;&lt;/p&gt;
  &lt;p&gt;Mike Clark and the Pragmatic Programmers just released the beta version of their latest offering:  &lt;a href="http://pragprog.com/titles/fr_arr"&gt;Advanced Rails Recipes: 72 New Ways to Build Stunning Rails Apps&lt;/a&gt;.  This is one of the few rails books I&amp;#8217;ve been eagerly waiting for, so you can imagine how honored I was when Mike Clark asked me to review his section on Shoulda.&lt;/p&gt;
  &lt;h3&gt;That&amp;#8217;s right, folks! Shoulda got its own stake of land in recipe #22:  &amp;#8220;Getting Started with &lt;span class="caps"&gt;BDD&lt;/span&gt;.&amp;#8221;&lt;/h3&gt;
  &lt;p&gt;So head on over and &lt;a href="http://pragprog.com/titles/fr_arr"&gt;grab the combo pack&lt;/a&gt;.  You get the beta &lt;span class="caps"&gt;PDF&lt;/span&gt; now (&amp;#8217;cause none of us respect delayed gratification) and the print book when it ships &amp;#8211; all for around $40.&lt;/p&gt;
&lt;/div&gt;
&lt;div class='extended'&gt;
  
&lt;/div&gt;
&lt;div class='clear'&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/TammerSaleh?a=IPdABUvfO0g:sgT_G67tiXE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TammerSaleh?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TammerSaleh?a=IPdABUvfO0g:sgT_G67tiXE:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TammerSaleh?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TammerSaleh/~4/IPdABUvfO0g" height="1" width="1"/&gt;</content>
    <author>
      <name>Tammer Saleh</name>
    </author>
  <feedburner:origLink>http://tammersaleh.com/posts/shoulda-in-advanced-rails-recipes</feedburner:origLink></entry>
</feed>
