<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
  <channel>
    <title>PaulBarry.com</title>
    <link>http://paulbarry.com/</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>My thoughts, ideas, questions and concerns on technology, sports, music and life</description>
    <geo:lat>39.273841</geo:lat><geo:long>-76.610201</geo:long><image><link>http://www.gravatar.com/avatar/6661ef9d747db3af8896cd94959d717d?s=80</link><url>http://www.feedburner.com/fb/images/pub/fb_pwrd.gif</url><title>Paul Barry</title></image><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/paulbarry" type="application/rss+xml" /><feedburner:emailServiceId>paulbarry</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
      <title>A rake task for tracking your time with git</title>
      <description>&lt;p&gt;Are you using Ruby on Rails?  Are you using Git?  Do you have a need to track how long you spend on things?  Then I have just the thing for you.&lt;/p&gt;

&lt;p&gt;I threw together a quick rake task that gets all of your commits in a git repo and  parses out the times and commit message from them.  Then it formats them with the time and also the time interval between them.  You can get the &lt;a href="http://bit.ly/rake-git-time-tracker"&gt;rake task to track your time from this gist&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The output will look something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Fri, Jul 07 10:55AM  20m 49s  Added toolbar for controllers using temp...
Fri, Jul 07 10:34AM  21h 52m  Added support for using page templates i...
Thu, Jul 07 12:42PM  37m 57s  LH#77, fixed issue with tests failing on...
Thu, Jul 07 12:04PM  12m 18s  LH#67, added a limit option to the rende...
Thu, Jul 07 11:52AM  17m 30s  Removed debug statement                 ...
Thu, Jul 07 11:34AM  19h 52m  LH#66, added :path option to render menu...
Wed, Jul 07 03:41PM           Added DSL for modifying portlet behavior...
Tue, Jun 06 02:05PM  18h 44m  LH#119, multiple HTML fields on one bloc...
Mon, Jun 06 07:20PM   6h 21m  Converted docs to textile               ...
Mon, Jun 06 12:58PM           Fix for LH#118, create directories in ge...
Sat, Jun 06 10:22PM           Added support for other template handler...
Fri, Jun 06 04:49PM   0m 58s  bump build                              ...
Fri, Jun 06 04:48PM  23m 11s  Fix LH#106: Section not correctly loadin...
Fri, Jun 06 04:25PM  34m 25s  Fix for LH#107, images were not showing ...
Fri, Jun 06 03:51PM   9m 48s  Fix for LH#110, can't view usages of a p...
Fri, Jun 06 03:41PM  11m 12s  Fix for LH#113, check to see if there is...
Fri, Jun 06 03:30PM   2m 52s  Fixed LH#114, documentation typo        ...
Fri, Jun 06 03:27PM   0m 38s  bump build number                       ...
Fri, Jun 06 03:26PM   5h 38m  Fix for LH#98, tags not getting updated ...
Fri, Jun 06 09:48AM  33m 14s  Fixed LH#105, deleted portlets showing u...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It doesn't actually truncate the commit messages, I just did that here to make each one fit on a line.  If the time interval is over 24 hours, it doesn't bother printing the interval, because you probably didn't actually work on that one commit for 37 hours straight.  I've been thinking if you really want to track time this way then each time you sit down to start hacking on a project, you just make a minor change to the .gitignore or something and then commit it with a message like "started hacking on foo", so then when you commit your first chunk of actual work, you will know how long you spend on that.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/paulbarry?a=mm4gh-90E7I:87qWd95zZwM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulbarry?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/paulbarry?a=mm4gh-90E7I:87qWd95zZwM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulbarry?i=mm4gh-90E7I:87qWd95zZwM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/paulbarry?a=mm4gh-90E7I:87qWd95zZwM:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulbarry?i=mm4gh-90E7I:87qWd95zZwM:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/paulbarry?a=mm4gh-90E7I:87qWd95zZwM:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulbarry?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Tue, 07 Jul 2009 00:49:03 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:a2f77695-7b12-473f-9c63-cd30cd100565</guid>
      <author>mail@paulbarry.com (Paul Barry)</author>
      <link>http://feedproxy.google.com/~r/paulbarry/~3/mm4gh-90E7I/a-rake-task-for-tracking-your-time-with-git</link>
      <category>Technology</category>
            <category>Rake</category>
      <category>Git</category>
      <category>Ruby</category>
          <feedburner:origLink>http://paulbarry.com/articles/2009/07/07/a-rake-task-for-tracking-your-time-with-git</feedburner:origLink></item>
    <item>
      <title>Programming Clojure</title>
      <description>&lt;div style="float: left"&gt;&lt;img src="http://farm4.static.flickr.com/3550/3668736570_5d0528aaed_m.jpg" alt="Programming Clojure" style="margin: 0 15px 15px 0"/&gt;&lt;/div&gt;

&lt;p&gt;A few weeks ago I received my printed copy of &lt;a href="http://pragprog.com/titles/shcloj/programming-clojure"&gt;Programming Clojure&lt;/a&gt; by &lt;a href="http://twitter.com/stuarthalloway"&gt;Stuart Halloway&lt;/a&gt; in the mail.  I had been a technical reviewer of the book so I was excited to see it finally in print.  In case you haven't heard of it yet, &lt;a href="http://clojure.org"&gt;Clojure&lt;/a&gt; is a programming language designed by Rich Hickey, a Lisp dialect, that runs on the Java Virtual Machine and is designed support concurrent programming.&lt;/p&gt;

&lt;p&gt;Clojure has &lt;a href="http://clojure.org/Reference"&gt;excellent documentation&lt;/a&gt; and Rich has posted &lt;a href="http://clojure.blip.tv/posts?view=archive&amp;amp;nsfw=dc"&gt;several great videos&lt;/a&gt; of talks he has given that cover the rational for Clojure as well as an introduction into the major concepts.  I highly recommend that you watch those videos if you haven't already because Rich does a great job explaining why concurrency is hard using the typical Object-Oriented model that we program in today and how the features of Clojure support a better model for concurrency.  Whether you are programming in Java, C#, Erlang, Haskell, Python, Ruby, etc., you will probably be able to learn something from these talks, and plus Rich is just an interesting guy to listen to.&lt;/p&gt;

&lt;p&gt;So after all that, you might be saying why do we need a book about Clojure?  The answer is that although the documentation is good, it can be a little intimidating when first learning Clojure.  For programmers with little or no Lisp or functional programming experience, figuring out how to do basic things the idiomatic way in Clojure can be a daunting task.  Stuart's book does an excellent job filling this gap.&lt;/p&gt;

&lt;p&gt;The book covers all the major feature of Clojure and is very up-to-date.  As a reviewer I got to see the evolution of this book from revision to revision and it was amazing to me to see how much work Stuart put in.  Chapters were often completely re-written to keep up with changes in the language that occurred before it stabilized in a 1.0 release.  I think the final product greatly benefited from that work and is an excellent resource for learning Clojure.  I encourage you to pick up a copy today.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/paulbarry?a=OgTjFoJGk1g:RtZ1PB-UneU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulbarry?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/paulbarry?a=OgTjFoJGk1g:RtZ1PB-UneU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulbarry?i=OgTjFoJGk1g:RtZ1PB-UneU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/paulbarry?a=OgTjFoJGk1g:RtZ1PB-UneU:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulbarry?i=OgTjFoJGk1g:RtZ1PB-UneU:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/paulbarry?a=OgTjFoJGk1g:RtZ1PB-UneU:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulbarry?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Sun, 28 Jun 2009 12:37:44 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:032f1da0-1d0d-430f-aca3-9b2d2e16a182</guid>
      <author>mail@paulbarry.com (Paul Barry)</author>
      <link>http://feedproxy.google.com/~r/paulbarry/~3/OgTjFoJGk1g/programming-clojure</link>
      <category>Technology</category>
            <category>Clojure</category>
          <feedburner:origLink>http://paulbarry.com/articles/2009/06/28/programming-clojure</feedburner:origLink></item>
    <item>
      <title>Zip Code Proximity Search with Rails</title>
      <description>&lt;p&gt;So you're building the next big social networking website using &lt;a href="http://rubyonrails.org"&gt;Rails&lt;/a&gt; and like all the other hip kids you are going to need to allow your users to search for other users near them.  The fancy term for this is "Proximity Search".  For our search, we just want be able to find other people that are generally within some radius, like 5, 10 or 25 miles.  For this, there is no need to geocode the address for each user in our database, we'll just use their zip code.  So effectively, in our system, every user's location is just the center point of their zip code.&lt;/p&gt;

&lt;p&gt;For starters we want to create a zip code model:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;script/generate model zip code:string city:string state:string lat:decimal lon:decimal
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That will create a model and a migration.  You need to alter the migration to specify the precision and scale for the lat and the lon.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;t.decimal :lat, :precision =&amp;gt; 15, :scale =&amp;gt; 10
t.decimal :lon, :precision =&amp;gt; 15, :scale =&amp;gt; 10
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So to populate this database, luckily the good people over at the &lt;a href="http://www.census.gov"&gt;US Census Bureau&lt;/a&gt; have the &lt;a href="http://www.census.gov/tiger/tms/gazetteer/zips.txt"&gt;data&lt;/a&gt; readily available for us.  I've created a rake task to download and load that data into your zips table.  Simply put the &lt;code&gt;load.rake&lt;/code&gt; file from &lt;a href="http://bit.ly/rails-proximity-search"&gt;this gist&lt;/a&gt; into the &lt;code&gt;lib/tasks&lt;/code&gt; directory of your Rails app.&lt;/p&gt;

&lt;p&gt;So now when you run &lt;code&gt;rake load:zip_codes&lt;/code&gt; you should see something like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;== Loaded 29470 zip codes in ( 1m 40s) ========================================
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Next we need a table for our users.  So let's generate a model and a migration:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;script/generate model user
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I'll save you the hassle of typing out all the fields at the command-line and just give them to you here.  Paste this into the &lt;code&gt;create_users&lt;/code&gt; migration that was generated:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;t.string   :username
t.string   :email
t.string   :password
t.string   :password_confirmation
t.string   :first_name
t.string   :last_name
t.string   :address
t.string   :city
t.string   :state
t.integer  :zip_id
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Next you need to hook up the relationship between the zip and the user.  This is basic stuff, the zip has many users and the user belongs to a zip.&lt;/p&gt;

&lt;p&gt;Now we need some users to play with.  A great tool for this is &lt;a href="http://subelsky.com"&gt;Mike Subelsky's&lt;/a&gt; &lt;a href="http://random-data.rubyforge.org/"&gt;Random Data&lt;/a&gt; gem.  I've already created a rake task that uses this gem to create some test user accounts.  You call it like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;rake load:random_users[10000]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The 10000 is the number of users we want the rake task to generate for us.  Did you know you can pass command-line arguments to a rake task like that?  Pretty spiffy.  10000 is a pretty good number because it gives us a fairly large dataset to work with and is still able to load in a reasonable amount of time.  10000 users finished in about 6 minutes and 30 seconds for me.&lt;/p&gt;

&lt;p&gt;Next we need to setup our methods to do the querying.  For this I basically used &lt;a href="http://joshhuckabee.com/simple-zip-code-perimeter-search-rails"&gt;Josh Huckabee's Simple Zip Code Perimeter Search&lt;/a&gt; method, but re-worked it a little so we can use named scope with it.  You can grab the code for both &lt;code&gt;zip.rb&lt;/code&gt; and &lt;code&gt;user.rb&lt;/code&gt; from &lt;a href="http://bit.ly/rails-proximity-search"&gt;the gist&lt;/a&gt;.           &lt;/p&gt;

&lt;p&gt;There are a couple of things we get here.  First is a named scope to easily find zip codes.  Looking at the output of the loading of the random users, the last one for me was Mr. Steven Moore of Koloa, HI, 96756.  So let's see how many other people are in that zip code.  Start up &lt;code&gt;script/console&lt;/code&gt; and run this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt; Zip.code(96756).users.count
=&amp;gt; 1
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Hmm...I guess it's lonely in Hawaii.  Let's find the zip code that randomly ended up with the most inhabitants:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt; Zip.count_by_sql "select zip_id, count(*) as count 
from users group by zip_id order by count desc limit 1"
=&amp;gt; 18177
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Ok, so that's the id of the zip record, not to be confused with the actual zip code.  So let's find the first person in this zip code:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt; user = Zip.find(18177).users.first
=&amp;gt; #&amp;lt;User id: 1267, username: "cabel1266", ...&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I got Ms. Cheryl Abel of Bloomville, NY.  So now for the big moment.  What we really want to do is find everyone within 25 miles of Cheryl.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt; user.within_miles(25).count(:all)
49
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Looks like Cheryl has 49 people nearby.  Let's see who they are:    &lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt; user.within_miles(25).all.each{|u|
?&amp;gt; puts "%.2f %20s, %2s, %5s" %
?&amp;gt; [u.distance, u.city, u.state, u.zip.code]}
0.00           Bloomville, NY, 13739
0.00           Bloomville, NY, 13739
0.00           Bloomville, NY, 13739
0.00           Bloomville, NY, 13739
0.00           Bloomville, NY, 13739
7.04            Worcester, NY, 12197
7.04            Worcester, NY, 12197
7.43             Maryland, NY, 12116
8.09             Meredith, NY, 13753
8.54            De Lancey, NY, 13752
8.71     Livingston Manor, NY, 12758
9.11             Roseboom, NY, 13450
9.88          Jordanville, NY, 13361
...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So there you have it!  I'm still trying to work out some kinks with this and get it to work with count and will paginate, so if you have any suggestions, fork the gist, hack away and leave a comment.  I'll update this post when I get count and pagination working.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/paulbarry?a=Oz_EsqFUkho:yV0xrOf0mG8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulbarry?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/paulbarry?a=Oz_EsqFUkho:yV0xrOf0mG8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulbarry?i=Oz_EsqFUkho:yV0xrOf0mG8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/paulbarry?a=Oz_EsqFUkho:yV0xrOf0mG8:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulbarry?i=Oz_EsqFUkho:yV0xrOf0mG8:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/paulbarry?a=Oz_EsqFUkho:yV0xrOf0mG8:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulbarry?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Sat, 27 Jun 2009 02:17:37 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:48b2b36d-193c-41c9-98cc-b39e98b416d0</guid>
      <author>mail@paulbarry.com (Paul Barry)</author>
      <link>http://feedproxy.google.com/~r/paulbarry/~3/Oz_EsqFUkho/zip-code-proximity-search-with-rails</link>
      <category>Technology</category>
            <category>Rails</category>
      <category>Ruby</category>
          <feedburner:origLink>http://paulbarry.com/articles/2009/06/27/zip-code-proximity-search-with-rails</feedburner:origLink></item>
    <item>
      <title>Ruby Nation</title>
      <description>&lt;p&gt;Thanks to everyone who attended my talk yesterday at &lt;a href="http://rubynation.org"&gt;Ruby Nation&lt;/a&gt; about &lt;a href="http://browsercms.org"&gt;BrowserCMS&lt;/a&gt;.  I've posted my slides online &lt;a href="http://www.paulbarry.com/BrowserCMS_Presentation_RubyNation.pdf"&gt;here&lt;/a&gt;.  Unfortunately the demo part of the talk wasn't record, so I'll try to record a screencast of the demo.  Look for that in the next few days.&lt;/p&gt;

&lt;p&gt;If you did attend my talk, I would appreciate it if you take a minute to &lt;a href="http://speakerrate.com/talks/1174-bringing-content-management-to-rails-with-browsercms"&gt;rate it&lt;/a&gt;.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/paulbarry?a=bWj_CASufII:iVOXl8ktZP8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulbarry?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/paulbarry?a=bWj_CASufII:iVOXl8ktZP8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulbarry?i=bWj_CASufII:iVOXl8ktZP8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/paulbarry?a=bWj_CASufII:iVOXl8ktZP8:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulbarry?i=bWj_CASufII:iVOXl8ktZP8:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/paulbarry?a=bWj_CASufII:iVOXl8ktZP8:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulbarry?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Sat, 13 Jun 2009 10:43:29 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:108ec343-0da3-4cfd-af8e-ccb77facfb8e</guid>
      <author>mail@paulbarry.com (Paul Barry)</author>
      <link>http://feedproxy.google.com/~r/paulbarry/~3/bWj_CASufII/ruby-nation</link>
      <category>Technology</category>
            <category>Ruby</category>
          <feedburner:origLink>http://paulbarry.com/articles/2009/06/13/ruby-nation</feedburner:origLink></item>
    <item>
      <title>This Just In: JavaScript is a Real Language</title>
      <description>&lt;p&gt;Some people think of &lt;a href="http://en.wikipedia.org/wiki/JavaScript"&gt;JavaScript&lt;/a&gt; as that crappy language that runs inside of browsers.  The truth is that the languages is not that bad, aside from a few warts (void/explicit return, &lt;a href="http://paulbarry.com/articles/2008/09/01/javascript-global-by-default"&gt;global by default&lt;/a&gt; I'm looking at you), it's pretty nice.  I think it's gotten a bad wrap for a few reasons.  &lt;/p&gt;

&lt;p&gt;First of all, the &lt;a href="http://en.wikipedia.org/wiki/Document_Object_Model"&gt;DOM&lt;/a&gt;.  Before modern JavaScript libraries like &lt;a href="http://jquery.com"&gt;jQuery&lt;/a&gt; and &lt;a href="http://prototypejs.org"&gt;Prototype&lt;/a&gt; came along, developers were constantly pulling their hair out dealing with incompatibilities across different browser implementations of the DOM.  Modern libraries have done a lot to normalize behavior across browsers and browser implementations have gotten better, but many developers still have bad memories of dealing with "JavaScript" back in the day.  The truth was this wasn't really a problem in JavaScript the language, more so the DOM and browser implementations.  If the language that Netscape put into the browser originally was Ruby, we would blame Ruby for all of these problems too.&lt;/p&gt;

&lt;p&gt;Next, I think there was a whole class of Java developers upset that &lt;a href="http://en.wikipedia.org/wiki/Object_oriented"&gt;OO&lt;/a&gt; didn't work in JavaScript the way it did in Java.  JavaScript wasn't considered a "real" OO language and was therefore inferior to Java.  JavaScript has &lt;a href="http://blog.blainebuxton.com/2008/05/javascript-stop-fighting-it.html"&gt;it's own way of dealing with OO&lt;/a&gt; and the sooner you understand how that works, the more comfortable you will be with JavaScript.&lt;/p&gt;

&lt;p&gt;In the opposite way that many Java developers despised JavaScript, many Ruby developers, including Java developers converted to Ruby developers, started to appreciate JavaScript.  JavaScript has anonymous functions just like Ruby has anonymous functions.  Ruby makes ubiquitous use of anonymous functions through blocks.  I think for many developers, Ruby was the first language they used that showed how useful anonymous functions can be.  I think this is also the reason that you see some many Ruby developers interested other functional languages like Erlang, Haskell and Lisp.&lt;/p&gt;

&lt;p&gt;Lastly, I think many developers don't see JavaScript as a general purpose language simply because it's trapped inside the browser.  You can't run a JavaScript script from the command line just like you can run a Ruby, Python or Perl script.  &lt;/p&gt;

&lt;p&gt;Well, it turns out that last one isn't true and I want to show you how to get started writing some JavaScript as a "real" language, and specifically, a functional language.&lt;/p&gt;

&lt;p&gt;The first thing you'll need is a JavaScript interpreter.  There are two that I'm aware of, &lt;a href="http://www.mozilla.org/js/spidermonkey/"&gt;SpiderMonkey&lt;/a&gt;, the C-based JavaScript interpreter, and &lt;a href="http://www.mozilla.org/rhino/"&gt;Rhino&lt;/a&gt;, the Java-based JavaScript interpreter.  Let's go with SpiderMonkey.&lt;/p&gt;

&lt;p&gt;First, &lt;a href="http://ftp.mozilla.org/pub/mozilla.org/js/js-1.8.0-rc1.tar.gz"&gt;download the tarball&lt;/a&gt; and untar it somewhere on your machine.  I did that in the &lt;code&gt;src&lt;/code&gt; directory in my home directory.  Then you go into the &lt;code&gt;js/src&lt;/code&gt; directory and run the make command.  Here's what that looks like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cd ~/src
wget http://ftp.mozilla.org/pub/mozilla.org/js/js-1.8.0-rc1.tar.gz
tar xvzf js-1.8.0-rc1.tar.gz
cd js/src
make -f Makefile.ref
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now you should have a directory like &lt;code&gt;Darwin_DBG.OBJ&lt;/code&gt;, it will be named differently if you aren't on a Mac.  Inside that directory there is a &lt;code&gt;js&lt;/code&gt; program you can run.  To make life easier, add &lt;code&gt;src/js/src/Darwin_DBG.OBJ&lt;/code&gt; to your path.  Now you should be able to just type &lt;code&gt;js&lt;/code&gt; and be at an interactive JavaScript interpreter, with &lt;code&gt;js&amp;gt;&lt;/code&gt; as the prompt:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ js
js&amp;gt; print("Hello, World")
Hello, World
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can also run &lt;code&gt;js -f my_awesome_script.js&lt;/code&gt; to run a script saved into a file.  I have created a quick hack of a textmate command to be able to a JavaScript file.  Click on the image below to see:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://farm4.static.flickr.com/3389/3522087661_4e151a4c39_o.png" title="Run JavaScript File Textmate Command"&gt;&lt;img src="http://farm4.static.flickr.com/3389/3522087661_c4a1978fe7.jpg" width="500" height="281" alt="Run JavaScript File Textmate Command" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So now let's write a little JavaScript.  First things first, open a file called &lt;code&gt;hello.js&lt;/code&gt; in Textmate and put this into it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;print("Hello, World!")
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you've created the command properly, you should see &lt;code&gt;Hello, World!&lt;/code&gt; printed out.  If you aren't using Textmate, then you will have to figure out how to get your editor to run the file.  Even if you can't do that, it's as simple as running &lt;code&gt;js -f hello.js&lt;/code&gt; from the command line.&lt;/p&gt;

&lt;p&gt;Now we can write some real code.  What we want to focus on doing is functional programming.  Most of the basic functions for functional programming aren't defined in JavaScript by default, but it's easy enough to write our own that handle the basic things.  Note that this kind of functional programming is going to be functional in that we are going to pass functions to and return functions from functions, a.k.a higher-order functions, but we aren't going to focus on another popular aspect of functional programming, which is immutable data.  Baby steps.  :)&lt;/p&gt;

&lt;p&gt;So the first thing we need is some kind of implementation of an iterator function, because we're not writing for loops.  Let's do something like Ruby's &lt;code&gt;each&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;function each(f, arr) {
  for(var i in arr) {
    f.apply(null, [arr[i]])
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;What this does is take a Function and an Array and applies the Function to each element of the Array.  To test this out, let's also add this line of code to test it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;each(print, [1,2,3,4,5])
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can see that we can pass the &lt;code&gt;print&lt;/code&gt; function to each and have it print the numbers from 1 to 5.  Ok, next up is &lt;code&gt;map&lt;/code&gt;, which takes a Function and an Array and returns a new Array which contains the result of applying the Function to each element of the Array.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;function map(f, arr) {
  var result = []
  each(function(e) {
    result.push(f.apply(null, [e]))
  }, arr)
  return result
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We can test that out with:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;print(map(function(e){
  return e * e
}, [1,2,3,4,5]))
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This time, we are passing an anonymous Function as the first argument to the &lt;code&gt;map&lt;/code&gt; Function.  This Function takes one value and multiplies it by itself, better know as &lt;code&gt;square&lt;/code&gt;.  Now for our last trick, we will do the functional programming equivalent of hello world, &lt;a href="http://en.wikipedia.org/wiki/Fibonacci_number"&gt;fibonacci&lt;/a&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;function fib(n) {
  if(n &amp;lt;= 1) {
    return n
  } else {
    return fib(n-1) + fib(n-2)
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We can test this with:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;each(print, map(fib, [1,2,3,4,5,6,7,8,9,10]))
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Here's the &lt;a href="http://gist.github.com/110072"&gt;entire code in one gist&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now that JavaScript is being viewed as a "real" language, it's even got it's on &lt;a href="http://jsconf2009.com"&gt;conference&lt;/a&gt;!  There's also some &lt;a href="https://developer.mozilla.org/en/SpiderMonkey#Community"&gt;IRC channels devoted to JavaScript&lt;/a&gt; as well and of course, &lt;a href="http://stackoverflow.com/questions/tagged/javascript"&gt;Stack Overflow&lt;/a&gt;.  Happy JavaScripting!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/paulbarry?a=UzrX0uRMuAQ:ZbzLd4-Or4o:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulbarry?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/paulbarry?a=UzrX0uRMuAQ:ZbzLd4-Or4o:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulbarry?i=UzrX0uRMuAQ:ZbzLd4-Or4o:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/paulbarry?a=UzrX0uRMuAQ:ZbzLd4-Or4o:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulbarry?i=UzrX0uRMuAQ:ZbzLd4-Or4o:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/paulbarry?a=UzrX0uRMuAQ:ZbzLd4-Or4o:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulbarry?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Mon, 11 May 2009 14:15:32 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:ccec2278-863f-4a2b-ab97-6354abf59721</guid>
      <author>mail@paulbarry.com (Paul Barry)</author>
      <link>http://feedproxy.google.com/~r/paulbarry/~3/UzrX0uRMuAQ/this-just-in-javascript-is-a-real-language</link>
      <category>Technology</category>
            <category>Javascript</category>
          <feedburner:origLink>http://paulbarry.com/articles/2009/05/11/this-just-in-javascript-is-a-real-language</feedburner:origLink></item>
    <item>
      <title>The Busy Rails Developer's Intro To Rake</title>
      <description>&lt;p&gt;This is just a quick 60 second intro to &lt;a href="http://rake.rubyforge.org"&gt;Rake&lt;/a&gt;.  If you are doing development with &lt;a href="http://rubyonrails.org"&gt;Ruby on Rails&lt;/a&gt;, you undoubtedly use Rake on a daily basis.  For example, you use &lt;code&gt;rake db:migrate&lt;/code&gt; to run your migrations or &lt;code&gt;rake test:units&lt;/code&gt; to run your unit tests.  But do you know how to write your own Rake tasks?  If you never have done that, you might hesitate to write a rake task instead thinking you ran just write a quick ruby script rather than take the time to figure out how to write a Rake task.&lt;/p&gt;

&lt;p&gt;So to create a rake task, in an existing Rails app, create a file called &lt;code&gt;lib/tasks/app.rake&lt;/code&gt;.  You can name it whatever you want as long as it ends in &lt;code&gt;.rake&lt;/code&gt;.  I'm choosing to use &lt;code&gt;app&lt;/code&gt; because we are going to write some app-specific tasks.  In the file, put this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;task :hello_world
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now from the command line you can run your task with &lt;code&gt;rake hello_world&lt;/code&gt;.  Nothing happens, but it runs.  Now let's have it print hello world:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;task :hello_world do
  puts "Hello, World!"
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now when you run your task, it prints "Hello, World!".  Let's add a description to our task to let people know what it does:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;desc "Prints 'Hello, World!'"
task :hello_world do
  puts "Hello, World!"
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now if you run &lt;code&gt;rake -T&lt;/code&gt;, you will see your hello_world task in the list of tasks.  &lt;code&gt;rake -T&lt;/code&gt; only shows tasks that have a description.  You can also run &lt;code&gt;rake -D hello_world&lt;/code&gt; to see the full description of the task.  You should give all of your tasks that you expect users to run from the command-line a description.&lt;/p&gt;

&lt;p&gt;Now a problem with our task is what happens if someone else wants to write a task named &lt;code&gt;hello_world&lt;/code&gt;?  Well, we would have a namespace problem.  So what we want to do is put all of our tasks into the &lt;code&gt;app&lt;/code&gt; namespace:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;namespace :app do
  desc "Prints 'Hello, World!'"
  task :hello_world do
    puts "Hello, World!"
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So now we can run our task as &lt;code&gt;rake app:hello_world&lt;/code&gt;.  &lt;/p&gt;

&lt;p&gt;So this is obviously not a real task. Let's say we want to know what the load path of our app looks like.  Easy, we'll just do this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;namespace :app do
  desc "Prints load path of this app"
  task :load_paths do
    Rails.configuration.load_paths.each do |p|
      puts p
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;When you try to run this rake tast, you will get this error:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;rake aborted!
uninitialized class variable @@configuration in Rails
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The problem is that by default, a rake task doesn't load the Rails environment.  It's easy to tell it to do that with this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;namespace :app do
  desc "Prints load path of this app"
  task :load_paths =&amp;gt; :environment do
    Rails.configuration.load_paths.each do |p|
      puts p
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;By saying &lt;code&gt;:load_path =&amp;gt; :environment&lt;/code&gt;, you are saying that the load_path task depends on the environment being loaded.  Or more specifically, you are saying "run the environment task before running this task".  There is a task called "environment", and it loads the Rails environment.  You won't see it under &lt;code&gt;rake -T&lt;/code&gt;, because it has no description because it is not a task you should run directly, only as a dependency of other tasks.  &lt;/p&gt;

&lt;p&gt;Now that we have the Rails environment loading, when you run the rake task, you will get the output you expect.  If you make your task depend on environment, you will also be able to access your models from within your task.  Now that you know the basics of Rake, you can easily get going making Rake tasks for your Rails app. &lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/paulbarry?a=3YrW2CdMtnE:8LwCxccnAD0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulbarry?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/paulbarry?a=3YrW2CdMtnE:8LwCxccnAD0:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulbarry?i=3YrW2CdMtnE:8LwCxccnAD0:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/paulbarry?a=3YrW2CdMtnE:8LwCxccnAD0:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulbarry?i=3YrW2CdMtnE:8LwCxccnAD0:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/paulbarry?a=3YrW2CdMtnE:8LwCxccnAD0:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulbarry?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Mon, 20 Apr 2009 22:02:25 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:f5f8c295-b9fe-480c-803f-a82ba38a2969</guid>
      <author>mail@paulbarry.com (Paul Barry)</author>
      <link>http://feedproxy.google.com/~r/paulbarry/~3/3YrW2CdMtnE/the-busy-rails-developers-intro-to-rake</link>
      <category>Technology</category>
            <category>Rails</category>
      <category>Rake</category>
      <category>Ruby</category>
          <feedburner:origLink>http://paulbarry.com/articles/2009/04/20/the-busy-rails-developers-intro-to-rake</feedburner:origLink></item>
    <item>
      <title>Implicit Conversions: Scala's Type Safe Answer To Ruby's Open Class</title>
      <description>&lt;p&gt;Let's say that you are writing an application that squares things often, so you would like to be able to do this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt; 4.squared
=&amp;gt; 16
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In Ruby, that's easy-peasy:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Integer
  def squared
    self * self
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Wham.  Done.  Open it right up, shove your method in there and you are bending the language to your will.  But what if you couldn't modify existing classes?  Maybe you would do this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class IntegerWrapper
  def initialize(value)
    @value = value
  end
  def squared
    @value * @value
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Cool.  Now you haven't modified Integer, but you get the same effect.  So you just use it like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt; IntegerWrapper.new(4).squared
=&amp;gt; 16
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;WOAH!  WTF?  That is a lot of extra syntax.  Having all to call wrapper classes like this really makes it too verbose.  So now we shift gears into Scala mode:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;scala&amp;gt; class IntegerWrapper(val value : Int) { def squared = value * value }
defined class IntegerWrapper

scala&amp;gt; new IntegerWrapper(4).squared
res0: Int = 16
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As you can see on the first line, we define the same IntegerWrapper class.  Then we use it just the same way we do in Ruby.  But now we throw in an implicit conversion to make the syntactic magic happen:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;scala&amp;gt; implicit def wrapInt(i:Int) = new IntegerWrapper(i)
wrapInt: (Int)IntegerWrapper

scala&amp;gt; 4.squared
res1: Int = 16
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;implicit def&lt;/code&gt; defines an implicit conversion from an Int to an IntegerWrapper.  This is our way to tell scala that if we try to call &lt;code&gt;squared&lt;/code&gt; on an Int, use this function to convert the Int to an IntegerWrapper for me.  Now as you can see, we can call &lt;code&gt;squared&lt;/code&gt; on what appears to be a Int, and get the same syntactic advantage of adding methods to existing classes, without really modifying existing classes.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/paulbarry?a=NHbhtxsoLkM:numymalnTIY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulbarry?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/paulbarry?a=NHbhtxsoLkM:numymalnTIY:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulbarry?i=NHbhtxsoLkM:numymalnTIY:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/paulbarry?a=NHbhtxsoLkM:numymalnTIY:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulbarry?i=NHbhtxsoLkM:numymalnTIY:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/paulbarry?a=NHbhtxsoLkM:numymalnTIY:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulbarry?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Fri, 17 Apr 2009 00:14:10 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:2804679d-0fc6-4033-99e8-baa332cd5ff2</guid>
      <author>mail@paulbarry.com (Paul Barry)</author>
      <link>http://feedproxy.google.com/~r/paulbarry/~3/NHbhtxsoLkM/implicit-conversions-scalas-type-safe-answer-to-rubys-open-class</link>
      <category>Technology</category>
            <category>Ruby</category>
      <category>Scala</category>
          <feedburner:origLink>http://paulbarry.com/articles/2009/04/17/implicit-conversions-scalas-type-safe-answer-to-rubys-open-class</feedburner:origLink></item>
    <item>
      <title>"Write Everything Twice" and "Because What If I Need It Later"</title>
      <description>&lt;p&gt;Programmers are concerned with the number of lines of code they write in their programs.  There is this idea that the fewer lines of code you write the better.  This is a hold over from the days of tiny hard drives measured in Kilobytes, a far cry from today's standard of measuring hard drives in hundreds of Gigabytes or even Terabytes.  We no longer need to convolute our programs with abstractions simply to save on the number of lines.  This is why I'm advocating the "Write Everything Twice", or the WET principle.  The next time you have a method or function in your code that does something and you want to use that function in another place in your code, but have it function slightly different, just simply copy and paste the original method and alter the copy.  You've heard it said time and time again.  Disk space is cheap, which in turn means lines of code are cheap.&lt;/p&gt;

&lt;p&gt;Another closely related principle is "Because What If I Need It Later", or BWIINIL (pronounced ba-WIN-null).  Many programmers are lazy in that when they develop an application, they sometimes only write the code for that features that they think they need at that moment.  What they don't realize is that there is significant mental cost of switching back into the context of that part of the code a later date.  Any time you are writing code you should say to yourself "What else might I need later?".  &lt;/p&gt;

&lt;p&gt;One particularly good way to apply the BWIINIL principle is to get the book &lt;a href="http://www.amazon.com/Design-Patterns-Object-Oriented-Addison-Wesley-Professional/dp/0201633612/ref=sr_11_1?ie=UTF8&amp;amp;qid=1238586549&amp;amp;sr=11-1"&gt;Design Patters: Elements of Reusable Object-Oriented Software&lt;/a&gt;, which is more commonly know as the &lt;a href="http://en.wikipedia.org/wiki/Design_Patterns_%28book%29"&gt;Gang of Four&lt;/a&gt; book, and attempt to apply every pattern in the book to every method you write.  This will allow you to insert layers upon layers of abstraction and indirection that may seem like overkill at first, but will come in handy some day when you are adding new features.&lt;/p&gt;

&lt;p&gt;Here's an &lt;a href="http://uncyclopedia.wikia.com/wiki/Java#public_class_ExampleCode_extends_Java_throws_EveryExceptionUnderTheSUN_.7B"&gt;excellent real word example taken from Uncyclopedia&lt;/a&gt;.  We'll all familiar with this trivial implementation of HelloWorld in Java:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This kind of code is often included in books about Java, which is understandably watered down for programmers first learning Java.  But if you really want to graduate to that next level and write a professional, enterprise-ready implementation of Hello World, you need this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;interface Printer {
    void print(Message message);
}

class Message {
    private String message;

    public Message(String message) {
        this.message = message;
    }

    public void print(Printer printer) {
        printer.print(this);
    }

    public String toString() {
        return message;
    }
}

abstract class AbstractPrinterFactory {
    public static AbstractPrinterFactory getFactory() {
        return new SystemOutPrinterFactory();
    }

    public abstract Printer getPrinter();
}

class SystemOutPrinterFactory extends AbstractPrinterFactory {
    public Printer getPrinter() {
        return new SystemOutPrinter();
    }
}

class SystemOutPrinter implements Printer {
    public void print(Message message) {
        System.out.println(message);
    }
}

class HelloWorld {
    public static void main(String[] args) {
        Message message = new Message("Hello, World!");
        AbstractPrinterFactory factory = AbstractPrinterFactory.getFactory();
        Printer printer = factory.getPrinter();
        message.print(printer);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Also make sure to include UML class diagrams that shows how these components interact.  Once you learn to embrace the WET and BWIINIL principles and apply them to your everyday coding, I'm sure you'll quickly see an increase in the quantity...er, I mean....quality of your code.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/paulbarry?a=hsFaQXJevZY:xGFlbr9K7gs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulbarry?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/paulbarry?a=hsFaQXJevZY:xGFlbr9K7gs:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulbarry?i=hsFaQXJevZY:xGFlbr9K7gs:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/paulbarry?a=hsFaQXJevZY:xGFlbr9K7gs:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulbarry?i=hsFaQXJevZY:xGFlbr9K7gs:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/paulbarry?a=hsFaQXJevZY:xGFlbr9K7gs:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulbarry?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Wed, 01 Apr 2009 08:25:49 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:0beef3a0-fdb1-4e75-9386-d3e776697991</guid>
      <author>mail@paulbarry.com (Paul Barry)</author>
      <link>http://feedproxy.google.com/~r/paulbarry/~3/hsFaQXJevZY/write-everything-twice-and-because-what-if-i-need-it-later</link>
      <category>Technology</category>
            <category>Java</category>
      <category>AprilFools</category>
          <feedburner:origLink>http://paulbarry.com/articles/2009/04/01/write-everything-twice-and-because-what-if-i-need-it-later</feedburner:origLink></item>
    <item>
      <title>Message to Apple: Get Your Act Together</title>
      <description>&lt;p&gt;This will be a short post, because &lt;a href="http://zdziarski.com/projects/amberalert/"&gt;Jonathan Zdziarski has said it much better than I could&lt;/a&gt;, but the bottom line is that Apple needs to get their act together with the App Store.  Coming of this heels of the &lt;a href="http://www.touchpodium.com/2008/08/09/iphone-programmers-upset-about-apples-nda/"&gt;NDA debacle&lt;/a&gt;, this is just ridiculous.  Take the time to read &lt;a href="http://zdziarski.com/projects/amberalert/email.txt"&gt;Johathan's email to Apple&lt;/a&gt; and you'll see what I mean.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/paulbarry?a=VWyLB-DZCUo:ZAR08Ycn0IE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulbarry?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/paulbarry?a=VWyLB-DZCUo:ZAR08Ycn0IE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulbarry?i=VWyLB-DZCUo:ZAR08Ycn0IE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/paulbarry?a=VWyLB-DZCUo:ZAR08Ycn0IE:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulbarry?i=VWyLB-DZCUo:ZAR08Ycn0IE:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/paulbarry?a=VWyLB-DZCUo:ZAR08Ycn0IE:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulbarry?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Tue, 10 Mar 2009 13:14:48 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:1dbbdede-7df2-479e-9f3c-cc20d18e158a</guid>
      <author>mail@paulbarry.com (Paul Barry)</author>
      <link>http://feedproxy.google.com/~r/paulbarry/~3/VWyLB-DZCUo/message-to-apple-get-your-act-together</link>
      <category>Technology</category>
            <category>Apple</category>
          <feedburner:origLink>http://paulbarry.com/articles/2009/03/10/message-to-apple-get-your-act-together</feedburner:origLink></item>
    <item>
      <title>Keyword Arguments and the Case for Literal Syntax for Hashes</title>
      <description>&lt;p&gt;I've studied various programming languages and one feature I've grown to love is keyword arguments.  Here's &lt;a href="http://lib.store.yahoo.net/lib/paulgraham/bbnexcerpts.txt"&gt;Paul Graham's take on keyword arguments&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Rtml even depended heavily on keyword parameters, which up to that time I had always considered one of the more dubious features of
  Common Lisp.  Because of the way Web-based software gets released, you have to design the software so that it's easy to change.  And
  Rtml itself had to be easy to change, just like any other part of the software.  Most of the operators in Rtml were designed to take
  keyword parameters, and what a help that turned out to be.  If I wanted to add another dimension to the behavior of one of the
  operators, I could just add a new keyword parameter, and everyone's existing templates would continue to work.  A few of the Rtml
  operators didn't take keyword parameters, because I didn't think I'd ever need to change them, and almost every one I ended up
  kicking myself about later.  If I could go back and start over from scratch, one of the things I'd change would be that I'd make every
  Rtml operator take keyword parameters.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In order to have keyword arguments in your language, what you only really need is Hash as a first class data type with a literal syntax.  This is a feature that all modern programming languages should have.  One reason why is it makes the feature of keyword arguments trivial to implement and use.  If your language has literal syntax for Hashes, you don't really need much as in the terms of syntax of the language to have support for keyword arguments. &lt;a href="http://python.org"&gt;Python&lt;/a&gt; has a little extra &lt;a href="http://docs.python.org/tutorial/controlflow.html#keyword-arguments"&gt;built-in support for keyword arguments&lt;/a&gt;.  In &lt;a href="http://www.ruby-lang.org/en/"&gt;Ruby&lt;/a&gt;, &lt;a href="http://www.lukeredpath.co.uk/blog/using-ruby-hashes-as-keyword-arguments-with-easy-defaults.html"&gt;hashes are used as keyword arguments to methods pretty easily&lt;/a&gt;.  To clarify, when I say Hash, I'm talking about the data structure that is referred to as a &lt;a href="http://docs.python.org/library/stdtypes.html#typesmapping"&gt;Dictionary&lt;/a&gt; in Python, &lt;a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSDictionary_Class/Reference/Reference.html"&gt;NSDictionary&lt;/a&gt; in &lt;a href="http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC/Introduction/chapter_1_section_1.html"&gt;Objective-C&lt;/a&gt;, a &lt;a href="http://www.ruby-doc.org/core/classes/Hash.html"&gt;Hash&lt;/a&gt; in Ruby, or a &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/Map.html"&gt;Map&lt;/a&gt; in &lt;a href="http://java.sun.com/"&gt;Java&lt;/a&gt;.  &lt;a href="http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC/Introduction/chapter_1_section_1.html"&gt;Objective-C&lt;/a&gt; does not have a literal syntax for Hashes, neither does Java, and I'll show why not having a literal syntax for Hashes leads to not having keyword arguments.  &lt;/p&gt;

&lt;p&gt;Objective-C does not have keyword arguments, but what it does have is named arguments.  I'm not sure if keyword arguments and named arguments are the official correct terms, but I like those terms and I'm going to define specifically what I mean by each.  Named arguments in Objective-C mean that each and every argument to a method call must have a name. In a language like Java which doesn't have named arguments, you could see something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Date iWeeksFromNow = now.add(0, 0, (i*7), 0, 0, 0);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It's hard to tell what this method does, because you have to know what the position of each argument means.  In Objective-C, it might look like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;NSCalendarDate *iWeeksFromNow = [now dateByAddingYears:0 
                                                months:0
                                                  days:(i*7)
                                                 hours:0
                                               minutes:0
                                               seconds:0];
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This call is self-documenting, because you can now easily determine what each parameter means.  Although this is an improvement, it still has some flaws.  First, I still must know the correct order of the arguments.  For example, this won't work:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;NSCalendarDate *iWeeksFromNow = [now dateByAddingSeconds:0 
                                                 minutes:0
                                                   hours:0
                                                    days:(i*7)
                                                  months:0
                                                   years:0];
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;More egregiously, you can't omit the arguments for which you would like to supply no value or have the default value used.  This is why we see all these parameters with a value of 0 being passed in.  You could fix this API in Objective-C by defining separate method to add each unit, so something like this would work:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;NSCalendarDate *iWeeksFromNow = [now dateByAddingDays:(i*7)];
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But what if you want to specify values for two of the arguments?  You end up with a huge explosion of methods in the API.  This also leads to another big problem, which is what if you want add another value that could be passed in?  For example, let's say we wanted to by able to pass in weeks, which is exactly what we are trying to do in this example.  We could modify the API and call the code like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;NSCalendarDate *iWeeksFromNow = [now dateByAddingYears:0 
                                                months:0
                                                  days:0
                                                 weeks:i
                                                 hours:0
                                               minutes:0
                                               seconds:0];
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But that means we have to go change all the code that doesn't have weeks in the method call to include it.  Depending on how much code you have calling the API, this could be a nightmare.  In this case, where we are talking about a core method of Cocoa, so I would suspect that Apple is unlikely to ever change this method for that reason.  This is why APIs developed in a language without keyword arguments sometimes stagnate over time, for fear of breaking backward compatibility.  If this were a keyword argument method, support for accepting weeks as an argument could easily be added without breaking any existing code.&lt;/p&gt;

&lt;p&gt;Keyword arguments, as typically implemented in Ruby or Python, are optional and unordered.  A method like this one in a Ruby API might look like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;iWeeksFromNowNextYear = now.add(:weeks =&amp;gt; i, :years =&amp;gt; 1)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is a very clean way to design an API.  It can easily be extended in the future when more arguments need to be added.  I don't need to pass in values for parameters I don't care about.  It is clean and easy to use as the caller of the API.  Techincally, this exact kind of thing is possible in Java and Objective-C.  The NSCalendateDate could have a method called add that takes an NSDictionary, which might make calling code look like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;NSCalendarDate *iWeeksFromNowNextYear = [now dateByAdding: 
  [NSDictionary dictionaryWithObjectsAndKeys:
    [[NSNumber alloc] initWithInt:i], @"weeks",
    [[NSNumber alloc] initWithInt:1], @"years",
    nil]];
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But as you can see, there is too much syntactical noise for this kind of thing to every become idiomatic, which goes back to my original point, which is that having a literal syntax for Hashes is a huge win for the syntax of a language.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/paulbarry?a=MuS6jh9FNYI:AmoyhwWWUss:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulbarry?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/paulbarry?a=MuS6jh9FNYI:AmoyhwWWUss:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulbarry?i=MuS6jh9FNYI:AmoyhwWWUss:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/paulbarry?a=MuS6jh9FNYI:AmoyhwWWUss:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulbarry?i=MuS6jh9FNYI:AmoyhwWWUss:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/paulbarry?a=MuS6jh9FNYI:AmoyhwWWUss:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/paulbarry?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Sun, 08 Mar 2009 04:22:40 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:0ab5a414-fff4-4985-a0b3-3657da98de76</guid>
      <author>mail@paulbarry.com (Paul Barry)</author>
      <link>http://feedproxy.google.com/~r/paulbarry/~3/MuS6jh9FNYI/keyword-arguments-and-the-case-for-literal-syntax-for-hashes</link>
      <category>Technology</category>
            <category>Python</category>
      <category>ObjectiveC</category>
      <category>Ruby</category>
          <feedburner:origLink>http://paulbarry.com/articles/2009/03/08/keyword-arguments-and-the-case-for-literal-syntax-for-hashes</feedburner:origLink></item>
      </channel>
</rss>
