→ Singin' Singletons

18 November 2008

There’s stuff I just don’t understand. David Bowie, for instance. Or the Southern Hemisphere. But nothing quite boggles my mind like Ruby’s Singleton. Because really, it’s totally unnecessary.

Here’s what they want you to do with your code:

require 'net/http'

# first you setup your singleton
class Cheat
  include Singleton
  
  def initialize
    @host = 'http://cheat.errtheblog.com/'
    @http = Net::HTTP.start(URI.parse(@host).host)
  end
  
  def sheet(name)
    @http.get("/s/#{name}").body
  end
end

# then you use it
Cheat.instance.sheet 'migrations'
Cheat.instance.sheet 'yahoo_ceo'

But that’s crazy. Fight the power.

require 'net/http'

# here's how we roll
module Cheat
  extend self

  def host
    @host ||= 'http://cheat.errtheblog.com/'
  end

  def http
    @http ||= Net::HTTP.start(URI.parse(host).host)
  end

  def sheet(name)
    http.get("/s/#{name}").body
  end
end

# then you use it
Cheat.sheet 'migrations'
Cheat.sheet 'singletons'

Any why not? The API is more concise, the code is easier to test, mock, and stub, and it’s still dead simple to convert into a proper class should the need arise.