This is Anti-pattern—thoughts on programming and whatnot by Brandon Weiss.

Use Bundler.setup Instead of Bundler.require

March 12, 2013

About two years ago I recommended using Bundler.require instead of Bundler.setup to automatically require and load gem dependencies. And in the spirit of changing my mind often I’m completely reversing my stance; using Bundler.setup is significantly better than Bundler.require.

The original reason I thought using Bundler.require was better was just a variety of bad habits leftover from Rails. Over the years Rails has changed a lot in how it handles dependencies. Gems used to be manually required, then were automatically required via Bundler. Code in the app folder has always been automatically required, and up until relatively recently so was code in the lib folder. The general message was and still is pretty clear; Rails implicitly—if not explicitly—discourages manual requiring. Over time this led me to the erroneous conclusion that manually requiring dependencies was repetitious and unnecessary. Why do something manually that can be done automatically?

But as I’ve gotten better my opinion has shifted the other way. There are some huge benefits to using Bundler.setup to set up load paths for gems, adding application directories to the load paths, and then manually requiring dependencies wherever they are used in an application.

It provides amazing design feedback and documentation

Manually requiring dependencies at the top of every file very explicitly tells you and anyone else exactly what dependencies that file has. This makes code easier to read, understand, test, and refactor. It also makes it painfully obvious when a class is too complicated. If a class needs more than five require statements to work there’s probably too much going on in that class.

It forces you to think about your dependencies and the cost associated with using them

Dependencies aren’t free. Every dependency you have adds complexity and increases coupling. Automatically loading all dependencies makes them seem like they’re free and can be used whenever and wherever in your application. Having to manually require a dependency to use it forces you to justify its use and keeps your dependency list lean.

It makes removing dependencies easier

If you automatically load all your dependencies when you load your environment, you have no way of knowing what parts of your application are using any given dependency. You’d have to manually search for class names, method names, and other ways of identifying a dependency in order to update it or remove it, which is tedious and error-prone. If you manually require dependencies, you can just search for the require statement and remove or replace the dependency.


The big question at the heart of this all is what is your application? Is it one monolithic, tightly-coupled mess? Or is it a structured collection of small, loosely-coupled objects? Using Bundler.require will lead you towards the former, but using Bundler.setup will help ensure you make the latter.

Ship Now, Not Later

March 04, 2013

A few days ago I shipped a small project I’ve been working on called Arrival. It estimates arrival times for Apple products based on previous release cycles. Embarrassingly, this is something I’d been thinking about for the better part of two years, but it took until a few days ago for me to make it happen.

I first had the idea a few years back after I stumbled onto the MacRumors Buyer’s Guide and was shocked at how poorly it was designed and how terribly it visualized the data. I was sure I could do much better. So I spent a few days cranking out a rough version that was functional but lacked an amazing visual design. And that’s where I hit a wall. I think great design is imperative and there was no way I was going to ship a product that didn’t look amazing.

I spent the next two years sitting on it while I emailed designers to try and find someone to create the perfect design. Many expressed interest but most were ultimately too busy. Twice someone said yes and started working on it but dropped off as other things came up. Eventually I just gave up and shelved it, figuring I’d just meet the right person to work on it with eventually.

A month or two ago my friend Andy Keil reached out to me with an idea for an event called FinishUp Weekend. It’s the antithesis of Startup Weekend, the premise being that starting is easy, finishing is hard, so instead of starting something new let’s finish up the projects we already have. He asked if I’d be interested in going and I told him absolutely, and that I knew just what I was going to work on.

Two months later I flew down to Austin, met Andre Jurgensen (co-founder of Handsome) at the event and jammed it out over the next two days. I would love to say that the moment I told Andy I was going I had an epiphany and realized waiting for the perfect design was ridiculous, but the truth is, all through the weeks leading up to the event and even for a little bit while I was down there I debated whether or not I should ship it. It wasn’t until I met Josh Long, who came down to participate in the event and gave a small talk about Execute, a book he wrote—in three fucking days—that I realized how asinine I had truly been. If I’d waited to ship it until it was as perfect as I wanted it to be, I would never have shipped it at all.

The moment after I shipped Arrival was the best I’ve felt in a long time, and I already usually feel pretty good. The high I got from shipping it is better than any food I’ve ever eaten, any drink I’ve ever tasted, or any drug I’ve ever done. The first day Arrival received 30,000 hits, three days later it has received over 60,000 hits, and the feedback has been nothing but positive. If you have an unfinished project that hasn’t shipped yet because you’re still perfecting it and it doesn’t quite meet your expectations, remember that you’re the only thing standing in your own way. Stop fucking around and ship it.

Litany Against Distraction

November 02, 2012

I must not get distracted.
Distraction is the mind-killer.
Distraction is the little-death that brings total obliteration.
I will face my distraction.
I will permit it to pass over me and through me.
And when it has gone past I will turn the inner eye to see its path.
Where the distraction has gone there will be nothing.
Only I will remain.

Upgrading from PostgreSQL 9.1.x to 9.2.x with Homebrew

October 13, 2012

I use Homebrew to manage my packages on OS X. It makes installing them dead-simple and keeping them up-to-date dead-easy. But the one package which I always try to upgrade and always winds up breaking my setup is PostgreSQL. It seems like every single minor version (according to Semantic Versioning) upgrades fine, but then fails to start, and because I start the processes on login and run them in the background using launch agents, it’s never immediately obvious that the upgrade didn’t work, why it didn’t work, or what I need to do next to get it to work.

This most recently bit me again when upgrading from 9.1.x to 9.2.x because apparently the database format changed and needed to be upgraded. I know how to do it and have done it several times in the past, but I still forget every time. So I’m documenting it here for myself and everyone else who forgets.

NB: The exact commands differ depending on which patch level of 9.1.x you’re upgrading from and which patch level of 9.2.x you’re upgrading to. So make sure to change the x’s to the proper patch level in the commands.

brew update
brew upgrade postgresql
launchctl unload -w ~/Library/LaunchAgents/homebrew.mxcl.postgresql.plist
mv /usr/local/var/postgres /usr/local/var/postgres91
initdb /usr/local/var/postgres -E utf8
pg_upgrade \
  -b /usr/local/Cellar/postgresql/9.1.x/bin \
  -B /usr/local/Cellar/postgresql/9.2.x/bin \
  -d /usr/local/var/postgres91 \
  -D /usr/local/var/postgres
cp /usr/local/Cellar/postgresql/9.2.x/homebrew.mxcl.postgresql.plist ~/Library/LaunchAgents/
launchctl load -w ~/Library/LaunchAgents/homebrew.mxcl.postgresql.plist

This will upgrade to the latest version of postgres, stop the process, move your database to a new location, initialize a new database, port your data from the old database to the new database, create a new launch agent, and start the process.

After you’ve confirmed that postgres has started, everything is working properly, and your old data has been properly converted you can remove the original database.

rm -rf /usr/local/var/postgres91

The Repository Pattern and Proper HTTP Status Codes

October 12, 2012

Suppose you are building an API and you need one of the resources to be upsertable—that is, you need to be able to either insert or update data from the same endpoint. Assuming you’re using Rails, it might look something like this.

def upsert
  @pickle = Pickle.new params[:pickle]

  if existing_pickle = Pickle.find_by_id(@pickle.id)
    @pickle = existing_pickle.assign_attributes = params[:pickle]
  end

  @pickle.save

  render :pickle
end

This isn’t bad, but all the cool kids are using the Repository pattern (which is really just a Facade for persistence layers) to abstract ActiveRecord away from the domain as much as possible. So something like this might be better.

def upsert
  @pickle = PickleRepository.create_or_update(params[:pickle])

  render :pickle
end

Now that is a delicious PicklesController. But it’s not quite finished. If the @pickle has any errors and can’t be created or updated, we’re still going to be returning a 200 OK response. That’s bad form. We can check if it has any errors and change the status accordingly.

def upsert
  @pickle     = PickleRepository.create_or_update(params[:pickle])
  http_status = @pickle.errors.any? ? :unprocessable_entity : :ok

  render :pickle, status: http_status
end

Excellent. Now we’re returning a 422 Unprocessable Entity if the @pickle has validation errors. But it’s still not quite finished. We’re returning a 200 OK if the resource is created. Although technically incorrect, that’s probably fine for most cases. But what if the client needs to know whether the request resulted in a resource being created or a resource being updated? Well there’s actually a different HTTP status code for that, 201 Created. So let’s just implement that and… crap, in the process of isolating persistence we’ve also removed our ability to determine if the object was saved or updated. What to do?

After poring over the Rails docs for an hour or two I found that you can kind of introspect the state of an object after saving using ActiveModel::Dirty#previous_changes. If previous_changes includes a key named id, it’s (probably) a new object and should return a 201 Created, otherwise it’s an update and should return a 200 OK. All together now.

def upsert
  @pickle     = PickleRepository.create_or_update(params[:pickle])
  http_status = HTTPStatusCode.new(@pickle).from_model

  render :pickle, status: http_status
end

# lib/http_status_code.rb
class HTTPStatusCode

  attr_reader :model

  def initialize(model)
    @model = model
  end

  def from_model
    unprocessable_entity || created || ok
  end

private

  def unprocessable_entity
    :unprocessable_entity if model.errors.any?
  end

  def created
    :created if model.previous_changes.include?("id")
  end

  def ok
    :ok
  end

end