1
0
Fork 0
mirror of https://github.com/jashkenas/coffeescript.git synced 2022-11-09 12:23:24 -05:00

updating documentation for 0.3

This commit is contained in:
Jeremy Ashkenas 2010-01-26 23:23:59 -05:00
parent 3524d618d8
commit ca0a65ab95
14 changed files with 200 additions and 214 deletions

View file

@ -1,7 +1,7 @@
Gem::Specification.new do |s| Gem::Specification.new do |s|
s.name = 'coffee-script' s.name = 'coffee-script'
s.version = '0.2.6' # Keep version in sync with coffee-script.rb s.version = '0.3.0' # Keep version in sync with coffee-script.rb
s.date = '2010-1-17' s.date = '2010-1-26'
s.homepage = "http://jashkenas.github.com/coffee-script/" s.homepage = "http://jashkenas.github.com/coffee-script/"
s.summary = "The CoffeeScript Compiler" s.summary = "The CoffeeScript Compiler"

View file

@ -1,4 +0,0 @@
$('table.list').each (table) ->
$('tr.account', table).each (row) ->
row.show()
row.highlight()

View file

@ -26,4 +26,4 @@ race: (winner, runners...) ->
alert "I knew it!" if elvis? alert "I knew it!" if elvis?
# Array comprehensions: # Array comprehensions:
cubed_list: math.cube(num) for num in list cubed_list: math.cube num for num in list

View file

@ -0,0 +1 @@
lottery.draw_winner()?.address?.zipcode

View file

@ -1,6 +1,6 @@
gold: silver: the_field: "unknown" gold: silver: the_field: "unknown"
medalists: (first, second, rest...) -> award_medals: (first, second, rest...) ->
gold: first gold: first
silver: second silver: second
the_field: rest the_field: rest
@ -18,7 +18,7 @@ contenders: [
"Usain Bolt" "Usain Bolt"
] ]
medalists contenders... award_medals contenders...
alert "Gold: " + gold alert "Gold: " + gold
alert "Silver: " + silver alert "Silver: " + silver

View file

@ -51,7 +51,7 @@
<p> <p>
<b>Latest Version:</b> <b>Latest Version:</b>
<a href="http://gemcutter.org/gems/coffee-script">0.2.6</a> <a href="http://gemcutter.org/gems/coffee-script">0.3.0</a>
</p> </p>
<h2>Table of Contents</h2> <h2>Table of Contents</h2>
@ -65,7 +65,6 @@
<a href="#objects_and_arrays">Objects and Arrays</a><br /> <a href="#objects_and_arrays">Objects and Arrays</a><br />
<a href="#lexical_scope">Lexical Scoping and Variable Safety</a><br /> <a href="#lexical_scope">Lexical Scoping and Variable Safety</a><br />
<a href="#conditionals">Conditionals, Ternaries, and Conditional Assignment</a><br /> <a href="#conditionals">Conditionals, Ternaries, and Conditional Assignment</a><br />
<a href="#existence">The Existential Operator</a><br />
<a href="#aliases">Aliases</a><br /> <a href="#aliases">Aliases</a><br />
<a href="#splats">Splats...</a><br /> <a href="#splats">Splats...</a><br />
<a href="#arguments">Arguments are Arrays</a><br /> <a href="#arguments">Arguments are Arrays</a><br />
@ -73,17 +72,16 @@
<a href="#comprehensions">Comprehensions (Arrays, Objects, and Ranges)</a><br /> <a href="#comprehensions">Comprehensions (Arrays, Objects, and Ranges)</a><br />
<a href="#slice_splice">Array Slicing and Splicing with Ranges</a><br /> <a href="#slice_splice">Array Slicing and Splicing with Ranges</a><br />
<a href="#expressions">Everything is an Expression</a><br /> <a href="#expressions">Everything is an Expression</a><br />
<a href="#existence">The Existential Operator</a><br />
<a href="#inheritance">Inheritance, and Calling Super from a Subclass</a><br /> <a href="#inheritance">Inheritance, and Calling Super from a Subclass</a><br />
<a href="#blocks">Blocks</a><br />
<a href="#pattern_matching">Pattern Matching</a><br /> <a href="#pattern_matching">Pattern Matching</a><br />
<a href="#long_arrow">Function Binding</a><br /> <a href="#fat_arrow">Function Binding</a><br />
<a href="#embedded">Embedded JavaScript</a><br /> <a href="#embedded">Embedded JavaScript</a><br />
<a href="#switch">Switch/When/Else</a><br /> <a href="#switch">Switch/When/Else</a><br />
<a href="#try">Try/Catch/Finally</a><br /> <a href="#try">Try/Catch/Finally</a><br />
<a href="#comparisons">Chained Comparisons</a><br /> <a href="#comparisons">Chained Comparisons</a><br />
<a href="#strings">Multiline Strings and Heredocs</a><br /> <a href="#strings">Multiline Strings and Heredocs</a><br />
<a href="#resources">Resources</a><br /> <a href="#resources">Resources</a><br />
<a href="#contributing">Contributing</a><br />
<a href="#change_log">Change Log</a><br /> <a href="#change_log">Change Log</a><br />
</p> </p>
@ -188,7 +186,7 @@ gem install coffee-script</pre>
<td><code>-v, --verbose</code></td> <td><code>-v, --verbose</code></td>
<td> <td>
As the JavaScript is being generated, print out every step of code As the JavaScript is being generated, print out every step of code
generation, including lexical scope and the node in the generation, including lexical scope and the nodes in the
AST. AST.
</td> </td>
</tr> </tr>
@ -248,6 +246,11 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
use indentation. use indentation.
</p> </p>
<p>
You don't need to use parentheses to invoke a function, if you're passing
arguments:<br /><tt>print "coffee"</tt>
</p>
<p> <p>
You can use newlines to break up your expression into smaller pieces, You can use newlines to break up your expression into smaller pieces,
as long as CoffeeScript can determine that the line hasn't finished yet. as long as CoffeeScript can determine that the line hasn't finished yet.
@ -336,20 +339,6 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
truthy variables. truthy variables.
</p> </p>
<p id="existence">
<b class="header">The Existential Operator</b>
It's a little difficult to check for the existence of a variable in
JavaScript. <tt>if (variable) ...</tt> comes close, but fails for zero,
the empty string, and false. The existential operator <tt>?</tt> returns true unless
a variable is <b>null</b> or <b>undefined</b>, which makes it analogous
to Ruby's <tt>nil?</tt>
</p>
<p>
It can also be used for safer conditional assignment than <tt>||=</tt>
provides, for cases where you may be handling numbers or strings.
</p>
<%= code_for('existence', 'speed') %>
<p id="aliases"> <p id="aliases">
<b class="header">Aliases</b> <b class="header">Aliases</b>
Because the <tt>==</tt> operator frequently causes undesirable coercion, Because the <tt>==</tt> operator frequently causes undesirable coercion,
@ -492,6 +481,35 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
CoffeeScript won't try to perform the conversion. CoffeeScript won't try to perform the conversion.
</p> </p>
<p id="existence">
<b class="header">The Existential Operator</b>
It's a little difficult to check for the existence of a variable in
JavaScript. <tt>if (variable) ...</tt> comes close, but fails for zero,
the empty string, and false. CoffeeScript's existential operator <tt>?</tt> returns true unless
a variable is <b>null</b> or <b>undefined</b>, which makes it analogous
to Ruby's <tt>nil?</tt>
</p>
<p>
It can also be used for safer conditional assignment than <tt>||=</tt>
provides, for cases where you may be handling numbers or strings.
</p>
<%= code_for('existence', 'speed') %>
<p>
The accessor variant of the existential operator <tt>?.</tt> can be used to soak
up null references in a chain of properties. Use it instead
of the dot accessor <tt>.</tt> in cases where the base value may be <b>null</b>
or <b>undefined</b>. If all of the properties exist then you'll get the expected
result, if the chain is broken, <b>undefined</b> is returned instead of
the <b>TypeError</b> that would be raised otherwise.
</p>
<%= code_for('soaks') %>
<p>
Soaking up nulls is similar to Ruby's
<a href="http://andand.rubyforge.org/">andand gem</a>, and to the
<a href="http://groovy.codehaus.org/Operators#Operators-SafeNavigationOperator%28%3F.%29">safe navigation operator</a>
in Groovy.
</p>
<p id="inheritance"> <p id="inheritance">
<b class="header">Inheritance, and Calling Super from a Subclass</b> <b class="header">Inheritance, and Calling Super from a Subclass</b>
JavaScript's prototypal inheritance has always been a bit of a JavaScript's prototypal inheritance has always been a bit of a
@ -514,15 +532,6 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
</p> </p>
<%= code_for('super', true) %> <%= code_for('super', true) %>
<p id="blocks">
<b class="header">Blocks</b>
Many common looping functions (in Prototype, jQuery, and Underscore,
for example) take a single function as their final argument. To make
final functions easier to pass, CoffeeScript includes block syntax,
so you don't have to close the parentheses on the other side.
</p>
<%= code_for('blocks') %>
<p id="pattern_matching"> <p id="pattern_matching">
<b class="header">Pattern Matching (Destructuring Assignment)</b> <b class="header">Pattern Matching (Destructuring Assignment)</b>
To make extracting values from complex arrays and objects more convenient, To make extracting values from complex arrays and objects more convenient,
@ -545,16 +554,16 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
</p> </p>
<%= code_for('object_extraction', 'poet + " — " + street') %> <%= code_for('object_extraction', 'poet + " — " + street') %>
<p id="long_arrow"> <p id="fat_arrow">
<b class="header">Function binding</b> <b class="header">Function binding</b>
The long arrow <tt>=></tt> can be used to both define a function, and to bind The fat arrow <tt>=></tt> can be used to both define a function, and to bind
it to the current value of <tt>this</tt>, right on the spot. This is helpful it to the current value of <tt>this</tt>, right on the spot. This is helpful
when using callback-based libraries like Prototype or jQuery, for creating when using callback-based libraries like Prototype or jQuery, for creating
iterator functions to pass to <tt>each</tt>, or event-handler functions iterator functions to pass to <tt>each</tt>, or event-handler functions
to use with <tt>bind</tt>. Functions created with the long arrow are able to access to use with <tt>bind</tt>. Functions created with the fat arrow are able to access
properties of the <tt>this</tt> where they're defined. properties of the <tt>this</tt> where they're defined.
</p> </p>
<%= code_for('long_arrow') %> <%= code_for('fat_arrow') %>
<p id="embedded"> <p id="embedded">
<b class="header">Embedded JavaScript</b> <b class="header">Embedded JavaScript</b>
@ -625,6 +634,12 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
<li> <li>
<a href="http://github.com/jashkenas/coffee-script/issues">Bugs, Feature Requests, and General Discussion</a> <a href="http://github.com/jashkenas/coffee-script/issues">Bugs, Feature Requests, and General Discussion</a>
</li> </li>
<li>
<a href="http://github.com/creationix/coffeepot">CoffeePot</a><br />
An implementation of CoffeeScript, written in CoffeeScript, by
<a href="http://github.com/creationix">Tim Caswell</a>. Compiles just
a limited subset at this point.
</li>
<li> <li>
<a href="http://github.com/jnicklas/bistro_car">BistroCar</a><br /> <a href="http://github.com/jnicklas/bistro_car">BistroCar</a><br />
A Rails plugin by A Rails plugin by
@ -640,39 +655,24 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
</li> </li>
</ul> </ul>
<h2 id="contributing">Contributing</h2> <h2 id="change_log">Change Log</h2>
<p> <p>
Here's a wish list of things that would be wonderful to have contributed: <b class="header" style="margin-top: 20px;">0.3.0</b>
CoffeeScript 0.3 includes major syntax changes:
<br />
The function symbol was changed to
<tt>-></tt>, and the bound function symbol is now <tt>=></tt>.
<br />
Parameter lists in function definitions must now be wrapped in parentheses.
<br />
Added property soaking, with the <tt>?.</tt> operator.
<br />
Made parentheses optional, when invoking functions with arguments.
<br />
Removed the obsolete block literal syntax.
</p> </p>
<ul>
<li>
<a href="http://github.com/jashkenas/coffee-script/issues#issue/8">
A CoffeeScript version of the compiler.
</a>
</li>
<li>
Test cases for any syntax errors you encounter that you think CoffeeScript
should be able to compile properly.
</li>
<li>
A tutorial that introduces CoffeeScript from the ground up for folks
without knowledge of JavaScript.
</li>
<li>
Integration with Processing.js's JavaScript API (this would depend on
having a JavaScript version of the compiler).
</li>
<li>
A lot of the code generation in <tt>nodes.rb</tt> gets into messy
string manipulation. Techniques for cleaning this up across the board
would be appreciated.
</li>
</ul>
<h2 id="change_log">Change Log</h2>
<p> <p>
<b class="header" style="margin-top: 20px;">0.2.6</b> <b class="header" style="margin-top: 20px;">0.2.6</b>
Added Python-style chained comparisons, the conditional existence Added Python-style chained comparisons, the conditional existence

View file

@ -1,8 +0,0 @@
(function(){
$('table.list').each(function(table) {
return $('tr.account', table).each(function(row) {
row.show();
return row.highlight();
});
});
})();

View file

@ -0,0 +1,4 @@
(function(){
var __a;
((__a = lottery.draw_winner()) == undefined ? undefined : __a.address == undefined ? undefined : __a.address.zipcode);
})();

View file

@ -1,7 +1,7 @@
(function(){ (function(){
var contenders, gold, medalists, silver, the_field; var award_medals, contenders, gold, silver, the_field;
gold = (silver = (the_field = "unknown")); gold = (silver = (the_field = "unknown"));
medalists = function medalists(first, second) { award_medals = function award_medals(first, second) {
var rest; var rest;
rest = Array.prototype.slice.call(arguments, 2); rest = Array.prototype.slice.call(arguments, 2);
gold = first; gold = first;
@ -9,7 +9,7 @@
return the_field = rest; return the_field = rest;
}; };
contenders = ["Michael Phelps", "Liu Xiang", "Yao Ming", "Allyson Felix", "Shawn Johnson", "Roman Sebrle", "Guo Jingjing", "Tyson Gay", "Asafa Powell", "Usain Bolt"]; contenders = ["Michael Phelps", "Liu Xiang", "Yao Ming", "Allyson Felix", "Shawn Johnson", "Roman Sebrle", "Guo Jingjing", "Tyson Gay", "Asafa Powell", "Usain Bolt"];
medalists.apply(this, contenders); award_medals.apply(this, contenders);
alert("Gold: " + gold); alert("Gold: " + gold);
alert("Silver: " + silver); alert("Silver: " + silver);
alert("The Field: " + the_field); alert("The Field: " + the_field);

View file

@ -37,7 +37,7 @@
<p> <p>
<b>Latest Version:</b> <b>Latest Version:</b>
<a href="http://gemcutter.org/gems/coffee-script">0.2.6</a> <a href="http://gemcutter.org/gems/coffee-script">0.3.0</a>
</p> </p>
<h2>Table of Contents</h2> <h2>Table of Contents</h2>
@ -51,7 +51,6 @@
<a href="#objects_and_arrays">Objects and Arrays</a><br /> <a href="#objects_and_arrays">Objects and Arrays</a><br />
<a href="#lexical_scope">Lexical Scoping and Variable Safety</a><br /> <a href="#lexical_scope">Lexical Scoping and Variable Safety</a><br />
<a href="#conditionals">Conditionals, Ternaries, and Conditional Assignment</a><br /> <a href="#conditionals">Conditionals, Ternaries, and Conditional Assignment</a><br />
<a href="#existence">The Existential Operator</a><br />
<a href="#aliases">Aliases</a><br /> <a href="#aliases">Aliases</a><br />
<a href="#splats">Splats...</a><br /> <a href="#splats">Splats...</a><br />
<a href="#arguments">Arguments are Arrays</a><br /> <a href="#arguments">Arguments are Arrays</a><br />
@ -59,17 +58,16 @@
<a href="#comprehensions">Comprehensions (Arrays, Objects, and Ranges)</a><br /> <a href="#comprehensions">Comprehensions (Arrays, Objects, and Ranges)</a><br />
<a href="#slice_splice">Array Slicing and Splicing with Ranges</a><br /> <a href="#slice_splice">Array Slicing and Splicing with Ranges</a><br />
<a href="#expressions">Everything is an Expression</a><br /> <a href="#expressions">Everything is an Expression</a><br />
<a href="#existence">The Existential Operator</a><br />
<a href="#inheritance">Inheritance, and Calling Super from a Subclass</a><br /> <a href="#inheritance">Inheritance, and Calling Super from a Subclass</a><br />
<a href="#blocks">Blocks</a><br />
<a href="#pattern_matching">Pattern Matching</a><br /> <a href="#pattern_matching">Pattern Matching</a><br />
<a href="#long_arrow">Function Binding</a><br /> <a href="#fat_arrow">Function Binding</a><br />
<a href="#embedded">Embedded JavaScript</a><br /> <a href="#embedded">Embedded JavaScript</a><br />
<a href="#switch">Switch/When/Else</a><br /> <a href="#switch">Switch/When/Else</a><br />
<a href="#try">Try/Catch/Finally</a><br /> <a href="#try">Try/Catch/Finally</a><br />
<a href="#comparisons">Chained Comparisons</a><br /> <a href="#comparisons">Chained Comparisons</a><br />
<a href="#strings">Multiline Strings and Heredocs</a><br /> <a href="#strings">Multiline Strings and Heredocs</a><br />
<a href="#resources">Resources</a><br /> <a href="#resources">Resources</a><br />
<a href="#contributing">Contributing</a><br />
<a href="#change_log">Change Log</a><br /> <a href="#change_log">Change Log</a><br />
</p> </p>
@ -85,7 +83,7 @@
<span class="FunctionName">number</span><span class="Keyword">:</span> <span class="Keyword">-</span><span class="Number">42</span> <span class="Keyword">if</span> opposite_day <span class="FunctionName">number</span><span class="Keyword">:</span> <span class="Keyword">-</span><span class="Number">42</span> <span class="Keyword">if</span> opposite_day
<span class="Comment"><span class="Comment">#</span> Functions:</span> <span class="Comment"><span class="Comment">#</span> Functions:</span>
<span class="FunctionName">square</span><span class="Keyword">:</span> (x) <span class="Storage">=&gt;</span> x <span class="Keyword">*</span> x <span class="FunctionName">square</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">x</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span> x <span class="Keyword">*</span> x
<span class="Comment"><span class="Comment">#</span> Arrays:</span> <span class="Comment"><span class="Comment">#</span> Arrays:</span>
<span class="FunctionName">list</span><span class="Keyword">:</span> [<span class="Number">1</span>, <span class="Number">2</span>, <span class="Number">3</span>, <span class="Number">4</span>, <span class="Number">5</span>] <span class="FunctionName">list</span><span class="Keyword">:</span> [<span class="Number">1</span>, <span class="Number">2</span>, <span class="Number">3</span>, <span class="Number">4</span>, <span class="Number">5</span>]
@ -94,18 +92,18 @@
<span class="FunctionName">math</span><span class="Keyword">:</span> { <span class="FunctionName">math</span><span class="Keyword">:</span> {
<span class="FunctionName">root</span><span class="Keyword">:</span> Math.sqrt <span class="FunctionName">root</span><span class="Keyword">:</span> Math.sqrt
<span class="FunctionName">square</span><span class="Keyword">:</span> square <span class="FunctionName">square</span><span class="Keyword">:</span> square
<span class="FunctionName">cube</span><span class="Keyword">:</span> (x) <span class="Storage">=&gt;</span> x <span class="Keyword">*</span> square x <span class="FunctionName">cube</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">x</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span> x <span class="Keyword">*</span> square x
} }
<span class="Comment"><span class="Comment">#</span> Splats:</span> <span class="Comment"><span class="Comment">#</span> Splats:</span>
<span class="FunctionName">race</span><span class="Keyword">:</span> (winner, runners...) <span class="Storage">=&gt;</span> <span class="FunctionName">race</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">winner, runners...</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
print winner, runners print winner, runners
<span class="Comment"><span class="Comment">#</span> Existence:</span> <span class="Comment"><span class="Comment">#</span> Existence:</span>
alert <span class="String"><span class="String">&quot;</span>I knew it!<span class="String">&quot;</span></span> <span class="Keyword">if</span> elvis<span class="Keyword">?</span> alert <span class="String"><span class="String">&quot;</span>I knew it!<span class="String">&quot;</span></span> <span class="Keyword">if</span> elvis<span class="Keyword">?</span>
<span class="Comment"><span class="Comment">#</span> Array comprehensions:</span> <span class="Comment"><span class="Comment">#</span> Array comprehensions:</span>
<span class="FunctionName">cubed_list</span><span class="Keyword">:</span> math.cube(num) <span class="Keyword">for</span> num <span class="Keyword">in</span> list <span class="FunctionName">cubed_list</span><span class="Keyword">:</span> math.cube num <span class="Keyword">for</span> num <span class="Keyword">in</span> list
</pre><pre class="idle"><span class="Storage">var</span> __a, __b, __c, cubed_list, list, math, num, number, opposite_day, race, square; </pre><pre class="idle"><span class="Storage">var</span> __a, __b, __c, cubed_list, list, math, num, number, opposite_day, race, square;
<span class="Comment"><span class="Comment">//</span> Assignment:</span> <span class="Comment"><span class="Comment">//</span> Assignment:</span>
number <span class="Keyword">=</span> <span class="Number">42</span>; number <span class="Keyword">=</span> <span class="Number">42</span>;
@ -285,7 +283,7 @@ gem install coffee-script</pre>
<td><code>-v, --verbose</code></td> <td><code>-v, --verbose</code></td>
<td> <td>
As the JavaScript is being generated, print out every step of code As the JavaScript is being generated, print out every step of code
generation, including lexical scope and the node in the generation, including lexical scope and the nodes in the
AST. AST.
</td> </td>
</tr> </tr>
@ -345,6 +343,11 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
use indentation. use indentation.
</p> </p>
<p>
You don't need to use parentheses to invoke a function, if you're passing
arguments:<br /><tt>print "coffee"</tt>
</p>
<p> <p>
You can use newlines to break up your expression into smaller pieces, You can use newlines to break up your expression into smaller pieces,
as long as CoffeeScript can determine that the line hasn't finished yet. as long as CoffeeScript can determine that the line hasn't finished yet.
@ -356,8 +359,8 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
function body. The empty function looks like this: <tt>-></tt>. All function body. The empty function looks like this: <tt>-></tt>. All
functions in CoffeeScript are named by default, for easier debugging. functions in CoffeeScript are named by default, for easier debugging.
</p> </p>
<div class='code'><pre class="idle"><span class="FunctionName">square</span><span class="Keyword">:</span> (x) <span class="Storage">=&gt;</span> x <span class="Keyword">*</span> x <div class='code'><pre class="idle"><span class="FunctionName">square</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">x</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span> x <span class="Keyword">*</span> x
<span class="FunctionName">cube</span><span class="Keyword">:</span> (x) <span class="Storage">=&gt;</span> square(x) <span class="Keyword">*</span> x <span class="FunctionName">cube</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">x</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span> square(x) <span class="Keyword">*</span> x
</pre><pre class="idle"><span class="Storage">var</span> cube, square; </pre><pre class="idle"><span class="Storage">var</span> cube, square;
square <span class="Keyword">=</span> <span class="Storage">function</span> <span class="FunctionName">square</span>(<span class="FunctionArgument">x</span>) { square <span class="Keyword">=</span> <span class="Storage">function</span> <span class="FunctionName">square</span>(<span class="FunctionArgument">x</span>) {
<span class="Keyword">return</span> x <span class="Keyword">*</span> x; <span class="Keyword">return</span> x <span class="Keyword">*</span> x;
@ -444,7 +447,7 @@ matrix = [1, 0, 1, 0, 0, 1, 1, 1, 0];
<tt>var</tt> yourself. <tt>var</tt> yourself.
</p> </p>
<div class='code'><pre class="idle"><span class="FunctionName">num</span><span class="Keyword">:</span> <span class="Number">1</span> <div class='code'><pre class="idle"><span class="FunctionName">num</span><span class="Keyword">:</span> <span class="Number">1</span>
<span class="FunctionName">change_numbers</span><span class="Keyword">:</span> () <span class="Storage">=&gt;</span> <span class="FunctionName">change_numbers</span><span class="Keyword">:</span> <span class="Storage">-&gt;</span>
<span class="FunctionName">new_num</span><span class="Keyword">:</span> <span class="Keyword">-</span><span class="Number">1</span> <span class="FunctionName">new_num</span><span class="Keyword">:</span> <span class="Keyword">-</span><span class="Number">1</span>
<span class="FunctionName">num</span><span class="Keyword">:</span> <span class="Number">10</span> <span class="FunctionName">num</span><span class="Keyword">:</span> <span class="Number">10</span>
<span class="FunctionName">new_num</span><span class="Keyword">:</span> change_numbers() <span class="FunctionName">new_num</span><span class="Keyword">:</span> change_numbers()
@ -526,38 +529,6 @@ expensive <span class="Keyword">=</span> expensive <span class="Keyword">||</spa
truthy variables. truthy variables.
</p> </p>
<p id="existence">
<b class="header">The Existential Operator</b>
It's a little difficult to check for the existence of a variable in
JavaScript. <tt>if (variable) ...</tt> comes close, but fails for zero,
the empty string, and false. The existential operator <tt>?</tt> returns true unless
a variable is <b>null</b> or <b>undefined</b>, which makes it analogous
to Ruby's <tt>nil?</tt>
</p>
<p>
It can also be used for safer conditional assignment than <tt>||=</tt>
provides, for cases where you may be handling numbers or strings.
</p>
<div class='code'><pre class="idle"><span class="FunctionName">solipsism</span><span class="Keyword">:</span> <span class="BuiltInConstant">true</span> <span class="Keyword">if</span> mind<span class="Keyword">?</span> <span class="Keyword">and</span> <span class="Keyword">not</span> world<span class="Keyword">?</span>
speed <span class="Keyword">?</span><span class="Keyword">=</span> <span class="Number">140</span>
</pre><pre class="idle"><span class="Storage">var</span> solipsism, speed;
<span class="Keyword">if</span> ((<span class="Keyword">typeof</span> mind <span class="Keyword">!</span><span class="Keyword">==</span> <span class="String"><span class="String">&quot;</span>undefined<span class="String">&quot;</span></span> <span class="Keyword">&amp;</span><span class="Keyword">&amp;</span> mind <span class="Keyword">!</span><span class="Keyword">==</span> <span class="BuiltInConstant">null</span>) <span class="Keyword">&amp;</span><span class="Keyword">&amp;</span> <span class="Keyword">!</span>(<span class="Keyword">typeof</span> world <span class="Keyword">!</span><span class="Keyword">==</span> <span class="String"><span class="String">&quot;</span>undefined<span class="String">&quot;</span></span> <span class="Keyword">&amp;</span><span class="Keyword">&amp;</span> world <span class="Keyword">!</span><span class="Keyword">==</span> <span class="BuiltInConstant">null</span>)) {
solipsism <span class="Keyword">=</span> <span class="BuiltInConstant">true</span>;
}
speed <span class="Keyword">=</span> (<span class="Keyword">typeof</span> speed <span class="Keyword">!</span><span class="Keyword">==</span> <span class="String"><span class="String">&quot;</span>undefined<span class="String">&quot;</span></span> <span class="Keyword">&amp;</span><span class="Keyword">&amp;</span> speed <span class="Keyword">!</span><span class="Keyword">==</span> <span class="BuiltInConstant">null</span>) ? speed : <span class="Number">140</span>;
</pre><button onclick='javascript: var solipsism, speed;
if ((typeof mind !== "undefined" && mind !== null) && !(typeof world !== "undefined" && world !== null)) {
solipsism = true;
}
speed = (typeof speed !== "undefined" && speed !== null) ? speed : 140;
;alert(speed);'>run: speed</button><br class='clear' /></div>
<p id="aliases"> <p id="aliases">
<b class="header">Aliases</b> <b class="header">Aliases</b>
Because the <tt>==</tt> operator frequently causes undesirable coercion, Because the <tt>==</tt> operator frequently causes undesirable coercion,
@ -615,7 +586,7 @@ car.speed <span class="Keyword">&lt;</span> speed_limit ? accelerate() : <span c
</p> </p>
<div class='code'><pre class="idle"><span class="FunctionName">gold</span><span class="Keyword">:</span> <span class="FunctionName">silver</span><span class="Keyword">:</span> <span class="FunctionName">the_field</span><span class="Keyword">:</span> <span class="String"><span class="String">&quot;</span>unknown<span class="String">&quot;</span></span> <div class='code'><pre class="idle"><span class="FunctionName">gold</span><span class="Keyword">:</span> <span class="FunctionName">silver</span><span class="Keyword">:</span> <span class="FunctionName">the_field</span><span class="Keyword">:</span> <span class="String"><span class="String">&quot;</span>unknown<span class="String">&quot;</span></span>
<span class="FunctionName">medalists</span><span class="Keyword">:</span> (first, second, rest...) <span class="Storage">=&gt;</span> <span class="FunctionName">award_medals</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">first, second, rest...</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="FunctionName">gold</span><span class="Keyword">:</span> first <span class="FunctionName">gold</span><span class="Keyword">:</span> first
<span class="FunctionName">silver</span><span class="Keyword">:</span> second <span class="FunctionName">silver</span><span class="Keyword">:</span> second
<span class="FunctionName">the_field</span><span class="Keyword">:</span> rest <span class="FunctionName">the_field</span><span class="Keyword">:</span> rest
@ -633,14 +604,14 @@ car.speed <span class="Keyword">&lt;</span> speed_limit ? accelerate() : <span c
<span class="String"><span class="String">&quot;</span>Usain Bolt<span class="String">&quot;</span></span> <span class="String"><span class="String">&quot;</span>Usain Bolt<span class="String">&quot;</span></span>
] ]
medalists contenders... award_medals contenders...
alert <span class="String"><span class="String">&quot;</span>Gold: <span class="String">&quot;</span></span> <span class="Keyword">+</span> gold alert <span class="String"><span class="String">&quot;</span>Gold: <span class="String">&quot;</span></span> <span class="Keyword">+</span> gold
alert <span class="String"><span class="String">&quot;</span>Silver: <span class="String">&quot;</span></span> <span class="Keyword">+</span> silver alert <span class="String"><span class="String">&quot;</span>Silver: <span class="String">&quot;</span></span> <span class="Keyword">+</span> silver
alert <span class="String"><span class="String">&quot;</span>The Field: <span class="String">&quot;</span></span> <span class="Keyword">+</span> the_field alert <span class="String"><span class="String">&quot;</span>The Field: <span class="String">&quot;</span></span> <span class="Keyword">+</span> the_field
</pre><pre class="idle"><span class="Storage">var</span> contenders, gold, medalists, silver, the_field; </pre><pre class="idle"><span class="Storage">var</span> award_medals, contenders, gold, silver, the_field;
gold <span class="Keyword">=</span> (silver <span class="Keyword">=</span> (the_field <span class="Keyword">=</span> <span class="String"><span class="String">&quot;</span>unknown<span class="String">&quot;</span></span>)); gold <span class="Keyword">=</span> (silver <span class="Keyword">=</span> (the_field <span class="Keyword">=</span> <span class="String"><span class="String">&quot;</span>unknown<span class="String">&quot;</span></span>));
medalists <span class="Keyword">=</span> <span class="Storage">function</span> <span class="FunctionName">medalists</span>(<span class="FunctionArgument">first, second</span>) { award_medals <span class="Keyword">=</span> <span class="Storage">function</span> <span class="FunctionName">award_medals</span>(<span class="FunctionArgument">first, second</span>) {
<span class="Storage">var</span> rest; <span class="Storage">var</span> rest;
rest <span class="Keyword">=</span> <span class="LibraryClassType">Array</span>.<span class="LibraryConstant">prototype</span>.slice.<span class="LibraryFunction">call</span>(arguments, <span class="Number">2</span>); rest <span class="Keyword">=</span> <span class="LibraryClassType">Array</span>.<span class="LibraryConstant">prototype</span>.slice.<span class="LibraryFunction">call</span>(arguments, <span class="Number">2</span>);
gold <span class="Keyword">=</span> first; gold <span class="Keyword">=</span> first;
@ -648,13 +619,13 @@ medalists <span class="Keyword">=</span> <span class="Storage">function</span> <
<span class="Keyword">return</span> the_field <span class="Keyword">=</span> rest; <span class="Keyword">return</span> the_field <span class="Keyword">=</span> rest;
}; };
contenders <span class="Keyword">=</span> [<span class="String"><span class="String">&quot;</span>Michael Phelps<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>Liu Xiang<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>Yao Ming<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>Allyson Felix<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>Shawn Johnson<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>Roman Sebrle<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>Guo Jingjing<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>Tyson Gay<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>Asafa Powell<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>Usain Bolt<span class="String">&quot;</span></span>]; contenders <span class="Keyword">=</span> [<span class="String"><span class="String">&quot;</span>Michael Phelps<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>Liu Xiang<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>Yao Ming<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>Allyson Felix<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>Shawn Johnson<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>Roman Sebrle<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>Guo Jingjing<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>Tyson Gay<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>Asafa Powell<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>Usain Bolt<span class="String">&quot;</span></span>];
medalists.<span class="LibraryFunction">apply</span>(<span class="Variable">this</span>, contenders); award_medals.<span class="LibraryFunction">apply</span>(<span class="Variable">this</span>, contenders);
<span class="LibraryFunction">alert</span>(<span class="String"><span class="String">&quot;</span>Gold: <span class="String">&quot;</span></span> <span class="Keyword">+</span> gold); <span class="LibraryFunction">alert</span>(<span class="String"><span class="String">&quot;</span>Gold: <span class="String">&quot;</span></span> <span class="Keyword">+</span> gold);
<span class="LibraryFunction">alert</span>(<span class="String"><span class="String">&quot;</span>Silver: <span class="String">&quot;</span></span> <span class="Keyword">+</span> silver); <span class="LibraryFunction">alert</span>(<span class="String"><span class="String">&quot;</span>Silver: <span class="String">&quot;</span></span> <span class="Keyword">+</span> silver);
<span class="LibraryFunction">alert</span>(<span class="String"><span class="String">&quot;</span>The Field: <span class="String">&quot;</span></span> <span class="Keyword">+</span> the_field); <span class="LibraryFunction">alert</span>(<span class="String"><span class="String">&quot;</span>The Field: <span class="String">&quot;</span></span> <span class="Keyword">+</span> the_field);
</pre><button onclick='javascript: var contenders, gold, medalists, silver, the_field; </pre><button onclick='javascript: var award_medals, contenders, gold, silver, the_field;
gold = (silver = (the_field = "unknown")); gold = (silver = (the_field = "unknown"));
medalists = function medalists(first, second) { award_medals = function award_medals(first, second) {
var rest; var rest;
rest = Array.prototype.slice.call(arguments, 2); rest = Array.prototype.slice.call(arguments, 2);
gold = first; gold = first;
@ -662,7 +633,7 @@ medalists = function medalists(first, second) {
return the_field = rest; return the_field = rest;
}; };
contenders = ["Michael Phelps", "Liu Xiang", "Yao Ming", "Allyson Felix", "Shawn Johnson", "Roman Sebrle", "Guo Jingjing", "Tyson Gay", "Asafa Powell", "Usain Bolt"]; contenders = ["Michael Phelps", "Liu Xiang", "Yao Ming", "Allyson Felix", "Shawn Johnson", "Roman Sebrle", "Guo Jingjing", "Tyson Gay", "Asafa Powell", "Usain Bolt"];
medalists.apply(this, contenders); award_medals.apply(this, contenders);
alert("Gold: " + gold); alert("Gold: " + gold);
alert("Silver: " + silver); alert("Silver: " + silver);
alert("The Field: " + the_field); alert("The Field: " + the_field);
@ -675,7 +646,7 @@ alert("The Field: " + the_field);
<a href="https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Objects/Array">Array methods</a> <a href="https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Objects/Array">Array methods</a>
available. available.
</p> </p>
<div class='code'><pre class="idle"><span class="FunctionName">backwards</span><span class="Keyword">:</span> () <span class="Storage">=&gt;</span> <div class='code'><pre class="idle"><span class="FunctionName">backwards</span><span class="Keyword">:</span> <span class="Storage">-&gt;</span>
alert arguments.reverse() alert arguments.reverse()
backwards <span class="String"><span class="String">&quot;</span>stairway<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>to<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>heaven<span class="String">&quot;</span></span> backwards <span class="String"><span class="String">&quot;</span>stairway<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>to<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>heaven<span class="String">&quot;</span></span>
@ -807,7 +778,7 @@ __d <span class="Keyword">=</span> asteroids;
</p> </p>
<div class='code'><pre class="idle"><span class="FunctionName">countdown</span><span class="Keyword">:</span> num <span class="Keyword">for</span> num <span class="Keyword">in</span> [<span class="Number">10</span>..<span class="Number">1</span>] <div class='code'><pre class="idle"><span class="FunctionName">countdown</span><span class="Keyword">:</span> num <span class="Keyword">for</span> num <span class="Keyword">in</span> [<span class="Number">10</span>..<span class="Number">1</span>]
<span class="FunctionName">egg_delivery</span><span class="Keyword">:</span> () <span class="Storage">=&gt;</span> <span class="FunctionName">egg_delivery</span><span class="Keyword">:</span> <span class="Storage">-&gt;</span>
<span class="Keyword">for</span> i <span class="Keyword">in</span> [<span class="Number">0</span>...eggs.length] <span class="Keyword">by</span> <span class="Number">12</span> <span class="Keyword">for</span> i <span class="Keyword">in</span> [<span class="Number">0</span>...eggs.length] <span class="Keyword">by</span> <span class="Number">12</span>
<span class="FunctionName">dozen_eggs</span><span class="Keyword">:</span> eggs[i...i<span class="Keyword">+</span><span class="Number">12</span>] <span class="FunctionName">dozen_eggs</span><span class="Keyword">:</span> eggs[i...i<span class="Keyword">+</span><span class="Number">12</span>]
deliver <span class="Keyword">new</span> <span class="TypeName">egg_carton</span>(dozen) deliver <span class="Keyword">new</span> <span class="TypeName">egg_carton</span>(dozen)
@ -945,7 +916,7 @@ numbers.splice.apply(numbers, [3, 6 - 3 + 1].concat([-3, -4, -5, -6]));
pushed down into each possible branch of execution, in the function pushed down into each possible branch of execution, in the function
below. below.
</p> </p>
<div class='code'><pre class="idle"><span class="FunctionName">grade</span><span class="Keyword">:</span> (student) <span class="Storage">=&gt;</span> <div class='code'><pre class="idle"><span class="FunctionName">grade</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">student</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="Keyword">if</span> student.excellent_work <span class="Keyword">if</span> student.excellent_work
<span class="String"><span class="String">&quot;</span>A+<span class="String">&quot;</span></span> <span class="String"><span class="String">&quot;</span>A+<span class="String">&quot;</span></span>
<span class="Keyword">else</span> <span class="Keyword">if</span> student.okay_stuff <span class="Keyword">else</span> <span class="Keyword">if</span> student.okay_stuff
@ -1058,6 +1029,56 @@ globals = ((function() {
CoffeeScript won't try to perform the conversion. CoffeeScript won't try to perform the conversion.
</p> </p>
<p id="existence">
<b class="header">The Existential Operator</b>
It's a little difficult to check for the existence of a variable in
JavaScript. <tt>if (variable) ...</tt> comes close, but fails for zero,
the empty string, and false. CoffeeScript's existential operator <tt>?</tt> returns true unless
a variable is <b>null</b> or <b>undefined</b>, which makes it analogous
to Ruby's <tt>nil?</tt>
</p>
<p>
It can also be used for safer conditional assignment than <tt>||=</tt>
provides, for cases where you may be handling numbers or strings.
</p>
<div class='code'><pre class="idle"><span class="FunctionName">solipsism</span><span class="Keyword">:</span> <span class="BuiltInConstant">true</span> <span class="Keyword">if</span> mind<span class="Keyword">?</span> <span class="Keyword">and</span> <span class="Keyword">not</span> world<span class="Keyword">?</span>
speed <span class="Keyword">?</span><span class="Keyword">=</span> <span class="Number">140</span>
</pre><pre class="idle"><span class="Storage">var</span> solipsism, speed;
<span class="Keyword">if</span> ((<span class="Keyword">typeof</span> mind <span class="Keyword">!</span><span class="Keyword">==</span> <span class="String"><span class="String">&quot;</span>undefined<span class="String">&quot;</span></span> <span class="Keyword">&amp;</span><span class="Keyword">&amp;</span> mind <span class="Keyword">!</span><span class="Keyword">==</span> <span class="BuiltInConstant">null</span>) <span class="Keyword">&amp;</span><span class="Keyword">&amp;</span> <span class="Keyword">!</span>(<span class="Keyword">typeof</span> world <span class="Keyword">!</span><span class="Keyword">==</span> <span class="String"><span class="String">&quot;</span>undefined<span class="String">&quot;</span></span> <span class="Keyword">&amp;</span><span class="Keyword">&amp;</span> world <span class="Keyword">!</span><span class="Keyword">==</span> <span class="BuiltInConstant">null</span>)) {
solipsism <span class="Keyword">=</span> <span class="BuiltInConstant">true</span>;
}
speed <span class="Keyword">=</span> (<span class="Keyword">typeof</span> speed <span class="Keyword">!</span><span class="Keyword">==</span> <span class="String"><span class="String">&quot;</span>undefined<span class="String">&quot;</span></span> <span class="Keyword">&amp;</span><span class="Keyword">&amp;</span> speed <span class="Keyword">!</span><span class="Keyword">==</span> <span class="BuiltInConstant">null</span>) ? speed : <span class="Number">140</span>;
</pre><button onclick='javascript: var solipsism, speed;
if ((typeof mind !== "undefined" && mind !== null) && !(typeof world !== "undefined" && world !== null)) {
solipsism = true;
}
speed = (typeof speed !== "undefined" && speed !== null) ? speed : 140;
;alert(speed);'>run: speed</button><br class='clear' /></div>
<p>
The accessor variant of the existential operator <tt>?.</tt> can be used to soak
up null references in a chain of properties. Use it instead
of the dot accessor <tt>.</tt> in cases where the base value may be <b>null</b>
or <b>undefined</b>. If all of the properties exist then you'll get the expected
result, if the chain is broken, <b>undefined</b> is returned instead of
the <b>TypeError</b> that would be raised otherwise.
</p>
<div class='code'><pre class="idle">lottery.draw_winner()<span class="Keyword">?</span>.address<span class="Keyword">?</span>.zipcode
</pre><pre class="idle"><span class="Storage">var</span> __a;
((__a <span class="Keyword">=</span> lottery.draw_winner()) <span class="Keyword">==</span> undefined ? undefined : __a.address <span class="Keyword">==</span> undefined ? undefined : __a.address.zipcode);
</pre><br class='clear' /></div>
<p>
Soaking up nulls is similar to Ruby's
<a href="http://andand.rubyforge.org/">andand gem</a>, and to the
<a href="http://groovy.codehaus.org/Operators#Operators-SafeNavigationOperator%28%3F.%29">safe navigation operator</a>
in Groovy.
</p>
<p id="inheritance"> <p id="inheritance">
<b class="header">Inheritance, and Calling Super from a Subclass</b> <b class="header">Inheritance, and Calling Super from a Subclass</b>
JavaScript's prototypal inheritance has always been a bit of a JavaScript's prototypal inheritance has always been a bit of a
@ -1078,19 +1099,19 @@ globals = ((function() {
object's prototype, and converts <tt>super()</tt> into a call against object's prototype, and converts <tt>super()</tt> into a call against
the immediate ancestor's method of the same name. the immediate ancestor's method of the same name.
</p> </p>
<div class='code'><pre class="idle"><span class="FunctionName">Animal</span><span class="Keyword">:</span> () <span class="Storage">=&gt;</span> <div class='code'><pre class="idle"><span class="FunctionName">Animal</span><span class="Keyword">:</span> <span class="Storage">-&gt;</span>
<span class="FunctionName">Animal::move</span><span class="Keyword">:</span> (meters) <span class="Storage">=&gt;</span> <span class="FunctionName">Animal::move</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">meters</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
alert <span class="Variable">this</span>.name <span class="Keyword">+</span> <span class="String"><span class="String">&quot;</span> moved <span class="String">&quot;</span></span> <span class="Keyword">+</span> meters <span class="Keyword">+</span> <span class="String"><span class="String">&quot;</span>m.<span class="String">&quot;</span></span> alert <span class="Variable">this</span>.name <span class="Keyword">+</span> <span class="String"><span class="String">&quot;</span> moved <span class="String">&quot;</span></span> <span class="Keyword">+</span> meters <span class="Keyword">+</span> <span class="String"><span class="String">&quot;</span>m.<span class="String">&quot;</span></span>
<span class="FunctionName">Snake</span><span class="Keyword">:</span> (name) <span class="Storage">=&gt;</span> <span class="FunctionName">this.name</span><span class="Keyword">:</span> name <span class="FunctionName">Snake</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">name</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span> <span class="FunctionName">this.name</span><span class="Keyword">:</span> name
Snake <span class="Variable">extends</span> Animal Snake <span class="Variable">extends</span> Animal
<span class="FunctionName">Snake::move</span><span class="Keyword">:</span> () <span class="Storage">=&gt;</span> <span class="FunctionName">Snake::move</span><span class="Keyword">:</span> <span class="Storage">-&gt;</span>
alert <span class="String"><span class="String">&quot;</span>Slithering...<span class="String">&quot;</span></span> alert <span class="String"><span class="String">&quot;</span>Slithering...<span class="String">&quot;</span></span>
<span class="Variable">super</span> <span class="Number">5</span> <span class="Variable">super</span> <span class="Number">5</span>
<span class="FunctionName">Horse</span><span class="Keyword">:</span> (name) <span class="Storage">=&gt;</span> <span class="FunctionName">this.name</span><span class="Keyword">:</span> name <span class="FunctionName">Horse</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">name</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span> <span class="FunctionName">this.name</span><span class="Keyword">:</span> name
Horse <span class="Variable">extends</span> Animal Horse <span class="Variable">extends</span> Animal
<span class="FunctionName">Horse::move</span><span class="Keyword">:</span> () <span class="Storage">=&gt;</span> <span class="FunctionName">Horse::move</span><span class="Keyword">:</span> <span class="Storage">-&gt;</span>
alert <span class="String"><span class="String">&quot;</span>Galloping...<span class="String">&quot;</span></span> alert <span class="String"><span class="String">&quot;</span>Galloping...<span class="String">&quot;</span></span>
<span class="Variable">super</span> <span class="Number">45</span> <span class="Variable">super</span> <span class="Number">45</span>
@ -1179,25 +1200,6 @@ sam.move();
tom.move(); tom.move();
;'>run</button><br class='clear' /></div> ;'>run</button><br class='clear' /></div>
<p id="blocks">
<b class="header">Blocks</b>
Many common looping functions (in Prototype, jQuery, and Underscore,
for example) take a single function as their final argument. To make
final functions easier to pass, CoffeeScript includes block syntax,
so you don't have to close the parentheses on the other side.
</p>
<div class='code'><pre class="idle">$(<span class="String"><span class="String">'</span>table.list<span class="String">'</span></span>).each (table) <span class="Storage">=&gt;</span>
$(<span class="String"><span class="String">'</span>tr.account<span class="String">'</span></span>, table).each (row) <span class="Storage">=&gt;</span>
row.show()
row.highlight()
</pre><pre class="idle"><span class="Keyword">$</span>(<span class="String"><span class="String">'</span>table.list<span class="String">'</span></span>).each(<span class="Storage">function</span>(table) {
<span class="Keyword">return</span> <span class="Keyword">$</span>(<span class="String"><span class="String">'</span>tr.account<span class="String">'</span></span>, table).each(<span class="Storage">function</span>(row) {
row.show();
<span class="Keyword">return</span> row.highlight();
});
});
</pre><br class='clear' /></div>
<p id="pattern_matching"> <p id="pattern_matching">
<b class="header">Pattern Matching (Destructuring Assignment)</b> <b class="header">Pattern Matching (Destructuring Assignment)</b>
To make extracting values from complex arrays and objects more convenient, To make extracting values from complex arrays and objects more convenient,
@ -1229,7 +1231,7 @@ and_switch = __a[1];
But it's also helpful for dealing with functions that return multiple But it's also helpful for dealing with functions that return multiple
values. values.
</p> </p>
<div class='code'><pre class="idle"><span class="FunctionName">weather_report</span><span class="Keyword">:</span> (location) <span class="Storage">=&gt;</span> <div class='code'><pre class="idle"><span class="FunctionName">weather_report</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">location</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="Comment"><span class="Comment">#</span> Make an Ajax request to fetch the weather...</span> <span class="Comment"><span class="Comment">#</span> Make an Ajax request to fetch the weather...</span>
[location, <span class="Number">72</span>, <span class="String"><span class="String">&quot;</span>Mostly Sunny<span class="String">&quot;</span></span>] [location, <span class="Number">72</span>, <span class="String"><span class="String">&quot;</span>Mostly Sunny<span class="String">&quot;</span></span>]
@ -1302,20 +1304,20 @@ street = __c[0];
city = __c[1]; city = __c[1];
;alert(poet + " — " + street);'>run: poet + " — " + street</button><br class='clear' /></div> ;alert(poet + " — " + street);'>run: poet + " — " + street</button><br class='clear' /></div>
<p id="long_arrow"> <p id="fat_arrow">
<b class="header">Function binding</b> <b class="header">Function binding</b>
The long arrow <tt>=></tt> can be used to both define a function, and to bind The fat arrow <tt>=></tt> can be used to both define a function, and to bind
it to the current value of <tt>this</tt>, right on the spot. This is helpful it to the current value of <tt>this</tt>, right on the spot. This is helpful
when using callback-based libraries like Prototype or jQuery, for creating when using callback-based libraries like Prototype or jQuery, for creating
iterator functions to pass to <tt>each</tt>, or event-handler functions iterator functions to pass to <tt>each</tt>, or event-handler functions
to use with <tt>bind</tt>. Functions created with the long arrow are able to access to use with <tt>bind</tt>. Functions created with the fat arrow are able to access
properties of the <tt>this</tt> where they're defined. properties of the <tt>this</tt> where they're defined.
</p> </p>
<div class='code'><pre class="idle"><span class="FunctionName">Account</span><span class="Keyword">:</span> (customer, cart) <span class="Storage">=&gt;</span> <div class='code'><pre class="idle"><span class="FunctionName">Account</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">customer, cart</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="FunctionName">this.customer</span><span class="Keyword">:</span> customer <span class="FunctionName">this.customer</span><span class="Keyword">:</span> customer
<span class="FunctionName">this.cart</span><span class="Keyword">:</span> cart <span class="FunctionName">this.cart</span><span class="Keyword">:</span> cart
$(<span class="String"><span class="String">'</span>.shopping_cart<span class="String">'</span></span>).bind(<span class="String"><span class="String">'</span>click<span class="String">'</span></span>) (event) <span class="Storage">==&gt;</span> $(<span class="String"><span class="String">'</span>.shopping_cart<span class="String">'</span></span>).bind <span class="String"><span class="String">'</span>click<span class="String">'</span></span>, <span class="FunctionArgument">(</span><span class="FunctionArgument">event</span><span class="FunctionArgument">)</span> <span class="Storage">=&gt;</span>
<span class="Variable">this</span>.customer.purchase <span class="Variable">this</span>.cart <span class="Variable">this</span>.customer.purchase <span class="Variable">this</span>.cart
</pre><pre class="idle"><span class="Storage">var</span> Account; </pre><pre class="idle"><span class="Storage">var</span> Account;
Account <span class="Keyword">=</span> <span class="Storage">function</span> <span class="FunctionName">Account</span>(<span class="FunctionArgument">customer, cart</span>) { Account <span class="Keyword">=</span> <span class="Storage">function</span> <span class="FunctionName">Account</span>(<span class="FunctionArgument">customer, cart</span>) {
@ -1497,6 +1499,12 @@ html <span class="Keyword">=</span> <span class="String"><span class="String">&q
<li> <li>
<a href="http://github.com/jashkenas/coffee-script/issues">Bugs, Feature Requests, and General Discussion</a> <a href="http://github.com/jashkenas/coffee-script/issues">Bugs, Feature Requests, and General Discussion</a>
</li> </li>
<li>
<a href="http://github.com/creationix/coffeepot">CoffeePot</a><br />
An implementation of CoffeeScript, written in CoffeeScript, by
<a href="http://github.com/creationix">Tim Caswell</a>. Compiles just
a limited subset at this point.
</li>
<li> <li>
<a href="http://github.com/jnicklas/bistro_car">BistroCar</a><br /> <a href="http://github.com/jnicklas/bistro_car">BistroCar</a><br />
A Rails plugin by A Rails plugin by
@ -1512,39 +1520,24 @@ html <span class="Keyword">=</span> <span class="String"><span class="String">&q
</li> </li>
</ul> </ul>
<h2 id="contributing">Contributing</h2> <h2 id="change_log">Change Log</h2>
<p> <p>
Here's a wish list of things that would be wonderful to have contributed: <b class="header" style="margin-top: 20px;">0.3.0</b>
CoffeeScript 0.3 includes major syntax changes:
<br />
The function symbol was changed to
<tt>-></tt>, and the bound function symbol is now <tt>=></tt>.
<br />
Parameter lists in function definitions must now be wrapped in parentheses.
<br />
Added property soaking, with the <tt>?.</tt> operator.
<br />
Made parentheses optional, when invoking functions with arguments.
<br />
Removed the obsolete block literal syntax.
</p> </p>
<ul>
<li>
<a href="http://github.com/jashkenas/coffee-script/issues#issue/8">
A CoffeeScript version of the compiler.
</a>
</li>
<li>
Test cases for any syntax errors you encounter that you think CoffeeScript
should be able to compile properly.
</li>
<li>
A tutorial that introduces CoffeeScript from the ground up for folks
without knowledge of JavaScript.
</li>
<li>
Integration with Processing.js's JavaScript API (this would depend on
having a JavaScript version of the compiler).
</li>
<li>
A lot of the code generation in <tt>nodes.rb</tt> gets into messy
string manipulation. Techniques for cleaning this up across the board
would be appreciated.
</li>
</ul>
<h2 id="change_log">Change Log</h2>
<p> <p>
<b class="header" style="margin-top: 20px;">0.2.6</b> <b class="header" style="margin-top: 20px;">0.2.6</b>
Added Python-style chained comparisons, the conditional existence Added Python-style chained comparisons, the conditional existence

View file

@ -10,7 +10,7 @@ require "coffee_script/parse_error"
# Namespace for all CoffeeScript internal classes. # Namespace for all CoffeeScript internal classes.
module CoffeeScript module CoffeeScript
VERSION = '0.2.6' # Keep in sync with the gemspec. VERSION = '0.3.0' # Keep in sync with the gemspec.
# Compile a script (String or IO) to JavaScript. # Compile a script (String or IO) to JavaScript.
def self.compile(script, options={}) def self.compile(script, options={})

View file

@ -5,5 +5,5 @@
"description": "Unfancy JavaScript", "description": "Unfancy JavaScript",
"keywords": ["javascript", "language"], "keywords": ["javascript", "language"],
"author": "Jeremy Ashkenas", "author": "Jeremy Ashkenas",
"version": "0.2.6" "version": "0.3.0"
} }