Avoid Else, Return Early
tldr;
- Return as soon as you know your method cannot do any more meaningful work
- Reduce indentation by using
if/returninstead of a top-levelif/else - Try keep the “meat” of your method at the lowest indentation level.
- Error handling is noise.
Programmers are often taught to have a ‘single exit point’ in their methods, i.e. only return from a single location.
function () {
var result;
if () {
result = x
} else {
if () {
result = y
} else {
result = z
}
}
return result // this return is single and lonely
}
This is a poor guideline in my opinion:
- “assign a result” doesn’t explain the intent: “this is the final value, processing stops here”
- Leaves question open “is the result object finished? can it be modified? by whom?”
- Allows accidental modification of the result
- Encourages “happy path” to be wrapped in one or more if/else statements
Example if/else refactoring
Consider this typical node callback code:
function(err, results) {
if (!err) {
doOtherStuff()
doMoreStuff()
// ... etc
// ... etc
} else {
handleError(err)
}
}
There’s a few problems here. First, our error handling is dangling off the end of the method. If the “happy path” is many lines long, it can easily become unclear what the else even refers to.
Let’s try keep the “meat” of the code at the bottom of the method, and keep any special cases together at the top:
function(err, results) {
if (err) {
handleError(err)
} else {
doOtherStuff()
doMoreStuff()
// ... etc
// ... etc
}
}
It’s very easy to get unweildy levels of indentation in JavaScript, so we should strive to reduce any unnecessary nesting.
In this case, we can remove the else indentation around
our “happy path” by replacing the else with a return:
function(err, results) {
if (err) {
handleError(err)
return
}
doOtherStuff()
doMoreStuff()
// ... etc
// ... etc
}
Not only does this unindent a bunch of code, it also moves the method’s main purpose/intention/meat to indentation level 0.
We also generally don’t care about return values in JS, so we can
futher compact the method vertically by putting the return first,
removing a whole line and more braces:
function(err, results) {
if (err) return handleError(err)
doOtherStuff()
doMoreStuff()
// ... etc
// ... etc
}
It also obeys the “one logical statement per line” guideline, compacting the error detection and handling noise to a single line.
Another benefit is that the return keyword is generally syntax highlighted, so all exit points become very clear, as opposed to hidden inside result = something assignments.
This final form has:
- Method at lowest indentation level
- No unecessary indentation.
- Many fewer lines
Rebecca Murphey has also written about this
The end.
TweetUndoing Emails
I’m sure we’ve all been in a situation like this:

Only to realise you accidentally wrote “dickhead” instead of “champion” after you hit send. Oops!
Thankfully, if you’re using GMail, there is a Google Labs project that gives you a 10 second window in which you can undo sending your email: Undo Send, by Yuko F.
This incredibly simple tool has saved me from so much embarrassment over the years: lengthy diatribes neutered, typos corrected, content TLDR’ed, missing information added, etc.
With Undo Send, I can easily prevent situations like the one above.

Crisis Averted!

Phew!
Using Undo Send is risk free, but the expensive disasters it can prevent makes it a no-brainer to install. Go enable it now.
You’ll find it in your GMail Settings -> Labs tab.
TweetSpeaking about components
Me speaking briefly at Taiwan Ruby Conf 2012 on components:
http://vimeo.com/57570857#t=3282
TweetDelete all local and remote tags
#!/bin/sh
# Deletes all local and remote tags.
# `git delete-tag` comes from git-extras:
# https://github.com/visionmedia/git-extras
# Is very slow but will get there in the end.
git ls-remote --tags \
| awk '!/\^{}/' \
| awk -F tags\/ '{ print $2}' \
| xargs -L 1 git delete-tag
Gist
If there’s a better way please tell me.
Tweet
Accurately calculate total time spent on skype calls with a client
Being able to directly query Skype’s built-in sqlite db is awesome. More apps should expose their data in such a useful manner.
$sqlite3 ~/Library/Application\ Support/Skype/{{SKYPE NAME}}/main.db \
"SELECT SUM(call_duration) FROM callmembers where identity is '{{CLIENT NAME}}'"
Tweet