/ rails

Hidden Assumption (Or: Why You Should Never Use glob.first)

A recent bug in a very specific setup of ReactOnRails and capistrano that I use reminded me the rule in the title.

I Don't Think It Means What You Think It Means

Let's assume you're looking to get a file name but you only know something about its structure. For example you know there's a file named .sprockets-manifest-something.json but you don't know what that something is.

Well one idea could be to use a glob pattern. In ruby that would be:

possible_names = Dir.glob('.sprockets-manifest-*.json')

But how do you get the specific file name? If you're sure there's only one file by that name you might do:

filename = possible_names.first

And now you just made some users really unhappy. Because when a user would have multiple files by that name your code breaks in ways that's hard to connect back to the actual problem.

Solution: Bend Or Break

A better approach is the Bend Or Break principle: If you can handle the unexpected scenario in which you just found multiple files by that name, go ahead and manage it. If you can't break in a way that your users will understand the problem and how to fix it.

Applied to our case the code could handle the sitation of an old .sprockets manifest file by taking the most recent one:

filename = possible_names.sort_by { |name| file.mtime(name) }.last

Alternatively you can break and let the user know their setup does not match your assumptions:

possible_names = Dir.glob('.sprockets-manifest-*.json')
raise "Found multiple .sprockets manifest files. Expected only one. The files were: #{possible_names}" if possible_names.length != 1
filename = possible_names.first

But please only use first if you really don't care which file you got.