diff --git a/documentation/index.html.erb b/documentation/index.html.erb index 47c0c3d9..de3def63 100644 --- a/documentation/index.html.erb +++ b/documentation/index.html.erb @@ -172,7 +172,7 @@ npm install -g coffee-script
(Leave off the -g if you don't wish to install globally.)
- +If you'd prefer to install the latest master version of CoffeeScript, you can clone the CoffeeScript @@ -191,7 +191,7 @@ sudo bin/cake install be careful not to use the existing out-of-date package. If installing on Windows, your best bet is probably to run Node.js under Cygwin. If you'd - just like to experiment, you can try the + just like to experiment, you can try the CoffeeScript Compiler For Windows.
@@ -229,7 +229,7 @@ sudo bin/cake install-j, --join [FILE]
- There are a number of excellent books and screencasts to help you get + There are a number of excellent books and screencasts to help you get started with CoffeeScript, some of which are freely available online.
- +1.1.2 @@ -1081,24 +1081,24 @@ Expressions against control structures, implicit invocation of a try/catch block, variadic arguments leaking from local scope, line numbers in syntax errors following heregexes, property access on parenthesized number literals, - bound class methods and super with reserved names, a REPL overhaul, + bound class methods and super with reserved names, a REPL overhaul, consecutive compiled semicolons, block comments in implicitly called objects, and a Chrome bug.
- +1.1.1
- + - Bugfix release for classes with external constructor functions, see + Bugfix release for classes with external constructor functions, see issue #1182.1.1.0
- When running via the coffee executable, process.argv and + When running via the coffee executable, process.argv and friends now report coffee instead of node. Better compatibility with Node.js 0.4.x module lookup changes. The output in the REPL is now colorized, like Node's is. @@ -1578,7 +1578,7 @@ Expressions(Leave off the -g if you don't wish to install globally.)
- +If you'd prefer to install the latest master version of CoffeeScript, you can clone the CoffeeScript @@ -259,7 +277,7 @@ sudo bin/cake install be careful not to use the existing out-of-date package. If installing on Windows, your best bet is probably to run Node.js under Cygwin. If you'd - just like to experiment, you can try the + just like to experiment, you can try the CoffeeScript Compiler For Windows.
@@ -297,7 +315,7 @@ sudo bin/cake install-j, --join [FILE]
square = (x) -> x * x cube = (x) -> square(x) * x
var cube, square; + square = function(x) { return x * x; }; + cube = function(x) { return square(x) * x; };
Functions may also have default values for arguments. Override the default value by passing a non-null argument. @@ -489,15 +512,18 @@ cube = function(x) {
var fill; + fill = function(container, liquid) { if (liquid == null) liquid = "coffee"; return "Filling the " + container + " with " + liquid + "..."; };
@@ -527,12 +553,16 @@ kids =
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", @@ -544,12 +574,16 @@ kids = { } };
In JavaScript, you can't use reserved words, like class, as properties of an object, without quoting them as strings. CoffeeScript notices reserved words @@ -571,9 +606,11 @@ kids = { log object.class -
$('.account').attr({ +
+$('.account').attr({ "class": 'active' }); + log(object["class"]);
var changeNumbers, inner, outer; + outer = 1; + changeNumbers = function() { var inner; inner = -1; return outer = 10; }; + inner = changeNumbers();
Notice how all of the variable declarations have been pushed up to the top of the closest scope, the first time they appear. @@ -663,14 +707,18 @@ options or= defaults
var date, mood; + if (singing) mood = greatlyImproved; + if (happy && knowsIt) { clapsHands(); chaChaCha(); } else { showIt(); } + date = friday ? sue : jill; + options || (options = defaults);
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) : []; @@ -719,14 +769,21 @@ gold = silver = rest < 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);
@@ -751,13 +814,36 @@ alert("The Field: " + rest);;'>run
# Eat lunch. eat food for food in ['toast', 'cheese', 'wine'] -
var food, _i, _len, _ref; + +# Fine dining +courses = ['salad', 'entree', 'dessert'] +menu course + 1, dish for dish, course in courses + +# Health conscious meal +foods = ['broccoli', 'spinach', 'chocolate'] +eat food for food in foods when food isnt 'chocolate' +
var course, courses, dish, food, foods, _i, _j, _len, _len2, _len3, _ref; + _ref = ['toast', 'cheese', 'wine']; for (_i = 0, _len = _ref.length; _i < _len; _i++) { food = _ref[_i]; eat(food); } -
Comprehensions should be able to handle most places where you otherwise
would use a loop, each/forEach, map, or select/filter:
@@ -769,6 +855,7 @@ _ref = ['
Note how because we are assigning the value of the comprehensions to a
variable in the example above, CoffeeScript is collecting the result of
@@ -810,11 +899,13 @@ countdown = (function() {
ages = for child, age of yearsOld
"#{child} is #{age}"
If you would like to iterate over just the keys that are defined on the
object itself, by adding a hasOwnProperty
@@ -862,6 +956,7 @@ lyrics = while num countdown = (num for num in [10..1])
var countdown, num;
+
countdown = (function() {
var _results;
_results = [];
@@ -778,6 +865,7 @@ countdown = (function(
return _results;
})();
var age, ages, child, yearsOld;
+
yearsOld = {
max: 10,
ida: 9,
tim: 11
};
+
ages = (function() {
var _results;
_results = [];
@@ -825,11 +916,13 @@ ages = (function() {
return _results;
})();
+})();
+;alert(ages.join(", "));'>run: ages.join(", ")
var lyrics, num;
+
if (this.studyingEconomics) {
while (supply > demand) {
buy();
@@ -870,7 +965,9 @@ lyrics = while num
6;
+
lyrics = (function() {
var _results;
_results = [];
@@ -880,6 +977,7 @@ lyrics = (function() {
return _results;
})();
For readability, the until keyword is equivalent to while not, and the loop keyword is equivalent to while true. @@ -913,6 +1014,7 @@ lyrics = (function() { 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()); @@ -939,13 +1041,20 @@ middle = copy[3..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);
+ +middle = copy.slice(3, 7); +;alert(middle);'>run: middle
The same syntax can be used with assignment to replace a segment of an array with new values, splicing it. @@ -956,11 +1065,16 @@ numbers[3..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;
+ +[].splice.apply(numbers, [3, 4].concat(_ref = [-3, -4, -5, -6])), _ref; +;alert(numbers);'>run: numbers
Note that JavaScript strings are immutable, and can't be spliced.
@@ -984,6 +1098,7 @@ numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; eldest = if 24 > 21 then "Liz" else "Ike"
var eldest, grade; + grade = function(student) { if (student.excellentWork) { return "A+"; @@ -997,8 +1112,10 @@ eldest = if return "C"; } }; + eldest = 24 > 21 ? "Liz" : "Ike";
Even though functions will always return their final value, it's both possible
and encouraged to return early from a function body writing out the explicit
@@ -1026,9 +1145,12 @@ eldest = 24 > 21 ? "Liz" : "Ike";;alert(eldest);'>run: eldest
load
Things that would otherwise be statements in JavaScript, when used
as part of an expression in CoffeeScript, are converted into expressions
@@ -1039,6 +1161,7 @@ six = (one = 1) + (two = 2) + (three = 3);;alert(six);'>run: six
=
var globals, name; + globals = ((function() { var _results; _results = []; @@ -1048,6 +1171,7 @@ globals = ((function() return _results; })()).slice(0, 10);
As well as silly things, like passing a try/catch statement directly into a function call: @@ -1067,20 +1192,23 @@ globals = ((function() { "And the error is ... #{error}" ) -
alert((function() { +
+alert((function() { try { return nonexistent / void 0; } catch (error) { return "And the error is ... " + error; } })()); -
There are a handful of statements in JavaScript that can't be meaningfully converted into expressions, namely break, continue, @@ -1155,11 +1283,17 @@ winner = yes < 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));
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";
The accessor variant of the existential operator ?. can be used to soak up null references in a chain of properties. Use it instead @@ -1207,6 +1348,7 @@ footprints = typeof yeti !== "undefined" && yeti !== null ? yeti : "bear";;alert
zip = lottery.drawWinner?().address?.zipcode
var zip, _ref; + zip = typeof lottery.drawWinner === "function" ? (_ref = lottery.drawWinner().address) != null ? _ref.zipcode : void 0 : void 0;
@@ -1266,93 +1408,122 @@ tom.move()
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; -}; +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();
If structuring your prototypes classically isn't your cup of tea, CoffeeScript
provides a couple of lower-level conveniences. The extends operator
@@ -1364,12 +1535,15 @@ tom.move();;'>run
String::dasherize = -> this.replace /_/g, "-" -
String.prototype.dasherize = function() { +
+String.prototype.dasherize = function() { return this.replace(/_/g, "-"); }; -
Finally, class definitions are blocks of executable code, which make for interesting metaprogramming possibilities. Because in the context of a class definition, @@ -1396,13 +1570,20 @@ theSwitch = 0
var theBait, theSwitch, _ref; + theBait = 1000; + theSwitch = 0; + _ref = [theSwitch, theBait], theBait = _ref[0], theSwitch = _ref[1];
But it's also helpful for dealing with functions that return multiple values. @@ -1415,15 +1596,20 @@ _ref = [theSwitch, theBait], theBait = _ref[0], theSwitch = _ref[1];;alert(theBa
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];
Destructuring assignment can be used with any depth of array and object nesting, to help pull out deeply nested properties. @@ -1442,6 +1628,7 @@ _ref = weatherReport("Berkeley, CA"), city = _ref[0], temp = _ref[1], forecast =
var city, futurists, name, street, _ref, _ref2; + futurists = { sculptor: "Umberto Boccioni", painter: "Vladimir Burliuk", @@ -1450,8 +1637,10 @@ futurists = { address: ["Via Roma 42R", "Bellagio, Italy 22021"] } }; -_ref = futurists.poet, name = _ref.name, _ref2 = _ref.address, street = _ref2[0], city = _ref2[1]; + +_ref = futurists.poet, name = _ref.name, (_ref2 = _ref.address, street = _ref2[0], city = _ref2[1]);
Destructuring assignment can even be combined with splats.
@@ -1473,12 +1664,17 @@ _ref = futurists.poet, name = _ref.name, _ref2 = _ref.address, street = _ref2[0]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++];
@@ -1506,6 +1702,7 @@ _ref = tag.split(""), open = _ref[0], contents = 3 <= _ref.length ? __slice.call @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; @@ -1533,13 +1730,16 @@ _ref = tag.split(""), open = _ref[0], contents = 3 <= _ref.length ? __slice.call
var hi; + hi = function() { return [document.title, "Hello JavaScript"].join(": "); };
@@ -1566,7 +1766,8 @@ hi = function() { go dancing when "Sun" then go church else go work -
switch (day) {
+
+switch (day) { case "Mon": go(work); break; @@ -1605,7 +1806,8 @@ hi = function() { finally cleanUp() -
try {
+
+try { allHellBreaksLoose(); catsAndDogsLivingTogether(); } catch (error) { @@ -1629,11 +1831,16 @@ healthy = 200var cholesterol, healthy; + cholesterol = 127; + healthy = (200 > cholesterol && cholesterol > 60);
+ +healthy = (200 > cholesterol && cholesterol > 60); +;alert(healthy);'>run: healthy
@@ -1649,13 +1856,20 @@ sentence = var author, quote, sentence; + author = "Wittgenstein"; + quote = "A picture is a fact. -- " + author; + sentence = "" + (22 / 7) + " is a decent approximation of π";
Multiline strings are allowed in CoffeeScript.
@@ -1668,9 +1882,12 @@ sentence = "" + (22 / 7) + " is a decent approximation of π";;alert(sentence);'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...";
Heredocs can be used to hold formatted or indentation-sensitive text (or, if you just don't feel like escaping quotes and apostrophes). The @@ -1685,8 +1902,12 @@ mobyDick = "Call me Ishmael. Some years ago -- never mind how long precisely --
var html; + html = '<strong>\n cup of coffeescript\n</strong>'; -
Double-quoted heredocs, like double-quoted strings, allow interpolation.
@@ -1702,10 +1923,13 @@ html = '< ### -/*
+
+/* CoffeeScript Compiler v1.1.2 Released under the MIT License */ + +
@@ -1729,6 +1953,7 @@ html = '<
- There are a number of excellent books and screencasts to help you get
+ There are a number of excellent books and screencasts to help you get
started with CoffeeScript, some of which are freely available online.
1.1.2
@@ -1966,24 +2194,24 @@ task('build:parser1.1.1
- Bugfix release for classes with external constructor functions, see
+ Bugfix release for classes with external constructor functions, see
issue #1182.
1.1.0
'build:parser
- source_fragment_prefix = "try_src:"
+ sourceFragment = "try:"
# Set up the compilation function, to run when you stop typing.
compileSource = ->
@@ -2481,7 +2709,7 @@ task('build:parservar OPERATOR;
+
OPERATOR = /^(?:[-=]>|[-+*\/%<>&|^!?=]=|>>>=?|([-+:])\1|([&|<>])\2=?|\?\.|\.{2,3})/;
@@ -1766,8 +1991,11 @@ task 'build:parser= 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');
@@ -1818,17 +2046,17 @@ task('build:parser
Books and Screencasts
-
+
If 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
+ The wiki also serves as a directory of handy
text editor extensions,
web framework plugins,
and general CoffeeScript build tools.
@@ -1956,7 +2184,7 @@ task('build:parser
Change Log
-
+