James Williams

CoffeeScript Gotchas

Tags: General

I've been converting a game that was previously in Java to CoffeeScript andfor the most part it hasn't been that bad. The painful parts have been errors that compile but escape notice until you inspect the generated JavaScript. Take for instance, the following function. It is incorrect but what is wrong with it?

equals = (letter, letter2) ->
  if letter is letter2

console.log equals('a','a')

Although CoffeeScript returns the last value, the above code is incorrect because even if the condition is true, it always returns false. We can fix it by changing the third line to return true. That forces the compiler to properly scope the true and false. We could alternatively make line four else false and it would do the same thing.

Here is a inner function that is declared in a CoffeeScript class. Looks fine and compiles too.

mouseOver = (event) ->
  state = game.isSelecting
  if state is yes
    this.attr {fill: 'red'}
    game.tempWord.push @letter
    this.attr {fill: 'blue'}

The problem occurs when the function is triggered by RaphaelJS. @letter is expanded in JavaScript to this.letter and this has a different when Raphael invokes it. We can account for this by using a local variable self to dereference this. That's not to say that you should always use the self instead of @variable-name but be aware of possible scope issues.

This JavaScript Kata sums it up pretty well.

My book "Learning HTML5 Game Programming..." is currently in early access on Safari Books Online, buy it here: http://bit.ly/html5gamebook