Avoid misindented CoffeeScript callbacks with CoffeeLint

Semantic indentation, as used by CoffeeScript or Python, can save you a lot of typing and bring more clarity to your code. However, it can also be the source of hard to find bugs, like misindented callbacks. In this post, I show you how to use CoffeeLint to make sure you don’t fall into this trap.

The problem

In the past, I have been bitten several times by the following CoffeeScript code:

someFunctionWithCallback ->
doSomethingSignificant()

In this example, doSomethingSignificant is always called synchronously after the call to someFunctionWithCallback. However, what this code’s author most probably meant was to call doSomethingSignificant from within the callback passed to someFunctionWithCallback:

someFunctionWithCallback ->
  doSomethingSignificant()

The difference is subtle, but can have dramatic consequences.

These kind of issues are often very tricky to find. Most of the time, they are located deep into the source code and when you look at them quickly, it’s hard to spot that an indentation token is missing. Moreover, the execution of such code may look perfectly valid, since doSomethingSignificant is expected to be called after someFunctionWithCallback anyway.

The solution

CoffeeLint’s newly added no_empty_functions rule, by preventing the definition of empty functions, allows you to detect such code automatically. Empty functions are functions without body. This also includes functions of the form:

class Foo
  setProperty: (@_instanceProperty) ->

which are used as a shortcuts to:

class Foo
  setProperty: (value) ->
    @_instanceProperty = value

I have never used empty functions myself, but I know that other programmers like to do so. When empty functions are needed, it is always possible to use the no_empty_functions rule by adding undefined as the only expression within the function body:

class Foo
  setProperty: (@_instanceProperty) ->
    undefined

It states the intention clearly and it’s not too long to type. It’s even similar to Python’s pass statement.

The no_empty_functions rule is available with release 1.3.0, so make sure to update your CoffeeLint’s version if you want to use it. If you want to know more about how to use CoffeeLint to check your CoffeeScript code base, head over to CoffeeLint’s website.

Happy linting!

Julien Gilli 21 April 2014
blog comments powered by Disqus