<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <title>Alloy Code - Home</title>
  <id>tag:www.alloycode.com,2010:mephisto/</id>
  <generator uri="http://mephistoblog.com" version="0.7.3">Mephisto Noh-Varr</generator>
  <link href="http://www.alloycode.com/feed/atom.xml" rel="self" type="application/atom+xml"/>
  <link href="http://www.alloycode.com/" rel="alternate" type="text/html"/>
  <updated>2010-07-28T20:03:33Z</updated>
  <entry xml:base="http://www.alloycode.com/">
    <author>
      <name>scott</name>
    </author>
    <id>tag:www.alloycode.com,2010-07-28:109</id>
    <published>2010-07-28T19:39:00Z</published>
    <updated>2010-07-28T20:03:33Z</updated>
    <category term="Programming"/>
    <link href="http://www.alloycode.com/2010/7/28/implementing-your-own-caching-layer" rel="alternate" type="text/html"/>
    <title>Implementing Your Own Caching Layer</title>
<content type="html">
            &lt;p&gt;I recently had to deal with performance problems in a very large application with a considerable number of SQL queries (i.e. object.find_by_sql or object.paginate_by_sql).  And while we can argue whether or not using sql directly in an ActiveRecord context is good, some of these were complex enough (think sum operations, etc) that I didn't want to go and rewrite them as ActiveRecord.  And, given a table that is being changed constantly by a crawler, the MySQL query cache wasn't an option*.&lt;/p&gt;
&lt;p&gt;So I started things off, as I do so often, by talking to a buddy and discussing the issues.  Oddly, he argued against using the built-in Rails caching tools and for doing it myself.  Now this is unusual to say the least.  Normally he always argues for the built-in frameworks but he and I have had issues in the &lt;a href=&quot;http://edufire.com/&quot;&gt;past&lt;/a&gt; around caching and, in particular, cache expiration.  So after that discussion, I came to a conceptual approach of this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use an ActiveRecord model to start the data&lt;/li&gt;
&lt;li&gt;Use created_at as a tool to manage the cache expiration &lt;/li&gt;
&lt;li&gt;Serialize the data after fetch to store it away&lt;/li&gt;
&lt;li&gt;Write a get_latest method inside the model to test whether or not to fetch the data from the cache or the source&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The first real problem came from needing to deal with not just straight ActiveRecord (AR) objects but will_paginate collections that wrap around the AR objects.  Here's something brilliant about ActiveRecord, irrelevant for me, but brilliant:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;serialize :data&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you put that at the top of your AR model file then that element of the model will be automatically serialized IN and OUT of the database.  Outstanding -- but it kept failing for me.  Why?  Because I had will_paginate collections over the top of the AR objects.  Oy.  So now that that wasn't working, at all, I turned to Google and I did some research via a great &lt;a href=&quot;http://www.skorks.com/2010/04/serializing-and-deserializing-objects-with-ruby/&quot;&gt;Skorks article&lt;/a&gt;.  Apparently you can serialize in Rails, automatically, via YAML or by using the marshal command.  The benefit to using marshal is its binary which means its &lt;strong&gt;smokingly&lt;/strong&gt; fast.  Or at least as fast as anything in Rails is.&lt;/p&gt;
&lt;p&gt;So I tried wrapping my data element like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;Marshal.dump(res)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;to store it (res was the result of the database operation).&lt;/p&gt;
&lt;p&gt;and&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;Marshal.load(cache_result.data)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And no matter what I did, it just plain failed.  So the normal walk away from the computer and ponder deeply while I wander the halls of my home looking contemplatively** around while I cogitate made me realize this: &lt;strong&gt;IT IS BINARY BUTTHEAD!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;MySQL doesn't store binary data by default so this would require a migration change and a db:migrate:redo.  So a quick dash back to the migration and I ended up with this:&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;﻿class CreateQueryResultsCaches &amp;lt; ActiveRecord::Migration
  def self.up
    create_table :query_results_caches do |t|
      t.string     :q_hash
      t.text       :q
      t.column :data, :binary, :limit =&amp;gt; 10.megabyte
      t.timestamps
    end
    add_index :query_results_caches, :q_hash
  end
  def self.down
    remove_index :query_results_caches, :q_hash
    drop_table :query_results_caches
  end
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;a href=&quot;http://stackoverflow.com/questions/579536/how-do-you-get-rails-to-use-the-longblob-column-in-mysql&quot;&gt;Useful reference on creating blobs via migrations.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And that actually worked!  If you notice the q_hash column, you may be wondering what that is.  Given that my queries are long, its faster to hash the query and then use that hash for the lookup instead of trying to look up on a query that's 500 bytes or longer.  Now there's only a few more bits to share.&lt;/p&gt;
&lt;p&gt;The routine which evaluates the cache result:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;﻿  def self.get_latest(q_hash)
    latest = self.find(:first, :conditions =&amp;gt; {:q_hash =&amp;gt; q_hash}, :order =&amp;gt; &amp;quot;created_at DESC&amp;quot;)
    # if within last 10 minutes then return else run the real query and store results
    if latest &amp;amp;amp;&amp;amp;amp; latest.created_at.between?(20.minutes.ago,Time.now)
      return latest
    else
      nil
    end 
  end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The two methods on the QueryCacheResult object for fetching from the cache and/or populating the cache with and without pagination:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;﻿  def self.cache_it_or_create_it_by_sql_with_pagination(obj,q,page)
    if page
     q_hash = Digest::SHA1.hexdigest(q + page).to_s
    else
      q_hash = Digest::SHA1.hexdigest(q).to_s
    end    
    cache_result = self.get_latest(q_hash)
    if cache_result.nil?
      res = obj.paginate_by_sql(q, :page =&amp;gt; page, :per_page =&amp;gt; 40)
      QueryResultsCache.create(:q_hash =&amp;gt; q_hash, :data =&amp;gt; Marshal.dump(res), :q =&amp;gt; q)
    else
      res = Marshal.load(cache_result.data)
    end
    res
  end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And...&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;  def self.cache_it_or_create_it_by_sql(obj,q)
    q_hash = Digest::SHA1.hexdigest(q).to_s
    cache_result = self.get_latest(q_hash)
    if cache_result.nil?
      res = obj.find_by_sql(q)
      QueryResultsCache.create(:q_hash =&amp;gt; q_hash, :data =&amp;gt; Marshal.dump(res), :q =&amp;gt; q)
    else
      res = Marshal.load(cache_result.data)
    end
    res
  end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As a final note, here's an example how this is used from a controller:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;@apps = QueryResultsCache.cache_it_or_create_it_by_sql_with_pagination(App,q,params[:page])&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Clearly there's more that can be done here but when you find that the built-in Rails caching mechanisms aren't working for you --or-- you feel that stepping out of the framework will teach you something, implementing your own caching approach isn't all that difficult.  Learn to use one of the serialization tools and you're off to the races!&lt;/p&gt;
&lt;p&gt;*As an aside, I'd point out that the MySQL query cache just ain't all that great but that's another story for another day.&lt;/p&gt;
&lt;p&gt;**Ok I went to the can.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.alloycode.com/">
    <author>
      <name>scott</name>
    </author>
    <id>tag:www.alloycode.com,2010-07-27:106</id>
    <published>2010-07-27T18:13:00Z</published>
    <updated>2010-07-27T18:19:35Z</updated>
    <category term="Programming"/>
    <link href="http://www.alloycode.com/2010/7/27/in-praise-of-rails-machine" rel="alternate" type="text/html"/>
    <title>In Praise of Rails Machine</title>
<content type="html">
            &lt;p&gt;It isn't often that you can pull a near 48 hour day dealing with deploying a new code base into production and come out of it with not only a smile but a blog post praising your hosting company.  I just finished such an endeavor (ordeal??) and it was the typical sort of experience where you need to do constant server tuning, rebooting to get around load issues, issues with crawlers flooding your site and thus fine grained ActiveRecord optimizations, etc.&lt;/p&gt;
&lt;p&gt;Now the site in question is hosted at &lt;a href=&quot;http://www.railsmachine.com/&quot;&gt;Rails Machine&lt;/a&gt; and, to paraphrase, I come not to bury them but to &lt;b&gt;praise&lt;/b&gt; them.  During the course of this project, Rails Machine has been:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Nothing but professional&lt;/li&gt;
&lt;li&gt;They turned me onto their new &lt;a href=&quot;http://github.com/railsmachine/moonshine&quot;&gt;Moonshine&lt;/a&gt; project which makes server tuning magnificently easy (imagine setting your Passenger configuration options from within Ruby code)&lt;/li&gt;
&lt;li&gt;They didn't bat an eye at multiple reboots even late on a Saturday night&lt;/li&gt;
&lt;li&gt;When we had major problems, they replaced our server without being asked; all I had to do was point out that the issue had happened twice and *whammo* new server&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And then, to add icing to a delicious cake, I just got this email:&lt;/p&gt;
&lt;p&gt;Hi Scott -&lt;/p&gt;
&lt;p&gt;I just wanted to check in and see if you were able to get this to work. Please let me know if you need any further help!&lt;/p&gt;
&lt;p&gt;--Ahesan&lt;/p&gt;
&lt;p&gt;Ahesan, you magnificent bastard!  Thank you for sending this.  I can't tell you how good it made me feel to get this at 3:24 am.&lt;/p&gt;
&lt;p&gt;So here's my personal bottom line for hosting Rails apps.  If you need quality, reliable hosting for Rails with outstanding support then you need to run, not walk and sign up with them.  I won't tell you its cheap -- it isn't but Rails Machine knows their stuff and does an outstanding job.  Overall I've been more impressed with Rails Machine than any other Rails hosting company I've worked with.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note 1&lt;/strong&gt;: I've been a Rails Machine customer for over 3 years now and they've kept every one of the Rails apps I've been a lead developer on running like a champ but their customer service over this past weekend was well over the top.  Thanks guys.  Appreciated.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note 2&lt;/strong&gt;: Since I wrote this up in the bowels of a Sunday night 3 am debugging session, I've since had follow up from others at Rails machine including Josh and Will.  Both took the time to go above and beyond just as Ahesan did.  Thanks guys.  Will in particular cobbled together an excellent suggestion showing how to use MoonShine to do something not explicitly supported yet﻿&lt;/p&gt;
&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.alloycode.com/">
    <author>
      <name>jared</name>
    </author>
    <id>tag:www.alloycode.com,2010-06-26:96</id>
    <published>2010-06-26T21:18:00Z</published>
    <updated>2010-06-27T02:11:32Z</updated>
    <category term="Programming"/>
    <link href="http://www.alloycode.com/2010/6/26/automatic-color-coding-for-script-console-and-irb" rel="alternate" type="text/html"/>
    <title>Automatic Color Coding for script/console and irb</title>
<content type="html">
            &lt;p&gt;A friend recently turned me onto Awesome Print, a pp replacement: &lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://github.com/michaeldv/awesome_print&quot;&gt; Michael Dvorkin's awesome_print on GitHub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What Awesome Print does is automatically color code your script/console and irb output when you use it as a pp replacement.  What gets even more trick though, nay awesome, is triggering it automatically so all output is color coded.  Here's the magic.&lt;/p&gt;

&lt;p&gt;Edit your .irbrc file in ~ and add the following lines:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;begin
  require &amp;quot;ap&amp;quot;
  IRB::Irb.class_eval do
    def output_value
      ap @context.last_value
    end
  end
rescue LoadError =&amp;gt; e
  puts &amp;quot;ap gem not found.  Try typing 'gem install awesome_print' to get super-fancy output.&amp;quot;
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You may also need to add this line at the top of the file:&lt;br /&gt;
&lt;code&gt;&lt;pre&gt;require 'rubygems'&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;
if your .irbrc file does not already contain it.  Mine did, which is why I omitted it above.&lt;/p&gt;

&lt;p&gt;Now the results of anything in script/console will have Awesome Print used automatically:&lt;/p&gt;
&lt;img src=&quot;http://www.alloycode.com/assets/2010/6/26/Screen_shot_2010-06-26_at_5.15.33_PM.png&quot; height=&quot;361&quot; alt=&quot;awesome_print output&quot; width=&quot;571&quot; /&gt;
          </content>  </entry>
  <entry xml:base="http://www.alloycode.com/">
    <author>
      <name>jared</name>
    </author>
    <id>tag:www.alloycode.com,2010-05-08:94</id>
    <published>2010-05-08T19:41:00Z</published>
    <updated>2010-05-08T19:44:57Z</updated>
    <category term="Programming"/>
    <link href="http://www.alloycode.com/2010/5/8/activerecord-vs-core-data" rel="alternate" type="text/html"/>
    <title>ActiveRecord vs. Core Data</title>
<content type="html">
            &lt;p&gt;With the release of &lt;a href=&quot;http://alloycode.com/2010/4/19/arrgeebee&quot;&gt;ArrGeeBee&lt;/a&gt; and the development of my first iPad application*, I recently found myself delving into a number of Objective-C technologies, including &lt;a href=&quot;http://developer.apple.com/macosx/coredata.html&quot;&gt;Core Data&lt;/a&gt;.  Given that I'm coming from a Ruby / Rails background, I found this really, really interesting since both Rails's ActiveRecord and CoreData are oriented around Object Relational Mappers (ORMs).  Let's consider a simple model in Ruby called Event that is backed by ActiveRecord:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;class Event &amp;lt; ActiveRecord::Base

end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Here's a simple example of using the an ActiveRecord finder to return all entries, sorted by creation date descending (using the newer style syntax): &lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;events = Event.all(:order =&amp;gt; &amp;quot;created_at DESC&amp;quot;)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;When you're learning a new platform, one of the first things you do is look at the new platform from the context of the old so my concern was how to write this in Objective C using its native ORM.  &lt;/p&gt;

&lt;p&gt;The basic structure of retrieving data from Core Data is bundled in a fetch request which specifies an entity from the Core Data stack (the Event), a predicate to limit the number of results returned (similar to the &lt;code&gt;:conditions =&gt; {...}&lt;/code&gt; hash in ActiveRecord), and a sort descriptor to place them into some sort of order.  Since my example above omitted any conditions, I'll do the same here and leave out the predicate for this request.&lt;/p&gt;

Here's what I came up with:

&lt;pre&gt;&lt;code class=&quot;objc&quot;&gt;// Create the Fetch request and scope it to the entity we're retrieving (in this case, an event).
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@&amp;quot;Event&amp;quot; inManagedObjectContext:managedObjectContext];
[request setEntity:entity];

// Create a sort descriptor to order these events by their creation date in descending order.
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@&amp;quot;creationDate&amp;quot; ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];
[sortDescriptors release];
[sortDescriptor release];

// Set up a pointer to hold an error, in case the fetch request fails.
NSError *error;
NSMutableArray *mutableFetchResults = [[managedObjectContext executeFetchRequest:request error:&amp;amp;error] mutableCopy];
if (mutableFetchResults == nil) {
  // Some amount of error handling here.
}

// Finally, assign the result set into a controller variable called eventsArray, then clean up the last of the objects we were holding in memory.
[self setEventsArray:mutableFetchResults];
[mutableFetchResults release];
[request release];&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That's about a 1:20 ratio of lines of code and while its never all about lines of code, this one example very dramatically spelled out to me a key difference between Objective C and Ruby and pointed out to me just how easy Ruby makes things.  I think, all too often, we overlook the important role that metaprogramming has played in the Ruby language, and in Ruby's most popular frameworks.  Things like object introspection have freed us from worrying about a lot of the little details around everyday tasks, such as retrieving records from a data store.&lt;/p&gt;

&lt;p&gt;Now, that said, I've got my first app in the &lt;a href=&quot;http://itunes.apple.com/us/app/arrgeebee/id368258824?mt=8&quot;&gt;App Store&lt;/a&gt;, I've bought my first iPad and I'm barreling down this path.  Onward!&lt;/p&gt;

&lt;p&gt;* Coming real soon now.  Interested?  Drop an email to &lt;a href=&quot;mailto:info@alloycode.com&quot;&gt;info@alloycode.com&lt;/a&gt; and I'll drop you on a mailing list.  All I can tell you about it for now is that ... (Actually skip it -- just sign up for the mailing list.)&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.alloycode.com/">
    <author>
      <name>jared</name>
    </author>
    <id>tag:www.alloycode.com,2010-04-19:91</id>
    <published>2010-04-19T22:10:00Z</published>
    <updated>2010-04-23T03:48:57Z</updated>
    <category term="iPhone"/>
    <category term="Portfolio"/>
    <category term="Projects"/>
    <link href="http://www.alloycode.com/2010/4/19/arrgeebee" rel="alternate" type="text/html"/>
    <title>ArrGeeBee</title>
<content type="html">
            &lt;a href=&quot;http://alloycode.com/assets/2010/4/19/arrgeebee.png&quot;&gt;&lt;img src=&quot;http://alloycode.com/assets/2010/4/19/arrgeebee.png&quot; height=&quot;160&quot; alt=&quot;ArrGeeBee Gameplay&quot; width=&quot;240&quot; /&gt;&lt;/a&gt;&lt;p&gt;&lt;strong&gt;ArrGeeBee&lt;/strong&gt; is an additive color mixing &amp;amp; matching game for the iPhone/iPod Touch from AlloyCode. Your goal is to move red, green and blue sliders to try and match a reference color square in as little time as possible.  The game features three difficulty levels: Casual, Serious and Nightmare.  On Casual difficulty, each slider can be set to one of ten possible color values, resulting in 1,000 possible color combinations to match.&lt;/p&gt;

&lt;p&gt;On Serious and Nightmare difficulty, the number of settings increases, resulting in 1,000,000 and 16,581,375 possible color combinations.&lt;/p&gt;

&lt;p&gt;The game ends one of two ways: if you successfully match the color, the game will display a winning message and the current top scores for the difficulty level.  No matter how certain you are that you've matched the colors exactly, you haven't won the game until you get that winner screen to appear.&lt;/p&gt;

&lt;p&gt;The other way the game can end is if you run out of time.  You've got 5 minutes to make a match, and if you run out of time, the game will end and show you the solution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ArrGeeBee&lt;/strong&gt; is available on the &lt;a href=&quot;http://itunes.apple.com/us/app/arrgeebee/id368258824?mt=8&quot;&gt;iTunes App Store&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For support, contact &lt;a href=&quot;mailto:info@alloycode.com&quot;&gt;info@alloycode.com&lt;/a&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.alloycode.com/">
    <author>
      <name>jared</name>
    </author>
    <id>tag:www.alloycode.com,2009-08-21:87</id>
    <published>2009-08-21T23:52:00Z</published>
    <updated>2010-04-07T14:50:21Z</updated>
    <link href="http://www.alloycode.com/2009/8/21/yet-another-theory-on-_why-s-disappearance" rel="alternate" type="text/html"/>
    <title>Yet Another Theory on _why's Disappearance</title>
<content type="html">
            &lt;p&gt;Since everyone seems to have their own theory on _why's disappearance, I figured I may as well add mine to the pile.&lt;/p&gt;

&lt;p&gt;While I doubt the authenticity of the &quot;whoiswhytheluckystiff&quot; blog site, I think that the current plethora of &lt;a href=&quot;http://www.reddit.com/search?q=anonymous+blogger&amp;t=year&quot;&gt;recent stories&lt;/a&gt; on the death of online anonymity may have played a role.  While _why may not have yet been outed, he may have thought it prudent to terminate his online identity before it could be traced by to his real life person.&lt;/p&gt;

&lt;p&gt;Wherever he's gone, though, I'd like to add my voice to the chorus of people who appreciate all his contributions to the Ruby world.&lt;/p&gt;

&lt;p&gt;Thank you, _why!&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.alloycode.com/">
    <author>
      <name>jared</name>
    </author>
    <id>tag:www.alloycode.com,2009-06-19:84</id>
    <published>2009-06-19T13:58:00Z</published>
    <updated>2010-04-07T14:50:30Z</updated>
    <category term="Programming"/>
    <link href="http://www.alloycode.com/2009/6/19/fun-with-rmagick" rel="alternate" type="text/html"/>
    <title>Fun with RMagick</title>
<content type="html">
            &lt;p&gt;As an avid photographer, I spend a lot of time tweaking my images to share them online.  I use Adobe Lightroom for all my cataloging needs, but when it comes time to display the pictures on the internet, I like to add a bit of copyright information to try and ward off the most casual attempts to reuse my images without giving credit.&lt;/p&gt;

&lt;p&gt;This is the sort of task that &lt;a href=&quot;http://www.simplesystems.org/RMagick/doc/index.html&quot;&gt;RMagick&lt;/a&gt; is incredibly well-suited to handle.  Plus, it indulges my geeky side to manipulate images using Ruby code.  Here's a snippet from my copyright script:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;require 'rubygems'
  require &amp;quot;RMagick&amp;quot;
  include Magick

  # Picture Section
  picture = Magick::Image.read(ARGV[0]).first
  width,height = picture.columns, picture.rows

  # Overlay Section
  overlay = Magick::Image.new(width, 20) {
    self.background_color = &amp;quot;rgba(0,0,0,0.6)&amp;quot;
  }

  # Combine them!
  picture.composite!(overlay, SouthGravity, MultiplyCompositeOp)

  # Text Section
  copyright = Draw.new
  copyright.fill('white')
  copyright.fill_opacity(0.75)

  copyright.pointsize(14)
  copyright.font_family('Helvetica')
  copyright.font_weight(LighterWeight)
  copyright.font_style(Magick::ItalicStyle)

  copyright.text_align(RightAlign)

  # Place the copyright onto the composite image 
  copyright.text(width - 5,height - 5,&amp;quot;© 2009 Jared Haworth&amp;quot;)
  copyright.draw(picture)

  out = ARGV[0].sub(/\./, &amp;quot;-final.&amp;quot;)
  puts &amp;quot;Writing #{out}&amp;quot;
  picture.write(out)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The code is fairly straightforward; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I start by loading the image and storing the width and height.&lt;/li&gt;
&lt;li&gt;Next, I create a black overlay, with 60% opacity, the width of the original image and 20 pixels high.&lt;/li&gt;
&lt;li&gt;I apply the overlay to the original picture, using SouthGravity to place it centered on the bottom of the image.&lt;/li&gt;
&lt;li&gt;Then, I create my drawing object, set the fill color, opacity, and font options.&lt;/li&gt;
&lt;li&gt;I use the drawing object to place the text on the composite image, setting the baseline for the text 5 pixels above the bottom of the image, and setting the end of the text (right justified) 5 pixels in from the right border of the image.&lt;/li&gt;
&lt;li&gt;Finally, I append the text &quot;-final&quot; to the filename, just before the extension, and save it back to the filesystem.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The end result looks like this:
&lt;a href=&quot;http://www.alloycode.com/assets/2009/6/19/one_small_voice_7.jpg&quot;&gt;&lt;img src=&quot;http://www.alloycode.com/assets/2009/6/19/one_small_voice_7.jpg&quot; height=&quot;266&quot; alt=&quot;Glowsticks&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;a href=&quot;http://www.simplesystems.org/RMagick/doc/index.html&quot;&gt;RMagick documentation&lt;/a&gt; is a great help, and has tons of examples.  I've used variations on this same code to create wet floor effects, drop shadows, and those neat, Polaroid-style images with the curly borders.  And since it's all Ruby code, you can use the &lt;strong&gt;File&lt;/strong&gt; and &lt;strong&gt;Dir&lt;/strong&gt; objects to iterate over an entire directory of images, performing drop dead simple batch processing.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.alloycode.com/">
    <author>
      <name>jared</name>
    </author>
    <id>tag:www.alloycode.com,2008-10-14:80</id>
    <published>2008-10-14T23:49:00Z</published>
    <updated>2010-04-07T14:50:36Z</updated>
    <link href="http://www.alloycode.com/2008/10/14/how-i-know-the-new-macbook-pro-is-a-business-computer" rel="alternate" type="text/html"/>
    <title>How I Know the New MacBook Pro is a Business Computer...</title>
<content type="html">
            &lt;p&gt;So, like many an Apple fanatic today, I spent some time around 1pm EDT watching various live feeds from sites like &lt;a href=&quot;http://live.gizmodo.com/&quot;&gt;Gizmodo&lt;/a&gt; and &lt;a href=&quot;http://engadget.com/2008/10/14/apples-all-new-macbook-pro-packs-new-nvidia-gpu-glass-trackpad/&quot;&gt;Engadget&lt;/a&gt;, waiting with breathless anticipation to see which new MacBook rumors would pan out.&lt;/p&gt;

&lt;p&gt;I'm definitely impressed by the changes I've seen, but I'd like to share with you how I'm certain that Apple is working harder to emphasize the gap between the consumer level MacBook and the MacBook Pro.&lt;/p&gt;

&lt;p&gt;Prior to today, a MacBook Pro came with a full-sized DVI port, so users could easily connect to a projector, external monitor, or Cinema Display.  But with today's announcement of the slimmer size, and the new &quot;DisplayPort&quot; connector for the entire MacBook line, your options for external displays are now as follows:&lt;/p&gt;

&lt;p&gt;If you do any public speaking, you probably connect your MBP to a projector to display your Keynote slides.  You'll now have to purchase a $29.99 DisplayPort to VGA adapter.&lt;/p&gt;

&lt;p&gt;If you use a digital external monitor at home or work with a screen size of less than or equal to 23&quot;, you'll now have to purchase an &lt;em&gt;additional&lt;/em&gt; $29.99 DisplayPort to DVI adapter, because you can't use a DVI to VGA dongle on the Apple DVI adapter.&lt;/p&gt;

&lt;p&gt;And if you're fortunate enough to have a 30&quot; monitor or Cinema Display, you'll have to pony up an additional &lt;strong&gt;$99.99&lt;/strong&gt; for the DisplayPort to Dual-Link DVI adapter.&lt;/p&gt;

&lt;p&gt;So how do I know it's a business computer?  These are the sort of &quot;Eh, the company will pick up the tab for it&quot; easy add-ons akin to an auto dealer's Undercarriage Wax or Destination Charge.  Maybe I'm old fashioned, but it seems to me if you're going to sell a $2,500 ($2,850 if Applecare matters to you) computer, you ought to throw in the adapters for free.  So, when you look at the new MacBook, and you find that you're impressed by it's slimmer size, or it's lighter weight, remember that it cost you an undisclosed $160 premium to achieve.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.alloycode.com/">
    <author>
      <name>jared</name>
    </author>
    <id>tag:www.alloycode.com,2008-09-11:67</id>
    <published>2008-09-11T21:03:00Z</published>
    <updated>2010-04-07T14:50:41Z</updated>
    <link href="http://www.alloycode.com/2008/9/11/confused-by-itunes-8" rel="alternate" type="text/html"/>
    <title>Confused by iTunes 8</title>
<content type="html">
            &lt;p&gt;Like many dedicated Apple fans, I decided to give &lt;a href=&quot;http://www.apple.com/itunes/&quot;&gt;iTunes 8&lt;/a&gt; a try this week.&lt;/p&gt;

&lt;p&gt;And, like many dedicated tin-foil hat wearers, I was more than a little worried about the privacy implications of the new &quot;Genius&quot; features.  So, after downloading iTunes 8 and rebooting my MacBook, I pulled the network cable out of the router, and launched the program.  After agreeing to the new EULA, I was faced with the new interface.&lt;/p&gt;

&lt;p&gt;Let me first say, I definitely like the look of the new grid view much better than Coverflow.  And there was no question of where I'd have to look go find the Genius playlist options, as the sidebar was already open for me on the right.&lt;/p&gt;

&lt;p&gt;So, my first order of business was to click the button to close the Genius Sidebar, since I wasn't really interested in trying out the new features. Instead, I was confronted by this dialog box:&lt;/p&gt;
&lt;img src=&quot;http://www.alloycode.com/assets/2008/9/11/Picture_2.png&quot; height=&quot;154&quot; alt=&quot;Network Required&quot; width=&quot;482&quot; /&gt;

&lt;p&gt;Is Apple collecting data on those who opt-out of the Genius program as well?&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.alloycode.com/">
    <author>
      <name>jared</name>
    </author>
    <id>tag:www.alloycode.com,2008-06-01:66</id>
    <published>2008-06-01T14:03:00Z</published>
    <updated>2010-04-07T14:50:45Z</updated>
    <category term="Programming"/>
    <link href="http://www.alloycode.com/2008/6/1/rails-2-1-now-available" rel="alternate" type="text/html"/>
    <title>Rails 2.1 Now Available</title>
<content type="html">
            &lt;p&gt;Coinciding nicely with the conclusion of &lt;a href=&quot;http://en.oreilly.com/rails2008/public/content/home&quot;&gt;Railsconf 2008&lt;/a&gt;, it would appear that Rails 2.1 &lt;a href=&quot;http://weblog.rubyonrails.com/2008/6/1/rails-2-1-time-zones-dirty-caching-gem-dependencies-caching-etc&quot;&gt;has been released&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The feature I'm most excited about?  &lt;a href=&quot;http://ryandaigle.com/articles/2008/1/25/what-s-new-in-edge-rails-easier-timezones&quot;&gt;Native Timezone support&lt;/a&gt;.  June 2008 marks my two year anniversary of working with Rails, and of all the projects I've taken on, the majority have required working with time zones.  This is a most welcome change indeed.&lt;/p&gt;

&lt;p&gt;I'd just like to add my voice to the chorus saying 'Great Job!' to the Rails core team and the 1,400 other contributors that have all added to Rails in the past six months.   &lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.alloycode.com/">
    <author>
      <name>jared</name>
    </author>
    <id>tag:www.alloycode.com,2008-05-09:65</id>
    <published>2008-05-09T15:16:00Z</published>
    <updated>2008-05-09T15:16:52Z</updated>
    <category term="Programming"/>
    <link href="http://www.alloycode.com/2008/5/9/irb-command-history-in-time-machine" rel="alternate" type="text/html"/>
    <title>IRb Command History in Time Machine</title>
<content type="html">
            &lt;p&gt;&lt;img src=&quot;http://www.alloycode.com/assets/2008/5/9/Picture_5.png&quot; alt=&quot;TIme Machine&quot; /&gt;Of the 300 new features in Leopard (Mac OS 10.5), Time Machine may be the one that excites me the most.  I've already used to to repair applications after failed updates, pull back browser history items from two months ago, and restore emails that I had inadvertently flushed.  &lt;/p&gt;

&lt;p&gt;Yesterday, I found a new use for Time Machine: reviving IRb command history.&lt;/p&gt;

&lt;p&gt;Over at &lt;a href=&quot;http://edufire.com&quot;&gt;eduFire&lt;/a&gt;, we've been working on converting user profile pictures from file system store to S3 backed storage.  Since we're using the &lt;code&gt;attachment_fu&lt;/code&gt; plugin, it seemed that the easiest way would be to just create a new instance of the user profile picture and feed in the path to the file.&lt;/p&gt;

&lt;p&gt;While using &lt;code&gt;attachment_fu&lt;/code&gt; in a controller is beautifully simple, requiring just an &lt;code&gt;uploaded_data&lt;/code&gt; parameter, manipulating files through &lt;code&gt;script/console&lt;/code&gt; is a bit more difficult.  I knew we had wrestled with this back in February, when we changed the default thumbnail resolutions, and had to reprocess everyone's photos.  What I had failed to do back then was document &lt;em&gt;how&lt;/em&gt; we actually achieved it.&lt;/p&gt;

&lt;p&gt;I have my IRb history logging to &lt;code&gt;~/.irb_history&lt;/code&gt;, but with only 500 lines of scrollback, I knew that there was no chance an entry from three months ago had survived.  My first attempt to view the file in Time Machine was unsuccessful, as I couldn't seem to figure out how to get Time Machine to display dot-files.&lt;/p&gt;

&lt;p&gt;However, the Time Machine archive is browsable in Terminal; after finding the path to the relevant backup (which looked something like this: &lt;code&gt;/Volumes/Time Machine Drive/Backups.backupdb/AlloyCode/2008-03-03-000650/Macintosh HD/Users/jared&lt;/code&gt;), I was able to open the &lt;code&gt;.irb_history&lt;/code&gt; file in TextMate and find the command I had lost.&lt;/p&gt;

&lt;p&gt;For those who might need to do a similar operation in the future, here's how to recreate a file attachment in script/console:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;Avatar.create(:filename =&amp;gt; filename, :content_type =&amp;gt; content_type, :temp_path =&amp;gt; temp_path)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In the above example, &lt;code&gt;filename&lt;/code&gt; corresponds to the name to save the attachment as on the server, &lt;code&gt;content_type&lt;/code&gt; is the MIME type, and &lt;code&gt;temp_path&lt;/code&gt; is the full path to the actual asset.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.alloycode.com/">
    <author>
      <name>jared</name>
    </author>
    <id>tag:www.alloycode.com,2008-04-26:51</id>
    <published>2008-04-26T15:56:00Z</published>
    <updated>2008-04-26T15:57:55Z</updated>
    <category term="Programming"/>
    <link href="http://www.alloycode.com/2008/4/26/another-passenger-on-the-mod_rails" rel="alternate" type="text/html"/>
    <title>Another Passenger on the mod_rails</title>
<content type="html">
            &lt;p&gt;A lot has been said about running Rails applications on shared hosting, most visibly in these two articles by &lt;a href=&quot;http://loudthinking.com/posts/21-the-deal-with-shared-hosts&quot;&gt;David Heinemeier Hansson&lt;/a&gt; and &lt;a href=&quot;http://blog.dreamhost.com/2008/01/07/how-ruby-on-rails-could-be-much-better/&quot;&gt;Dallas Kashuba&lt;/a&gt; (on the DreamHost blog).  For the past eight months, Alloy Code and &lt;a href=&quot;http://yourgarageonline.com&quot;&gt;Your Garage Online&lt;/a&gt; have been running on a single 256mb slice from &lt;a href=&quot;http://slicehost.com&quot;&gt;Slicehost&lt;/a&gt;, and while it was possible to get the two sites to happily co-exist, I've always regarded it as something of a delicate house of cards, just waiting for a gust of wind or slammed door in a neighboring apartment to knock the whole stack down.  Well, two weeks ago, I made a serious change in back-end configuration, and I couldn't be happier.  Indulge me for a moment, because I feel that a little history is appropriate&amp;hellip;&lt;/p&gt;

&lt;p&gt;Initially, the slice was configured with Apache 2.2 acting as a proxy for two mongrel clusters.  The resources of the slice itself allowed me to run two mongrels for the blog, and three for Your Garage Online.  Since the majority of the blog's content is cached static pages, two mongrels seemed like plenty, and only suffered a slight delay in attempting to access the admin interface, or other dynamic content.  &lt;/p&gt;

&lt;p&gt;Then I came across &lt;a href=&quot;http://brainspl.at/articles/2006/08/23/nginx-my-new-favorite-front-end-for-mongrel-cluster&quot;&gt;Ezra's&lt;/a&gt; article on nginx, and I invested the better part of a weekend switching from a pure Apache/Mongrel setup, to something of a strange hybrid.  Since nginx wouldn't honor SVN webdav connections properly, I had to keep an apache instance handy, but restricted to listening on a high-numbered port, with nginx forwarding requests intended for my SVN repositories back into Apache.  Meanwhile, nginx had two other listeners set up, one forwarding Alloy Code traffic to the blog's mongrel cluster, and one forwarding Your Garage Online traffic to the other mongrel cluster.  &lt;/p&gt;

&lt;p&gt;A few months ago, I heard about Thin while listening to the &lt;a href=&quot;http://railsenvy.com&quot;&gt;Rails Envy Podcast&lt;/a&gt;, and the idea of using Unix sockets instead of TCP to forward the proxy requests really appealed to me.  Unfortunately, even though I had upgraded my slice's copy of Ruby to 1.8.6, I was never able to get the Thin gem to install.  Later, I discovered it was because my RubyGems installation was linked against the older, 1.8.5 version of the ruby binary.  I never did find a good way to switch the &lt;code&gt;gem&lt;/code&gt; command's installed ruby version, I had to reinstall RubyGems from scratch using the 1.8.6 binary to call the setup.rb file.&lt;/p&gt;

&lt;p&gt;So, when &lt;a href=&quot;http://modrails.com&quot;&gt;Passenger&lt;/a&gt; came out, the configuration-tweaker in me was &lt;em&gt;very&lt;/em&gt; excited to give it a try.  Once again, I set aside the better part of a weekend to get the installation going.  After sorting out the gems issue above, and recompiling Apache to include prefork support, I was ready to roll.  &lt;/p&gt;

&lt;p&gt;The installation instructions provided were enough to get me 90% of the way there.  I had overlooked the fact that, eight months ago, I told Apache to only listen for connections on port 8010 (part of the nginx-svn debacle).  And, it turns out that when running two rails applications on a single host, with a single IP address, I needed to provide a little extra context to make certain the static content was handled properly.  &lt;/p&gt;

&lt;p&gt;Since the hostname of the box itself is alloycode.com, the setup for the blog is as sparse as the Passenger sample:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;VirtualHost *:80&amp;gt;
    ServerName alloycode.com
    DocumentRoot /path/to/blog/public
  &amp;lt;/VirtualHost&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Setting up Your Garage Online was a little tricker.  My first attempt was just to mirror the same code as above, but with the proper &lt;code&gt;ServerName&lt;/code&gt; and &lt;code&gt;DocumentRoot&lt;/code&gt; settings.  Unfortunately, that meant that while the Rails stack did load, and process the requests properly, none of the stylesheets, images, javascrtips, or other static assets could be loaded.  After carefully investigating each of the options in the Passenger documentation, I managed to put together this VirtualHost definition that seemed to do the trick:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;VirtualHost *:80&amp;gt;
     ServerName yourgarageonline.com
     ServerAlias www.yourgarageonline.com        
     DocumentRoot /path/to/ygo/public
     &amp;lt;Directory &amp;quot;/path/to/ygo/public&amp;quot;&amp;gt;
         Options FollowSymLinks
         AllowOverride None
         Order allow,deny
         Allow from all
     &amp;lt;/Directory&amp;gt;
     RailsBaseURI /
  &amp;lt;/VirtualHost&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And like that, it was as if a switch was flipped, and everything was working 100%.  It's now been two weeks since I put Passenger on that slice, and I haven't had any outages or runaway memory problems, and I no longer have to worry about my web server and my mongrel cluster getting out of sync, resulting in dreaded 503 Service Unavailable errors.  &lt;/p&gt;

&lt;p&gt;Kudos to the &lt;a href=&quot;http://modrails.com&quot;&gt;Phusion&lt;/a&gt; folks, this is one incredible release.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.alloycode.com/">
    <author>
      <name>jared</name>
    </author>
    <id>tag:www.alloycode.com,2008-02-10:49</id>
    <published>2008-02-10T23:52:00Z</published>
    <updated>2008-03-02T00:40:29Z</updated>
    <category term="Programming"/>
    <link href="http://www.alloycode.com/2008/2/10/heroku-hijinks" rel="alternate" type="text/html"/>
    <title>Heroku Hijinks</title>
<content type="html">
            &lt;p&gt;&lt;a href=&quot;http://heroku.com&quot;&gt;Heroku&lt;/a&gt;, a &lt;a href=&quot;http://ycombinator.com/&quot;&gt;Y Combinator&lt;/a&gt; funded startup, has been making headlines lately!  Mentions on the official &lt;a href=&quot;http://weblog.rubyonrails.org/2008/2/7/write-rails-apps-in-your-browser&quot;&gt;Ruby on Rails blog&lt;/a&gt;, the &lt;a href=&quot;http://podcast.rubyonrails.org/programs/1/episodes/heroku&quot;&gt;Ruby on Rails Podcast&lt;/a&gt;, and even an article on &lt;a href=&quot;http://www.techcrunch.com/2008/02/07/heroku-lifts-ruby-on-rails-development-to-the-cloud/trackback/&quot;&gt;TechCrunch&lt;/a&gt; outlining some of the upcoming features.  Personally, I've been using it since late last year, and I've found it to be immensely useful in a couple of situations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario 1:&lt;/strong&gt; While interviewing for my &lt;a href=&quot;http://edurev.com&quot;&gt;current job&lt;/a&gt;, I wanted to show my interviewers the application Keith and I had developed for the Rails Rumble.  Thanks to some trademark issues and a certain corporation whose devices have become synonymous for copiers, the document collaboration application didn't have an online presence.  Rather than attempt to put it back online with my current shared hosting (already stretched to the limit by this blog and the YGO application) or secure new shared hosting, instead I prepared to zip up the entire application and upload it to my Heroku account.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The first thing I had to do was unpack the gems used by the application, such as &lt;code&gt;attachment_fu&lt;/code&gt; into my /vendor directory, and make sure I added them to my &lt;code&gt;config/environment.rb&lt;/code&gt; load path.  &lt;/li&gt;
&lt;li&gt;Secondly, I removed all my existing log files... no need to push an additional 300mb of data online!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After zipping the app and uploading it, I just needed to click the 'migrate' button inside the Heroku editor window, and I was in business.  By virtue of putting the app online in a private state, I could ensure that only my interviewers were able to see it, and I was able to take it back offline once the interview process had concluded.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario 2:&lt;/strong&gt; In doing some freelance work on a contract tracking app, I wanted to show &lt;a href=&quot;http://catalystgamelabs.com&quot;&gt;my client&lt;/a&gt; a live preview of the progress I was making, and to get some early feedback on some of the workflow.  Again, rather than expose the whole application live through my existing hosting, I again created a zipped version of the application and added it to Heroku.&lt;/p&gt;

&lt;p&gt;This time, I was able to show him the current 'snapshot' of the application, and instantly incorporate minor tweaks without even needing to reload a mongrel instance or re-upload any files.  Small details, like the text on a form label or the size of an element could easily be adjusted on the fly, in accordance with the client's wishes; then, those changes were easily mirrored back down to my local copy to continue development.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;All in all,&lt;/em&gt; I'm very impressed with Heroku.  While I don't make extensive use of the in-browser editor, the few times I've had to make tweaks to a running instance, it's been very easy to do so right in the browser.  Plus, having a browser based interface to my favorite ruby tool, &lt;code&gt;script/console&lt;/code&gt;, has been incredibly useful.&lt;/p&gt;

&lt;p&gt;Lastly, I think Heroku illustrates an excellent usage of Amazon Web Services as part of a business model, particularly in being able to make using EC2 easily available to the end user, along with an easy way to pass along the associated costs to that user.  I'll be very excited to see where the future takes them.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.alloycode.com/">
    <author>
      <name>jared</name>
    </author>
    <id>tag:www.alloycode.com,2008-01-11:44</id>
    <published>2008-01-11T19:28:00Z</published>
    <updated>2010-04-22T20:37:31Z</updated>
    <category term="Programming"/>
    <link href="http://www.alloycode.com/2008/1/11/learning-rspec-part-ii" rel="alternate" type="text/html"/>
    <title>Learning RSpec, Part II</title>
<content type="html">
            &lt;p&gt;&lt;strong&gt;UPDATED: April 22nd, 2010&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I've been notified by one of my eagle-eyed readers that the solution originally posted at the end of this article is no longer correct.  For whatever reason, RSpec no longer returns &quot;Status&quot; as one of the keys for the header.&lt;/p&gt;

&lt;p&gt;The new, improved syntax is as follows:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;it &amp;quot;should fail with invalid credentials&amp;quot; do
      get :index
      response.should_not be_success
      response.status.should =~ /401/
    end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Original Entry Follows&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the &lt;a href=&quot;/2007/12/30/learning-rspec&quot;&gt;first entry&lt;/a&gt;, one of the issues I addressed was stubbing a response to an HTTP-Basic Authentication scheme.  To get my spec to pass, I stubbed the entire &lt;code&gt;authenticate&lt;/code&gt; method which I had written.  While this approach was successful, it left me with a hole in my code coverage:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://www.alloycode.com/assets/2008/1/11/missing_coverage_1.png&quot; height=&quot;97&quot; alt=&quot;RCov Coverage&quot; width=&quot;420&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Now that I knew my controllers' actions were being tested, I needed a good way to test the authenticate method itself, to ensure that failed requests were not being let through.  A quick glance in the Rails source gave me some clues to implementation.&lt;/p&gt;

&lt;p&gt;Since the credentials are sent (encoded) in the HTTP header, the first thing I needed to do was inject those credentials into the header before the request was processed.  Rails core (using Test::Unit) uses the following convenience method in &lt;code&gt;/actionpack/test/controller/http_authentication_test.rb&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;def set_headers(value = @credentials, name = 'HTTP_AUTHORIZATION')
      @controller.request.env[name] = value
    end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The encoded credentials are passed in and assigned to the request environment.  Accomplishing this in RSpec wasn't much different.  First, we construct a set of encoded credentials, then we assign them to the environment variable 'HTTP_AUTHORIZATION'.  Note that in the RSpec code below, we don't call &lt;code&gt;@controller.request.env&lt;/code&gt;, but simply &lt;code&gt;request.env&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;before(:each) do 
    @credentials = ActionController::HttpAuthentication::Basic.encode_credentials(&amp;quot;david&amp;quot;, &amp;quot;clearly_false&amp;quot;)
    request.env['HTTP_AUTHORIZATION'] = @credentials
  end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This allowed me to create a series of tests to check that a user providing invalid credentials was not being allowed into the protected areas of the site.  &lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;it &amp;quot;should fail with invalid credentials&amp;quot; do
      get :index
      response.should_not be_success
      response.headers[&amp;quot;Status&amp;quot;].should =~ /401/
    end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Two fairly simple expectations, when attempting to access a resource using invalid credentials, the response should not be a success, and the status code should match 401 (Unauthorized).&lt;/p&gt;

&lt;p&gt;RSpec is definitely growing on me, and I've noticed some BDD disciplines starting to creep into my approach to testing with Test::Unit in my day job.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.alloycode.com/">
    <author>
      <name>jared</name>
    </author>
    <id>tag:www.alloycode.com,2007-12-30:41</id>
    <published>2007-12-30T21:59:00Z</published>
    <updated>2007-12-30T21:59:30Z</updated>
    <category term="Programming"/>
    <link href="http://www.alloycode.com/2007/12/30/learning-rspec" rel="alternate" type="text/html"/>
    <title>Learning RSpec</title>
<content type="html">
            &lt;p&gt;&lt;em&gt;The end of 2007 has brought about some exciting changes for me, most notably a new job with &lt;a href=&quot;http://edurev.com/&quot;&gt;Education Revolution&lt;/a&gt;.  To try and ease the transition during a stressful holiday season, I gave myself a week off between jobs, which left me with a bit of unexpected time on my hands between Christmas and New Year's.  I decided to make the most of my time off and try to learn &lt;a href=&quot;http://rspec.info&quot;&gt;RSpec&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;RSpec is quickly becoming a darling among some of the visionaries in the Rails world.  With the release of RSpec 1.1, which brings easy integration between Test::Unit style testing and Behavior Driven Development using RSpec, it seemed prudent to try it on myself and see how it fits.&lt;/p&gt;

&lt;p&gt;On the whole I really like the idea of specifying behaviors instead of assertions, especially when coupled with doing some design-driven development.  As a developer, having both a clear set of expected behaviors and a set of slides which show the application in a near-finished state, it removes a lot of the guesswork which had been plaguing me on previous projects.  Also, hearing &lt;a href=&quot;http://basement.thewilliams.ws/&quot;&gt;Adam Williams&lt;/a&gt; and &lt;a href=&quot;http://wiseheartdesign.com&quot;&gt;John Long&lt;/a&gt; talk at November's Raleigh.rb meetup about doing top-down testing (starting with integration tests, then drilling down to functional and unit tests merely to handle edge cases) has turned my opinion of Integration tests on it's head.&lt;/p&gt;

&lt;p&gt;Having come from a metaprogramming-driven Test::Unit background using Mike Clark's TestRig framework, RSpec &lt;em&gt;felt&lt;/em&gt; like a lot more testing code.  And indeed, my &lt;code&gt;rake stats&lt;/code&gt; seems to support that, showing a 1:2.8 ratio for my training project.  Finding help with RSpec has been tricky, though.  There are some really great contrived examples on the RSpec homepage, but I had trouble finding more information on how to deal with presenters, nested resources, and HTTP Basic authentication.  I want to show off two solutions that I cobbled together out of solutions found online.&lt;/p&gt;

&lt;p&gt;The first problem I encountered was in dealing with the &lt;code&gt;save!&lt;/code&gt; method in ActiveRecord.  My controllers typically use the &lt;code&gt;save!&lt;/code&gt; coupled with a rescue statement for &lt;code&gt;ActiveRecord::RecordInvalid&lt;/code&gt;, like so:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;class WidgetsController &amp;lt; ApplicationController

        def create
            @widget = Widget.new(params[:widget])
            @widget.save!
            respond_to do |format|
                format.html { redirect_to @widget }
            end
        rescue ActiveRecord::RecordInvalid =&amp;gt; e
            respond_to do |format|
                format.html { render :action =&amp;gt; 'edit' }
            end
        end

    end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Most of the RSpec examples I had come across show something like this (excerpted from &lt;a href=&quot;http://www.elevatedrails.com/articles/2007/09/10/testing-controllers-with-rspec/&quot;&gt;Testing Controllers with RSpec&lt;/a&gt;):&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;def do_create
    post :create, :menu_item=&amp;gt;{:name=&amp;gt;&amp;quot;value&amp;quot;}
  end

  it &amp;quot;should save the menu item&amp;quot; do
    @menu_item.should_receive(:save).and_return(false)
    do_create
  end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The problem being, using &lt;code&gt;save!&lt;/code&gt; doesn't return false on failure, it raises an exception.  Fortunately, the answer was available on the &lt;a href=&quot;http://www.nabble.com/Re%3A-Problems-with-raising-errors-on-a-mocked-object-p12047955.html&quot;&gt;RSpec-users mailing list&lt;/a&gt;.  Now my &lt;code&gt;widet_controller_spec.rb&lt;/code&gt; contains the following:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;it &amp;quot;should fail to save the widget&amp;quot; do
      @widget.should_receive(:save!).and_raise(ActiveRecord::RecordInvalid.new(@widget))
    end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The second major stoppage I encountered was dealing with HTTP Basic authentication.  The application I was building didn't require a huge complicated account/password structure, it just needed a few protected pages available to a single administrator.  &lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;class ApplicationController &amp;lt; ActionController::Base

        before_filter :authenticate

        def authenticate
          authenticate_or_request_with_http_basic do |username, password|
            username == 'jared' &amp;amp;&amp;amp; password == 'secret'
          end
        end
    end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Suddenly, all my controller specs for actions lying behind that &lt;code&gt;authenticate&lt;/code&gt; filter were failing.  The fix lies in stubbing out the method using the controller local variable in the spec.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;describe WidgetsController do

      describe &amp;quot;with successful admin login&amp;quot; do
        before(:each) do
          controller.stub!(:authenticate).and_return(true)
        end
            ...
        end
    end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Of course, I still need to come back and write an integration test which will address both the success and failure states of the authenticate method.&lt;/p&gt;

&lt;p&gt;All in all, I'm very impressed with RSpec, and I can see why it's picking up such a following.  I'm definitely going to play around with it further, but I'm not quite ready to say that I'm going to switch all my projects over; one important factor to consider is future code maintainability.  The pool of talented Rails developers is small enough to begin with, adding the further requirement of finding a Rails developer who is also versed in RSpec limits that result set even further.&lt;/p&gt;
          </content>  </entry>
</feed>
