If you know Python or Ruby, CoffeeScript is a more natural way to program than JavaScript. And the code it generates is way better than (my crappy) JavaScript code. Even with the relatively small codebase I was trying convert, I still found 4 major JS coding errors in the conversion process. Any one of those would have caused a long, painful debugging session. And CoffeeScript fixes a lot of JS problems like that auto-magically!
So I decided to re-write everything. In my limited experience there are three ways to rewrite code:
- Don't. If everything is already working, just use the code you have as modules and don't worry about what's inside those black boxes.
- Make small changes, test them, make some more changes, test them, etc. Otherwise known as the 'smart approach'.
- Make a huge amount of changes in a language you've never used before and then spend the next few weeks tracking down the bugs while simultaneously trying to learn the new language. A.K.A. the fun approach :-)
My experience with CoffeeScript was pretty straight-forward:
Install
The install with node.js's npm was super-easy, and well-documented:
npm install -g coffee-script
Set up
There are a lot of ways to run CoffeeScript. The method I chose was to have it monitor all of the JavaScript that I was writing and whenever it detected a difference it would automatically compile that script. The terminal window showed any compile-time errors after each save.
Another option I liked was the -join option. It takes all of the CoffeeScripts you specify and outputs them into a single file. So in order to start using CoffeeScript I would just cd to the correct directory and issue the following command:
coffee --watch --compile --join uno.js *.coffee
I had an individual coffeescript file for each object and it all compiled into a single JS file 'uno.js'.
Found Errors
Some of the biggest errors CoffeeScript found and fixed automatically for me were in the board module where I was accidentally declaring some variables as global. ( Note to the JavaScript language designers: global variables by default? Seriously? )
My Toughest CoffeeScript Error to Debug
The actual re-writing didn't take much time... except for one bug. I was calling the _drawStone method for one class. The method didn't take any parameters so I wrote the call as:
@_drawStone
( The @ symbol is like the 'this' keyword. So that would be equivalent to this._drawStone )
This might initially seem like an odd decision, however, it kind of makes sense because the parentheses are optional for function calls with parameters, so I left them off of the parameter-less call as well. However, it should have been:
@_drawStone( )
The main problem was that the CoffeeScript compiler didn't raise this as an issue. No warning, no runtime, error, nothing... I checked the line and it compiles into:
https://github.com/jashkenas/coffee-script/issues/514
https://github.com/jashkenas/coffee-script/issues/1412
I may enter this as a request to raise a warning during the compile phase and see what they say...
Edit: Before opening the request I did my due diligence and found out this had been opened before ( https://github.com/jashkenas/coffee-script/issues/988 ) The comments mentioned why this would be such a tricky problem to fix... I may just change my coding style and always use parentheses, even when they're not required.
A Great Resource
If you want to learn CoffeeScript one of the best resources is Alex MacCaw's great book The Little Book of CoffeeScript .
@_drawStone
( The @ symbol is like the 'this' keyword. So that would be equivalent to this._drawStone )
This might initially seem like an odd decision, however, it kind of makes sense because the parentheses are optional for function calls with parameters, so I left them off of the parameter-less call as well. However, it should have been:
@_drawStone( )
The main problem was that the CoffeeScript compiler didn't raise this as an issue. No warning, no runtime, error, nothing... I checked the line and it compiles into:
this._drawStone;
What does that even mean? It creates a property but it has no value assigned to it. Why would anybody do that? I lost 20 hours of my life tracking this down :-(
The only thing that made me feel any better was that I wasn't the only person who ran into this:
The only thing that made me feel any better was that I wasn't the only person who ran into this:
https://github.com/jashkenas/coffee-script/issues/514
https://github.com/jashkenas/coffee-script/issues/1412
I may enter this as a request to raise a warning during the compile phase and see what they say...
Edit: Before opening the request I did my due diligence and found out this had been opened before ( https://github.com/jashkenas/coffee-script/issues/988 ) The comments mentioned why this would be such a tricky problem to fix... I may just change my coding style and always use parentheses, even when they're not required.
A Great Resource
If you want to learn CoffeeScript one of the best resources is Alex MacCaw's great book The Little Book of CoffeeScript .