MindMap Gallery Coffee Script
This mind map is about Coffee Script. Start to use a mind map to express and organize your ideas and knowledge right now.
Edited at 2020-09-28 07:15:28This mind map is about Wholesaling Blueprint - Steps to Wholesaling Real Estate + Simple Systems. Start to use a mind map to express and organize your ideas and knowledge right now.
This mind map is about Western Front. Start to use a mind map to express and organize your ideas and knowledge right now.
This mind map is about THE SAMPLING PROCESS. Start to use a mind map to express and organize your ideas and knowledge right now.
This mind map is about Wholesaling Blueprint - Steps to Wholesaling Real Estate + Simple Systems. Start to use a mind map to express and organize your ideas and knowledge right now.
This mind map is about Western Front. Start to use a mind map to express and organize your ideas and knowledge right now.
This mind map is about THE SAMPLING PROCESS. Start to use a mind map to express and organize your ideas and knowledge right now.
Coffee Script
Command
Examples: Compile a directory tree of .coffee files into a parallel tree of .js, in lib:coffee -o lib/ -c src/Watch a file for changes, and recompile it every time the file is saved:coffee --watch --compile experimental.coffeeConcatenate a list of files into a single script:coffee --join project.js --compile src/*.coffeePrint out the compiled JS from a one-liner:coffee -bpe "alert i for i in [0..10]"Start the CoffeeScript REPL:coffee
-c, --compile Compile a .coffee script into a .js JavaScript file of the same name.
-i, --interactive Launch an interactive CoffeeScript session to try short snippets. More pleasant if wrapped with rlwrap.
-o, --output [DIR] Write out all compiled JavaScript files into the specified directory. Use in conjunction with --compile or --watch.
-j, --join [FILE] Before compiling, concatenate all scripts together in the order they were passed, and write them into the specified file. Useful for building large projects.
-w, --watch Watch the modification times of the coffee-scripts, recompiling as soon as a change occurs.
-p, --print Instead of writing out the JavaScript as a file, print it directly to stdout.
-l, --lint If the jsl (JavaScript Lint) command is installed, use it to check the compilation of a CoffeeScript file. (Handy in conjunction with --watch)
-s, --stdio Pipe in CoffeeScript to STDIN and get back JavaScript over STDOUT. Good for use with processes written in other languages. An example: cat src/cake.coffee | coffee -sc
-e, --eval Compile and print a little snippet of CoffeeScript directly from the command line. For example: coffee -e "console.log num for num in [10..1]"
-r, --require Load a library before compiling or executing your script. Can be used to hook in to the compiler (to add Growl notifications, for example).
-b, --bare Compile the JavaScript without the top-level function safety wrapper. (Used for CoffeeScript as a Node.js module.)
-t, --tokens Instead of parsing the CoffeeScript, just lex it, and print out the token stream: [IDENTIFIER square] [ASSIGN =] [PARAM_START (] ...
-n, --nodes Instead of compiling the CoffeeScript, just lex and parse it, and print out the parse tree:
Expressions
Assign
Value "square"
Code "x"
Op *
Value "x"
Value "x"
--nodejs The node executable has some useful options you can set, such as --debug, --debug-brk and --max-stack-size. Use this flag to forward options directly to Node.js.
Function
example (no default value)
square = (x) -> x * xcube = (x) -> square(x) * x
var cube, square;square = function(x) { return x * x;};cube = function(x) { return square(x) * x;};
example (with default value)
fill = (container, liquid = "coffee") -> "Filling the #{container} with #{liquid}..."
var fill;fill = function(container, liquid) { if (liquid == null) liquid = "coffee"; return "Filling the " + container + " with " + liquid + "...";};
closure
for filename in list do (filename) -> fs.readFile filename, (err, contents) -> compile filename, contents.toString()
var filename, _fn, _i, _len;_fn = function(filename) { return fs.readFile(filename, function(err, contents) { return compile(filename, contents.toString()); });};for (_i = 0, _len = list.length; _i < _len; _i++) { filename = list[_i]; _fn(filename);}load
Objects and Arrays Define
The CoffeeScript literals for objects and arrays look very similar to their JavaScript cousins. When each property is listed on its own line, the commas are optional. Objects may be created using indentation instead of explicit braces, similar to YAML.
define Object and Array
song = ["do", "re", "mi", "fa", "so"] singers = {Jagger: "Rock", Elvis: "Roll"} bitlist = [ 1, 0, 1 0, 0, 1 1, 1, 0] kids = brother: name: "Max" age: 11 sister: name: "Ida" age: 9
var bitlist, kids, singers, song;song = ["do", "re", "mi", "fa", "so"];singers = { Jagger: "Rock", Elvis: "Roll"};bitlist = [1, 0, 1, 0, 0, 1, 1, 1, 0];kids = { brother: { name: "Max", age: 11 }, sister: { name: "Ida", age: 9 }};
define with reversed words
$('.account').attr class: 'active' log object.class
$('.account').attr({ "class": 'active'});log(object["class"]);
Lexical Scoping and Variable Safety
The CoffeeScript compiler takes care to make sure that all of your variables are properly declared within lexical scope — you never need to write var yourself.
outer = 1changeNumbers = -> inner = -1 outer = 10inner = changeNumbers()
var changeNumbers, inner, outer;outer = 1;changeNumbers = function() { var inner; inner = -1; return outer = 10;};inner = changeNumbers();
If, Else, Unless, and Conditional Assignment
If/else statements can be written without the use of parentheses and curly brackets. As with functions and other block expressions, multi-line conditionals are delimited by indentation. There's also a handy postfix form, with the if or unless at the end. CoffeeScript can compile if statements into JavaScript expressions, using the ternary operator when possible, and closure wrapping otherwise. There is no explicit ternary statement in CoffeeScript — you simply use a regular if statement on a single line.
mood = greatlyImproved if singing if happy and knowsIt clapsHands() chaChaCha()else showIt() date = if friday then sue else jill options or= defaults
var date, mood;if (singing) mood = greatlyImproved;if (happy && knowsIt) { clapsHands(); chaChaCha();} else { showIt();}date = friday ? sue : jill;options || (options = defaults);
Splats...
The JavaScript arguments object is a useful way to work with functions that accept variable numbers of arguments. CoffeeScript provides splats ..., both for function definition as well as invocation, making variable numbers of arguments a little bit more palatable.
gold = silver = rest = "unknown" awardMedals = (first, second, others...) -> gold = first silver = second rest = others contenders = [ "Michael Phelps" "Liu Xiang" "Yao Ming" "Allyson Felix" "Shawn Johnson" "Roman Sebrle" "Guo Jingjing" "Tyson Gay" "Asafa Powell" "Usain Bolt"] awardMedals contenders... alert "Gold: " + goldalert "Silver: " + silveralert "The Field: " + rest
var awardMedals, contenders, gold, rest, silver;var __slice = Array.prototype.slice;gold = silver = rest = "unknown";awardMedals = function() { var first, others, second; first = arguments[0], second = arguments[1], others = 3 <= arguments.length ? __slice.call(arguments, 2) : []; gold = first; silver = second; return rest = others;};contenders = ["Michael Phelps", "Liu Xiang", "Yao Ming", "Allyson Felix", "Shawn Johnson", "Roman Sebrle", "Guo Jingjing", "Tyson Gay", "Asafa Powell", "Usain Bolt"];awardMedals.apply(null, contenders);alert("Gold: " + gold);alert("Silver: " + silver);alert("The Field: " + rest);
Loops and Comprehensions
Most of the loops you'll write in CoffeeScript will be comprehensions over arrays, objects, and ranges. Comprehensions replace (and compile into) for loops, with optional guard clauses and the value of the current array index. Unlike for loops, array comprehensions are expressions, and can be returned and assigned.
for
var food, _i, _len, _ref;_ref = ['toast', 'cheese', 'wine'];for (_i = 0, _len = _ref.length; _i < _len; _i++) { food = _ref[_i]; eat(food);}
# Eat lunch.eat food for food in ['toast', 'cheese', 'wine']
each/forEach, map, or select/filter
yearsOld = max: 10, ida: 9, tim: 11 ages = for child, age of yearsOld "#{child} is #{age}"
var age, ages, child, yearsOld;yearsOld = { max: 10, ida: 9, tim: 11};ages = (function() { var _results; _results = []; for (child in yearsOld) { age = yearsOld[child]; _results.push("" + child + " is " + age); } return _results;})();
while
# Econ 101if this.studyingEconomics buy() while supply > demand sell() until supply > demand # Nursery Rhymenum = 6lyrics = while num -= 1 "#{num} little monkeys, jumping on the bed. One fell out and bumped his head."
var lyrics, num;if (this.studyingEconomics) { while (supply > demand) { buy(); } while (!(supply > demand)) { sell(); }}num = 6;lyrics = (function() { var _results; _results = []; while (num -= 1) { _results.push("" + num + " little monkeys, jumping on the bed. One fell out and bumped his head."); } return _results;})();loadrun: lyrics.join("\n")
Array
Array Slicing and Splicing with Ranges
example1
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] copy = numbers[0...numbers.length] middle = copy[3..6]
var copy, middle, numbers;numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];copy = numbers.slice(0, numbers.length);middle = copy.slice(3, 7);
example2
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] numbers[3..6] = [-3, -4, -5, -6]
var numbers, _ref;numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];[].splice.apply(numbers, [3, 4].concat(_ref = [-3, -4, -5, -6])), _ref;
Everything is an Expression (at least, as much as possible)
You might have noticed how even though we don't add return statements to CoffeeScript functions, they nonetheless return their final value. The CoffeeScript compiler tries to make sure that all statements in the language can be used as expressions. Watch how the return gets pushed down into each possible branch of execution in the function below.
grade = (student) -> if student.excellentWork "A+" else if student.okayStuff if student.triedHard then "B" else "B-" else "C" eldest = if 24 > 21 then "Liz" else "Ike"
var eldest, grade;grade = function(student) { if (student.excellentWork) { return "A+"; } else if (student.okayStuff) { if (student.triedHard) { return "B"; } else { return "B-"; } } else { return "C"; }};eldest = 24 > 21 ? "Liz" : "Ike";
Operators and Aliases
Because the == operator frequently causes undesirable coercion, is intransitive, and has a different meaning than in other languages, CoffeeScript compiles == into ===, and != into !==. In addition, is compiles into ===, and isnt into !==. You can use not as an alias for !. For logic, and compiles to &&, and or into ||. Instead of a newline or semicolon, then can be used to separate conditions from expressions, in while, if/else, and switch/when statements. As in YAML, on and yes are the same as boolean true, while off and no are boolean false. For single-line statements, unless can be used as the inverse of if. As a shortcut for this.property, you can use @property. You can use in to test for array presence, and of to test for JavaScript object-key presence.
CoffeeScript JavaScript
is ===
isnt !==
not !
and &&
or ||
true, yes, on true
false, no, off false
@, this this
of in
in no JS equivalent
example
launch() if ignition is on volume = 10 if band isnt SpinalTap letTheWildRumpusBegin() unless answer is no if car.speed < limit then accelerate() winner = yes if pick in [47, 92, 13] print inspect "My name is #{@name}"
var volume, winner;if (ignition === true) launch();if (band !== SpinalTap) volume = 10;if (answer !== false) letTheWildRumpusBegin();if (car.speed < limit) accelerate();if (pick === 47 || pick === 92 || pick === 13) winner = true;print(inspect("My name is " + this.name));load
The Existential Operator
It's a little difficult to check for the existence of a variable in JavaScript. if (variable) ... comes close, but fails for zero, the empty string, and false. CoffeeScript's existential operator ? returns true unless a variable is null or undefined, which makes it analogous to Ruby's nil? It can also be used for safer conditional assignment than ||= provides, for cases where you may be handling numbers or strings.
solipsism = true if mind? and not world? speed ?= 75 footprints = yeti ? "bear"zip = lottery.drawWinner?().address?.zipcode
var footprints, solipsism;if ((typeof mind !== "undefined" && mind !== null) && !(typeof world !== "undefined" && world !== null)) { solipsism = true;}if (typeof speed === "undefined" || speed === null) speed = 75;footprints = typeof yeti !== "undefined" && yeti !== null ? yeti : "bear";var zip, _ref;zip = typeof lottery.drawWinner === "function" ? (_ref = lottery.drawWinner().address) != null ? _ref.zipcode : void 0 : void 0;
Classes, Inheritance, and Super
JavaScript's prototypal inheritance has always been a bit of a brain-bender, with a whole family tree of libraries that provide a cleaner syntax for classical inheritance on top of JavaScript's prototypes: Base2, Prototype.js, JS.Class, etc. The libraries provide syntactic sugar, but the built-in inheritance would be completely usable if it weren't for a couple of small exceptions: it's awkward to call super (the prototype object's implementation of the current function), and it's awkward to correctly set the prototype chain. Instead of repetitively attaching functions to a prototype, CoffeeScript provides a basic class structure that allows you to name your class, set the superclass, assign prototypal properties, and define the constructor, in a single assignable expression. Constructor functions are named, to better support helpful stack traces.
class Animal constructor: (@name) -> move: (meters) -> alert @name + " moved #{meters}m." class Snake extends Animal move: -> alert "Slithering..." super 5 class Horse extends Animal move: -> alert "Galloping..." super 45 sam = new Snake "Sammy the Python"tom = new Horse "Tommy the Palomino" sam.move()tom.move() String::dasherize = -> this.replace /_/g, "-"
var Animal, Horse, Snake, sam, tom;var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child;};Animal = (function() { function Animal(name) { this.name = name; } Animal.prototype.move = function(meters) { return alert(this.name + (" moved " + meters + "m.")); }; return Animal;})();Snake = (function() { __extends(Snake, Animal); function Snake() { Snake.__super__.constructor.apply(this, arguments); } Snake.prototype.move = function() { alert("Slithering..."); return Snake.__super__.move.call(this, 5); }; return Snake;})();Horse = (function() { __extends(Horse, Animal); function Horse() { Horse.__super__.constructor.apply(this, arguments); } Horse.prototype.move = function() { alert("Galloping..."); return Horse.__super__.move.call(this, 45); }; return Horse;})();sam = new Snake("Sammy the Python");tom = new Horse("Tommy the Palomino");sam.move();tom.move(); String.prototype.dasherize = function() { return this.replace(/_/g, "-");};loadrun: "one_two".dasherize()
Destructuring Assignment
To make extracting values from complex arrays and objects more convenient, CoffeeScript implements ECMAScript Harmony's proposed destructuring assignment syntax. When you assign an array or object literal to a value, CoffeeScript breaks up and matches both sides against each other, assigning the values on the right to the variables on the left. In the simplest case, it can be used for parallel assignment:
theBait = 1000theSwitch = 0 [theBait, theSwitch] = [theSwitch, theBait] weatherReport = (location) -> # Make an Ajax request to fetch the weather... [location, 72, "Mostly Sunny"] [city, temp, forecast] = weatherReport "Berkeley, CA" futurists = sculptor: "Umberto Boccioni" painter: "Vladimir Burliuk" poet: name: "F.T. Marinetti" address: [ "Via Roma 42R" "Bellagio, Italy 22021" ] {poet: {name, address: [street, city]}} = futurists tag = "<impossible>" [open, contents..., close] = tag.split("")
var theBait, theSwitch, _ref;theBait = 1000;theSwitch = 0;_ref = [theSwitch, theBait], theBait = _ref[0], theSwitch = _ref[1]; var city, forecast, temp, weatherReport, _ref;weatherReport = function(location) { return [location, 72, "Mostly Sunny"];};_ref = weatherReport("Berkeley, CA"), city = _ref[0], temp = _ref[1], forecast = _ref[2]; var city, futurists, name, street, _ref, _ref2;futurists = { sculptor: "Umberto Boccioni", painter: "Vladimir Burliuk", poet: { name: "F.T. Marinetti", address: ["Via Roma 42R", "Bellagio, Italy 22021"] }};_ref = futurists.poet, name = _ref.name, _ref2 = _ref.address, street = _ref2[0], city = _ref2[1]; var close, contents, open, tag, _i, _ref;var __slice = Array.prototype.slice;tag = "<impossible>";_ref = tag.split(""), open = _ref[0], contents = 3 <= _ref.length ? __slice.call(_ref, 1, _i = _ref.length - 1) : (_i = 1, []), close = _ref[_i++];
Function binding
In JavaScript, the this keyword is dynamically scoped to mean the object that the current function is attached to. If you pass a function as a callback or attach it to a different object, the original value of this will be lost. If you're not familiar with this behavior, this Digital Web article gives a good overview of the quirks. The fat arrow => can be used to both define a function, and to bind it to the current value of this, right on the spot. This is helpful when using callback-based libraries like Prototype or jQuery, for creating iterator functions to pass to each, or event-handler functions to use with bind. Functions created with the fat arrow are able to access properties of the this where they're defined.
Account = (customer, cart) -> @customer = customer @cart = cart $('.shopping_cart').bind 'click', (event) => @customer.purchase @cart
var Account;var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };Account = function(customer, cart) { this.customer = customer; this.cart = cart; return $('.shopping_cart').bind('click', __bind(function(event) { return this.customer.purchase(this.cart); }, this));};
Embedded JavaScript
Hopefully, you'll never need to use it, but if you ever need to intersperse snippets of JavaScript within your CoffeeScript, you can use backticks to pass it straight through.
hi = `function() { return [document.title, "Hello JavaScript"].join(": ");}`
var hi;hi = function() { return [document.title, "Hello JavaScript"].join(": ");};
Switch/When/Else
Switch statements in JavaScript are a bit awkward. You need to remember to break at the end of every case statement to avoid accidentally falling through to the default case. CoffeeScript prevents accidental fall-through, and can convert the switch into a returnable, assignable expression. The format is: switch condition, when clauses, else the default case. As in Ruby, switch statements in CoffeeScript can take multiple values for each when clause. If any of the values match, the clause runs.
switch day when "Mon" then go work when "Tue" then go relax when "Thu" then go iceFishing when "Fri", "Sat" if day is bingoDay go bingo go dancing when "Sun" then go church else go work
switch (day) { case "Mon": go(work); break; case "Tue": go(relax); break; case "Thu": go(iceFishing); break; case "Fri": case "Sat": if (day === bingoDay) { go(bingo); go(dancing); } break; case "Sun": go(church); break; default: go(work);}
Try/Catch/Finally
Try/catch statements are just about the same as JavaScript (although they work as expressions).
try allHellBreaksLoose() catsAndDogsLivingTogether()catch error print errorfinally cleanUp()
try { allHellBreaksLoose(); catsAndDogsLivingTogether();} catch (error) { print(error);} finally { cleanUp();}
Chained Comparisons
CoffeeScript borrows chained comparisons from Python — making it easy to test if a value falls within a certain range.
cholesterol = 127 healthy = 200 > cholesterol > 60
var cholesterol, healthy;cholesterol = 127;healthy = (200 > cholesterol && cholesterol > 60);loadrun: healthy
String Interpolation, Heredocs, and Block Comments
Ruby-style string interpolation is included in CoffeeScript. Double-quoted strings allow for interpolated values, using #{ ... }, and single-quoted strings are literal. Multiline strings are allowed in CoffeeScript. Heredocs can be used to hold formatted or indentation-sensitive text (or, if you just don't feel like escaping quotes and apostrophes). The indentation level that begins the heredoc is maintained throughout, so you can keep it all aligned with the body of your code.
author = "Wittgenstein"quote = "A picture is a fact. -- #{ author }" sentence = "#{ 22 / 7 } is a decent approximation of π" mobyDick = "Call me Ishmael. Some years ago -- never mind how long precisely -- having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of the world..." html = ''' <strong> cup of coffeescript </strong> ''' ###CoffeeScript Compiler v1.1.2Released under the MIT License###
var author, quote, sentence;author = "Wittgenstein";quote = "A picture is a fact. -- " + author;sentence = "" + (22 / 7) + " is a decent approximation of π"; var mobyDick;mobyDick = "Call me Ishmael. Some years ago -- never mind how long precisely -- having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of the world..."; var html;html = '<strong>\n cup of coffeescript\n</strong>'; /*CoffeeScript Compiler v1.1.2Released under the MIT License*/
Extended Regular Expressions
Similar to "heredocs" and "herecomments", CoffeeScript supports "heregexes" — extended regular expressions that ignore internal whitespace and can contain comments, after Perl's /x modifier, but delimited by ///. They go a long way towards making complex regular expressions readable. To quote from the CoffeeScript source:
OPERATOR = /// ^ ( ?: [-=]> # function | [-+*/%<>&|^!?=]= # compound assign / compare | >>>=? # zero-fill right shift | ([-+:])\1 # doubles | ([&|<>])\2=? # logic / shift | \?\. # soak access | \.{2,3} # range or splat) ///
var OPERATOR;OPERATOR = /^(?:[-=]>|[-+*\/%<>&|^!?=]=|>>>=?|([-+:])\1|([&|<>])\2=?|\?\.|\.{2,3})/;
Cake, and Cakefiles
CoffeeScript includes a (very) simple build system similar to Make and Rake. Naturally, it's called Cake, and is used for the tasks that build and test the CoffeeScript language itself. Tasks are defined in a file named Cakefile, and can be invoked by running cake [task] from within the directory. To print a list of all the tasks and options, just type cake. Task definitions are written in CoffeeScript, so you can put arbitrary code in your Cakefile. Define a task with a name, a long description, and the function to invoke when the task is run. If your task takes a command-line option, you can define the option with short and long flags, and it will be made available in the options object. Here's a task that uses the Node.js API to rebuild CoffeeScript's parser:
fs = require 'fs' option '-o', '--output [DIR]', 'directory for compiled code' task 'build:parser', 'rebuild the Jison parser', (options) -> require 'jison' code = require('./lib/grammar').parser.generate() dir = options.output or 'lib' fs.writeFile "#{dir}/parser.js", code
var fs;fs = require('fs');option('-o', '--output [DIR]', 'directory for compiled code');task('build:parser', 'rebuild the Jison parser', function(options) { var code, dir; require('jison'); code = require('./lib/grammar').parser.generate(); dir = options.output || 'lib'; return fs.writeFile("" + dir + "/parser.js", code);});
"text/coffeescript" Script Tags
While it's not recommended for serious use, CoffeeScripts may be included directly within the browser using In fact, the little bit of glue script that runs "Try CoffeeScript" above, as well as the jQuery for the menu, is implemented in just this way. View source and look at the bottom of the page to see the example. Including the script also gives you access to CoffeeScript.compile() so you can pop open Firebug and try compiling some strings. The usual caveats about CoffeeScript apply — your inline scripts will run within a closure wrapper, so if you want to expose global variables or functions, attach them to the window object.
Books and Screencasts
There are a number of excellent books and screencasts to help you get started with CoffeeScript, some of which are freely available online. The Little Book on CoffeeScript is a brief 5-chapter introduction to CoffeeScript, written with great clarity and precision by Alex MacCaw.Smooth CoffeeScript is a reimagination of the excellent book Eloquent JavaScript, as if it had been written in CoffeeScript instead. Covers language features as well a the functional and object oriented programming styles. By E. Hoigaard.CoffeeScript: Accelerated JavaScript Development is Trevor Burnham's thorough introduction to the language. By the end of the book, you'll have built a fast-paced multiplayer word game, writing both the client-side and Node.js portions in CoffeeScript.Meet CoffeeScript is a 75-minute long screencast by PeepCode. Highly memorable for its animations which demonstrate transforming CoffeeScript into the equivalent JS.If you're looking for less of a time commitment, RailsCasts' CoffeeScript Basics should have you covered, hitting all of the important notes about CoffeeScript in 11 minutes.
Examples
sstephenson's Pow, a zero-configuration Rack server, with comprehensive annotated source.frank06's riak-js, a Node.js client for Riak, with support for HTTP and Protocol Buffers.technoweenie's Coffee-Resque, a port of Resque for Node.js.assaf's Zombie.js, A headless, full-stack, faux-browser testing library for Node.js.jashkenas' Underscore.coffee, a port of the Underscore.js library of helper functions.stephank's Orona, a remake of the Bolo tank game for modern browsers.josh's nack, a Node.js-powered Rack server.
Resources
Source CodeUse bin/coffee to test your changes,bin/cake test to run the test suite,bin/cake build to rebuild the CoffeeScript compiler, and bin/cake build:parser to regenerate the Jison parser if you're working on the grammar. git checkout lib && bin/cake build:full is a good command to run when you're working on the core language. It'll refresh the lib directory (in case you broke something), build your altered compiler, use that to rebuild itself (a good sanity test) and then run all of the tests. If they pass, there's a good chance you've made a successful change.CoffeeScript IssuesBug reports, feature proposals, and ideas for changes to the language belong here.CoffeeScript Google GroupIf you'd like to ask a question, the mailing list is a good place to get help.The CoffeeScript WikiIf you've ever learned a neat CoffeeScript tip or trick, or ran into a gotcha — share it on the wiki. The wiki also serves as a directory of handy text editor extensions, web framework plugins, and general CoffeeScript build tools.The FAQPerhaps your CoffeeScript-related question has been asked before. Check the FAQ first.