mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
Switching default arguments to use an if instead of an and, more documentation.
This commit is contained in:
parent
5dfd36af6a
commit
fc64fa49ac
25 changed files with 283 additions and 162 deletions
8
documentation/coffee/default_args.coffee
Normal file
8
documentation/coffee/default_args.coffee
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
fill = (container, liquid = "coffee") ->
|
||||||
|
"Filling the #{container} with #{liquid}..."
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
9
documentation/coffee/heregexes.coffee
Normal file
9
documentation/coffee/heregexes.coffee
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
OPERATOR = /// ^ (
|
||||||
|
?: [-=]> # function
|
||||||
|
| [-+*/%<>&|^!?=]= # compound assign / compare
|
||||||
|
| >>>=? # zero-fill right shift
|
||||||
|
| ([-+:])\1 # doubles
|
||||||
|
| ([&|<>])\2=? # logic / shift
|
||||||
|
| \?\. # soak access
|
||||||
|
| \.{2,3} # range or splat
|
||||||
|
) ///
|
|
@ -1,2 +1,6 @@
|
||||||
author = "Wittgenstein"
|
author = "Wittgenstein"
|
||||||
quote = "A picture is a fact. -- #{author}"
|
quote = "A picture is a fact. -- #{ author }"
|
||||||
|
|
||||||
|
sentence = "#{ 22 / 7 } is a decent approximation of π"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
sentence = "#{ 22 / 7 } is a decent approximation of π"
|
|
||||||
|
|
||||||
sep = "[.\\/\\- ]"
|
|
||||||
dates = /\d+#{sep}\d+#{sep}\d+/g
|
|
||||||
|
|
||||||
|
|
|
@ -1092,8 +1092,7 @@ parentheses, but no longer -- you can put in as many as you please.</p>
|
||||||
<span class="nv">forPart = </span><span class="nx">source</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">merge</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="p">{</span><span class="nx">index</span><span class="o">:</span> <span class="nx">ivar</span><span class="p">,</span> <span class="nx">@step</span><span class="p">})</span>
|
<span class="nv">forPart = </span><span class="nx">source</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">merge</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="p">{</span><span class="nx">index</span><span class="o">:</span> <span class="nx">ivar</span><span class="p">,</span> <span class="nx">@step</span><span class="p">})</span>
|
||||||
<span class="k">else</span>
|
<span class="k">else</span>
|
||||||
<span class="nv">svar = </span><span class="nx">@source</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_TOP</span>
|
<span class="nv">svar = </span><span class="nx">@source</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_TOP</span>
|
||||||
<span class="k">if</span> <span class="p">(</span><span class="nx">name</span> <span class="o">or</span> <span class="o">not</span> <span class="nx">@raw</span><span class="p">)</span> <span class="o">and</span>
|
<span class="k">if</span> <span class="p">(</span><span class="nx">name</span> <span class="o">or</span> <span class="o">not</span> <span class="nx">@raw</span><span class="p">)</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">IDENTIFIER</span><span class="p">.</span><span class="nx">test</span> <span class="nx">svar</span>
|
||||||
<span class="o">not</span> <span class="p">(</span><span class="nx">IDENTIFIER</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nx">svar</span><span class="p">)</span> <span class="o">and</span> <span class="nx">scope</span><span class="p">.</span><span class="nx">check</span> <span class="nx">svar</span><span class="p">,</span> <span class="nx">immediate</span><span class="o">:</span> <span class="kc">on</span><span class="p">)</span>
|
|
||||||
<span class="nv">defPart = </span><span class="s2">"#{@tab}#{ref = scope.freeVariable 'ref'} = #{svar};\n"</span>
|
<span class="nv">defPart = </span><span class="s2">"#{@tab}#{ref = scope.freeVariable 'ref'} = #{svar};\n"</span>
|
||||||
<span class="nv">svar = </span><span class="nx">ref</span>
|
<span class="nv">svar = </span><span class="nx">ref</span>
|
||||||
<span class="nv">namePart = </span><span class="k">if</span> <span class="nx">@pattern</span>
|
<span class="nv">namePart = </span><span class="k">if</span> <span class="nx">@pattern</span>
|
||||||
|
@ -1248,7 +1247,7 @@ force inner <em>else</em> bodies into statement form.</p> </td>
|
||||||
generation to generate other combinations of nodes.</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-138"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-138">¶</a> </div> <h3>Push</h3> </td> <td class="code"> <div class="highlight"><pre><span class="nv">Closure =</span></pre></div> </td> </tr> <tr id="section-139"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-139">¶</a> </div> <p>The <strong>Push</strong> creates the tree for <code>array.push(value)</code>,
|
generation to generate other combinations of nodes.</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-138"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-138">¶</a> </div> <h3>Push</h3> </td> <td class="code"> <div class="highlight"><pre><span class="nv">Closure =</span></pre></div> </td> </tr> <tr id="section-139"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-139">¶</a> </div> <p>The <strong>Push</strong> creates the tree for <code>array.push(value)</code>,
|
||||||
which is helpful for recording the result arrays from comprehensions.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">wrap</span><span class="o">:</span> <span class="p">(</span><span class="nx">expressions</span><span class="p">,</span> <span class="nx">statement</span><span class="p">,</span> <span class="nx">noReturn</span><span class="p">)</span> <span class="o">-></span>
|
which is helpful for recording the result arrays from comprehensions.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">wrap</span><span class="o">:</span> <span class="p">(</span><span class="nx">expressions</span><span class="p">,</span> <span class="nx">statement</span><span class="p">,</span> <span class="nx">noReturn</span><span class="p">)</span> <span class="o">-></span>
|
||||||
<span class="k">return</span> <span class="nx">expressions</span> <span class="k">if</span> <span class="nx">expressions</span><span class="p">.</span><span class="nx">containsPureStatement</span><span class="p">()</span>
|
<span class="k">return</span> <span class="nx">expressions</span> <span class="k">if</span> <span class="nx">expressions</span><span class="p">.</span><span class="nx">containsPureStatement</span><span class="p">()</span>
|
||||||
<span class="nv">func = </span><span class="k">new</span> <span class="nx">Parens</span> <span class="k">new</span> <span class="nx">Code</span> <span class="p">[],</span> <span class="nx">Expressions</span><span class="p">.</span><span class="nx">wrap</span> <span class="p">[</span><span class="nx">expressions</span><span class="p">]</span>
|
<span class="nv">func = </span><span class="k">new</span> <span class="nx">Code</span> <span class="p">[],</span> <span class="nx">Expressions</span><span class="p">.</span><span class="nx">wrap</span> <span class="p">[</span><span class="nx">expressions</span><span class="p">]</span>
|
||||||
<span class="nv">args = </span><span class="p">[]</span>
|
<span class="nv">args = </span><span class="p">[]</span>
|
||||||
<span class="k">if</span> <span class="p">(</span><span class="nv">mentionsArgs = </span><span class="nx">expressions</span><span class="p">.</span><span class="nx">contains</span> <span class="nx">@literalArgs</span><span class="p">)</span> <span class="o">or</span>
|
<span class="k">if</span> <span class="p">(</span><span class="nv">mentionsArgs = </span><span class="nx">expressions</span><span class="p">.</span><span class="nx">contains</span> <span class="nx">@literalArgs</span><span class="p">)</span> <span class="o">or</span>
|
||||||
<span class="p">(</span> <span class="nx">expressions</span><span class="p">.</span><span class="nx">contains</span> <span class="nx">@literalThis</span><span class="p">)</span>
|
<span class="p">(</span> <span class="nx">expressions</span><span class="p">.</span><span class="nx">contains</span> <span class="nx">@literalThis</span><span class="p">)</span>
|
||||||
|
|
|
@ -55,8 +55,8 @@
|
||||||
<a href="#switch">The Switch Statement</a>
|
<a href="#switch">The Switch Statement</a>
|
||||||
<a href="#try">Try/Catch/Finally</a>
|
<a href="#try">Try/Catch/Finally</a>
|
||||||
<a href="#comparisons">Chained Comparisons</a>
|
<a href="#comparisons">Chained Comparisons</a>
|
||||||
<a href="#interpolation">String and RegExp Interpolation</a>
|
<a href="#strings">String Interpolation, Heredocs, and Block Comments</a>
|
||||||
<a href="#heredocs">Multiline Strings, Heredocs, and Block Comments</a>
|
<a href="#regexes">Extended Regular Expressions</a>
|
||||||
<a href="#cake">Cake, and Cakefiles</a>
|
<a href="#cake">Cake, and Cakefiles</a>
|
||||||
<a href="#scripts">"text/coffeescript" Script Tags</a>
|
<a href="#scripts">"text/coffeescript" Script Tags</a>
|
||||||
<a href="#examples">Examples</a>
|
<a href="#examples">Examples</a>
|
||||||
|
@ -107,17 +107,17 @@
|
||||||
<p>
|
<p>
|
||||||
CoffeeScript is a little language that compiles into JavaScript. Underneath
|
CoffeeScript is a little language that compiles into JavaScript. Underneath
|
||||||
all of those embarrassing braces and semicolons, JavaScript has always had
|
all of those embarrassing braces and semicolons, JavaScript has always had
|
||||||
a gorgeous object model at its heart. CoffeeScript is an attempt to expose
|
a gorgeous object model at its heart. CoffeeScript is an attempt to expose
|
||||||
the good parts of JavaScript in a simple way.
|
the good parts of JavaScript in a simple way.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The golden rule of CoffeeScript is: <i>"It's just JavaScript"</i>. The code
|
The golden rule of CoffeeScript is: <i>"It's just JavaScript"</i>. The code
|
||||||
compiles one-to-one into the equivalent JS, and there is
|
compiles one-to-one into the equivalent JS, and there is
|
||||||
no interpretation at runtime. You can use any existing JavaScript library
|
no interpretation at runtime. You can use any existing JavaScript library
|
||||||
seamlessly (and vice-versa). The compiled output is readable and pretty-printed,
|
seamlessly (and vice-versa). The compiled output is readable and pretty-printed,
|
||||||
passes through <a href="http://www.javascriptlint.com/">JavaScript Lint</a>
|
passes through <a href="http://www.javascriptlint.com/">JavaScript Lint</a>
|
||||||
without warnings, and can be run by any JavaScript implementation.
|
without warnings, and can be run by any JavaScript implementation.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
@ -140,17 +140,17 @@
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The CoffeeScript compiler
|
The CoffeeScript compiler
|
||||||
<a href="documentation/docs/grammar.html">is itself written in CoffeeScript</a>,
|
<a href="documentation/docs/grammar.html">is itself written in CoffeeScript</a>,
|
||||||
using the <a href="http://jison.org">Jison parser generator</a>. The command-line
|
using the <a href="http://jison.org">Jison parser generator</a>. The command-line
|
||||||
version of <tt>coffee</tt> is available as a <a href="http://nodejs.org/">Node.js</a> utility.
|
version of <tt>coffee</tt> is available as a <a href="http://nodejs.org/">Node.js</a> utility.
|
||||||
The core compiler however, does not depend on Node, and can be run in any
|
The core compiler however, does not depend on Node, and can be run in any
|
||||||
JavaScript environment, or in the browser (see "Try CoffeeScript", above).
|
JavaScript environment, or in the browser (see "Try CoffeeScript", above).
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
To install, first make sure you have a working copy of the latest tagged version of
|
To install, first make sure you have a working copy of the latest tagged version of
|
||||||
<a href="http://nodejs.org/">Node.js</a>, and <a href="http://npmjs.org">NPM</a>
|
<a href="http://nodejs.org/">Node.js</a>, and <a href="http://npmjs.org">NPM</a>
|
||||||
(the Node Package Manager). You can then install CoffeeScript with NPM:
|
(the Node Package Manager). You can then install CoffeeScript with NPM:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
@ -158,7 +158,7 @@
|
||||||
npm install coffee-script</pre>
|
npm install coffee-script</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
If you'd prefer to install the latest master version of CoffeeScript, you
|
If you'd prefer to install the latest master version of CoffeeScript, you
|
||||||
can clone the CoffeeScript
|
can clone the CoffeeScript
|
||||||
<a href="http://github.com/jashkenas/coffee-script">source repository</a>
|
<a href="http://github.com/jashkenas/coffee-script">source repository</a>
|
||||||
from GitHub, or download
|
from GitHub, or download
|
||||||
|
@ -169,11 +169,11 @@ npm install coffee-script</pre>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
sudo bin/cake install</pre>
|
sudo bin/cake install</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Both of these provide the <tt>coffee</tt> command, which can execute
|
Both of these provide the <tt>coffee</tt> command, which can execute
|
||||||
coffee scripts, compile <tt>.coffee</tt> files into <tt>.js</tt>, and
|
coffee scripts, compile <tt>.coffee</tt> files into <tt>.js</tt>, and
|
||||||
provides an interactive REPL. The <tt>coffee</tt> command takes the
|
provides an interactive REPL. The <tt>coffee</tt> command takes the
|
||||||
following options:
|
following options:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
@ -326,7 +326,7 @@ coffee --bare --print --stdio</pre>
|
||||||
arguments:<br /><tt>print "coffee"</tt>. The implicit call wraps forward
|
arguments:<br /><tt>print "coffee"</tt>. The implicit call wraps forward
|
||||||
to the end of the line or block expression.
|
to the end of the line or block expression.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Within object literals, indentation can be used to create nested objects.
|
Within object literals, indentation can be used to create nested objects.
|
||||||
</p>
|
</p>
|
||||||
|
@ -338,6 +338,10 @@ coffee --bare --print --stdio</pre>
|
||||||
function body. The empty function looks like this: <tt>-></tt>
|
function body. The empty function looks like this: <tt>-></tt>
|
||||||
</p>
|
</p>
|
||||||
<%= code_for('functions', 'cube(5)') %>
|
<%= code_for('functions', 'cube(5)') %>
|
||||||
|
<p>
|
||||||
|
Functions may also have default values for arguments.
|
||||||
|
</p>
|
||||||
|
<%= code_for('default_args', 'fill("cup")') %>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<span id="objects_and_arrays" class="bookmark"></span>
|
<span id="objects_and_arrays" class="bookmark"></span>
|
||||||
|
@ -351,7 +355,7 @@ coffee --bare --print --stdio</pre>
|
||||||
<p>
|
<p>
|
||||||
In JavaScript, you can't use reserved words, like <tt>class</tt>, as properties
|
In JavaScript, you can't use reserved words, like <tt>class</tt>, as properties
|
||||||
of an object, without quoting them as strings. CoffeeScript notices reserved words
|
of an object, without quoting them as strings. CoffeeScript notices reserved words
|
||||||
used as keys in objects and quotes them for you, so you don't have to worry
|
used as keys in objects and quotes them for you, so you don't have to worry
|
||||||
about it (say, when using jQuery).
|
about it (say, when using jQuery).
|
||||||
</p>
|
</p>
|
||||||
<%= code_for('objects_reserved') %>
|
<%= code_for('objects_reserved') %>
|
||||||
|
@ -446,11 +450,11 @@ coffee --bare --print --stdio</pre>
|
||||||
You can use <tt>in</tt> to test for array presence, and <tt>of</tt> to
|
You can use <tt>in</tt> to test for array presence, and <tt>of</tt> to
|
||||||
test for JavaScript object-key presence.
|
test for JavaScript object-key presence.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
All together now:
|
All together now:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<table class="definitions">
|
<table class="definitions">
|
||||||
<tr><th>CoffeeScript</th><th>JavaScript</th></tr>
|
<tr><th>CoffeeScript</th><th>JavaScript</th></tr>
|
||||||
<tr><td><tt>is</tt></td><td><tt>===</tt></td></tr>
|
<tr><td><tt>is</tt></td><td><tt>===</tt></td></tr>
|
||||||
|
@ -464,7 +468,7 @@ coffee --bare --print --stdio</pre>
|
||||||
<tr><td><tt>of</tt></td><td><tt>in</tt></td></tr>
|
<tr><td><tt>of</tt></td><td><tt>in</tt></td></tr>
|
||||||
<tr><td><tt>in</tt></td><td>(no JS equivalent)</td></tr>
|
<tr><td><tt>in</tt></td><td>(no JS equivalent)</td></tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<%= code_for('aliases') %>
|
<%= code_for('aliases') %>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
@ -616,6 +620,10 @@ coffee --bare --print --stdio</pre>
|
||||||
set the superclass, assign prototypal properties, and define the constructor,
|
set the superclass, assign prototypal properties, and define the constructor,
|
||||||
in a single assignable expression.
|
in a single assignable expression.
|
||||||
</p>
|
</p>
|
||||||
|
<p>
|
||||||
|
Constructor functions are named, to better support reflection. In the
|
||||||
|
example below for the first class, <tt>this.constructor.name is "Animal"</tt>.
|
||||||
|
</p>
|
||||||
<%= code_for('classes', true) %>
|
<%= code_for('classes', true) %>
|
||||||
<p>
|
<p>
|
||||||
If structuring your prototypes classically isn't your cup of tea, CoffeeScript
|
If structuring your prototypes classically isn't your cup of tea, CoffeeScript
|
||||||
|
@ -626,8 +634,11 @@ coffee --bare --print --stdio</pre>
|
||||||
</p>
|
</p>
|
||||||
<%= code_for('prototypes', '"one_two".dasherize()') %>
|
<%= code_for('prototypes', '"one_two".dasherize()') %>
|
||||||
<p>
|
<p>
|
||||||
Finally, you may assign Class-level (static) properties within a class
|
Finally class definitions are blocks of executable code, which make for interesting
|
||||||
definition by using<br /><tt>@property: value</tt>
|
metaprogramming possibilities. Because in the context of a class definition,
|
||||||
|
<tt>this</tt> is the class object itself (the constructor function), you
|
||||||
|
can assign static properties by using <br /><tt>@property: value</tt>, and call
|
||||||
|
functions defined in parent classes: <tt>@attr 'title', type: 'text'</tt>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
@ -727,21 +738,14 @@ coffee --bare --print --stdio</pre>
|
||||||
<%= code_for('comparisons', 'healthy') %>
|
<%= code_for('comparisons', 'healthy') %>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<span id="interpolation" class="bookmark"></span>
|
<span id="strings" class="bookmark"></span>
|
||||||
<b class="header">String and RegExp Interpolation</b>
|
<b class="header">String Interpolation, Heredocs, and Block Comments</b>
|
||||||
Ruby-style string interpolation is included in CoffeeScript. Double-quoted
|
Ruby-style string interpolation is included in CoffeeScript. Double-quoted
|
||||||
strings allow for interpolated values, while single-quoted strings are literal.
|
strings allow for interpolated values, using <tt>#{ ... }</tt>,
|
||||||
|
and single-quoted strings are literal.
|
||||||
</p>
|
</p>
|
||||||
<%= code_for('interpolation', 'quote') %>
|
<%= code_for('interpolation', 'sentence') %>
|
||||||
<p>
|
<p>
|
||||||
And arbitrary expressions can be interpolated by using brackets <tt>#{ ... }</tt><br />
|
|
||||||
Interpolation works the same way within regular expressions.
|
|
||||||
</p>
|
|
||||||
<%= code_for('interpolation_expression', 'sentence') %>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<span id="heredocs" class="bookmark"></span>
|
|
||||||
<b class="header">Multiline Strings, Heredocs, and Block Comments</b>
|
|
||||||
Multiline strings are allowed in CoffeeScript.
|
Multiline strings are allowed in CoffeeScript.
|
||||||
</p>
|
</p>
|
||||||
<%= code_for('strings', 'mobyDick') %>
|
<%= code_for('strings', 'mobyDick') %>
|
||||||
|
@ -763,6 +767,18 @@ coffee --bare --print --stdio</pre>
|
||||||
</p>
|
</p>
|
||||||
<%= code_for('block_comment') %>
|
<%= code_for('block_comment') %>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<span id="regexes" class="bookmark"></span>
|
||||||
|
<b class="header">Extended Regular Expressions</b>
|
||||||
|
Similar to "heredocs" and "herecomments", CoffeeScript supports "heregexes" —
|
||||||
|
extended regular expressions that ignore internal whitespace and can contain
|
||||||
|
comments, after Perl's <tt>/x</tt> modifier, but delimited by <tt>///</tt>.
|
||||||
|
They go a long way towards making complex regular expressions readable.
|
||||||
|
To quote from the CoffeeScript source:
|
||||||
|
</p>
|
||||||
|
<%= code_for('heregexes') %>
|
||||||
|
|
||||||
|
|
||||||
<h2>
|
<h2>
|
||||||
<span id="cake" class="bookmark"></span>
|
<span id="cake" class="bookmark"></span>
|
||||||
Cake, and Cakefiles
|
Cake, and Cakefiles
|
||||||
|
@ -802,7 +818,7 @@ coffee --bare --print --stdio</pre>
|
||||||
While it's not recommended for serious use, CoffeeScripts may be included
|
While it's not recommended for serious use, CoffeeScripts may be included
|
||||||
directly within the browser using <tt><script type="text/coffeescript"></tt>
|
directly within the browser using <tt><script type="text/coffeescript"></tt>
|
||||||
tags. The source includes a compressed and minified version of the compiler
|
tags. The source includes a compressed and minified version of the compiler
|
||||||
(<a href="extras/coffee-script.js">Download current version here, 43k when gzipped</a>)
|
(<a href="extras/coffee-script.js">Download current version here, 39k when gzipped</a>)
|
||||||
as <tt>extras/coffee-script.js</tt>. Include this file on a page with
|
as <tt>extras/coffee-script.js</tt>. Include this file on a page with
|
||||||
inline CoffeeScript tags, and it will compile and evaluate them in order.
|
inline CoffeeScript tags, and it will compile and evaluate them in order.
|
||||||
</p>
|
</p>
|
||||||
|
@ -820,15 +836,15 @@ coffee --bare --print --stdio</pre>
|
||||||
run within a closure wrapper, so if you want to expose global variables or
|
run within a closure wrapper, so if you want to expose global variables or
|
||||||
functions, attach them to the <tt>window</tt> object.
|
functions, attach them to the <tt>window</tt> object.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h2>
|
<h2>
|
||||||
<span id="examples" class="bookmark"></span>
|
<span id="examples" class="bookmark"></span>
|
||||||
Examples
|
Examples
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<b>frank06</b>'s <a href="http://riakjs.org/">riak-js</a>, a Node.js client for
|
<b>frank06</b>'s <a href="http://riakjs.org/">riak-js</a>, a Node.js client for
|
||||||
<a href="http://www.basho.com/Riak.html">Riak</a>, with support for HTTP
|
<a href="http://www.basho.com/Riak.html">Riak</a>, with support for HTTP
|
||||||
and Protocol Buffers.
|
and Protocol Buffers.
|
||||||
</li>
|
</li>
|
||||||
|
@ -846,11 +862,11 @@ coffee --bare --print --stdio</pre>
|
||||||
the Bolo tank game for modern browsers.
|
the Bolo tank game for modern browsers.
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<b>josh</b>'s <a href="http://josh.github.com/nack/">nack</a>, a Node.js-powered
|
<b>josh</b>'s <a href="http://josh.github.com/nack/">nack</a>, a Node.js-powered
|
||||||
<a href="http://rack.rubyforge.org/">Rack</a> server.
|
<a href="http://rack.rubyforge.org/">Rack</a> server.
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<b>sstephenson</b>'s <a href="http://sstephenson.github.com/strscan-js/">StringScanner</a>,
|
<b>sstephenson</b>'s <a href="http://sstephenson.github.com/strscan-js/">StringScanner</a>,
|
||||||
a simple tokenizer and lexical scanner for JavaScript strings.
|
a simple tokenizer and lexical scanner for JavaScript strings.
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -993,6 +1009,18 @@ coffee --bare --print --stdio</pre>
|
||||||
Change Log
|
Change Log
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<b class="header" style="margin-top: 20px;">0.9.5</b>
|
||||||
|
0.9.5 should be considered the first release candidate for CoffeeScript 1.0.
|
||||||
|
There have been a large number of internal changes since the previous release,
|
||||||
|
many contributed from <b>satyr</b>'s <a href="http://github.com/satyr/coco">Coco</a>
|
||||||
|
dialect of CoffeeScript. Heregexes (extended regexes) were added. Functions
|
||||||
|
can now have default arguments. Class bodies are now executable code.
|
||||||
|
Improved syntax errors for invalid CoffeeScript code. <tt>undefined</tt> now
|
||||||
|
works like <tt>null</tt>, and cannot be assigned a new value. Object literals
|
||||||
|
can now take dynamic keys, like this: <tt>{(key): value}</tt>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<b class="header" style="margin-top: 20px;">0.9.4</b>
|
<b class="header" style="margin-top: 20px;">0.9.4</b>
|
||||||
CoffeeScript now uses appropriately-named temporary variables, and recycles
|
CoffeeScript now uses appropriately-named temporary variables, and recycles
|
||||||
|
|
7
documentation/js/default_args.js
Normal file
7
documentation/js/default_args.js
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
var fill;
|
||||||
|
fill = function(container, liquid) {
|
||||||
|
if (liquid == null) {
|
||||||
|
liquid = "coffee";
|
||||||
|
}
|
||||||
|
return "Filling the " + container + " with " + liquid + "...";
|
||||||
|
};
|
|
@ -1,10 +1,10 @@
|
||||||
var globals, name, _results;
|
var globals, name, _results;
|
||||||
var __hasProp = Object.prototype.hasOwnProperty;
|
var __hasProp = Object.prototype.hasOwnProperty;
|
||||||
globals = ((function() {
|
globals = (function() {
|
||||||
_results = [];
|
_results = [];
|
||||||
for (name in window) {
|
for (name in window) {
|
||||||
if (!__hasProp.call(window, name)) continue;
|
if (!__hasProp.call(window, name)) continue;
|
||||||
_results.push(name);
|
_results.push(name);
|
||||||
}
|
}
|
||||||
return _results;
|
return _results;
|
||||||
})()).slice(0, 10);
|
}()).slice(0, 10);
|
|
@ -1,7 +1,7 @@
|
||||||
alert((function() {
|
alert(function() {
|
||||||
try {
|
try {
|
||||||
return nonexistent / void 0;
|
return nonexistent / void 0;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return "And the error is ... " + error;
|
return "And the error is ... " + error;
|
||||||
}
|
}
|
||||||
})());
|
}());
|
2
documentation/js/heregexes.js
Normal file
2
documentation/js/heregexes.js
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
var OPERATOR;
|
||||||
|
OPERATOR = /^(?:[-=]>|[-+*\/%<>&|^!?=]=|>>>=?|([-+:])\1|([&|<>])\2=?|\?\.|\.{2,3})/;
|
|
@ -1,3 +1,4 @@
|
||||||
var author, quote;
|
var author, quote, sentence;
|
||||||
author = "Wittgenstein";
|
author = "Wittgenstein";
|
||||||
quote = "A picture is a fact. -- " + author;
|
quote = "A picture is a fact. -- " + author;
|
||||||
|
sentence = "" + (22 / 7) + " is a decent approximation of π";
|
|
@ -1,4 +0,0 @@
|
||||||
var dates, sentence, sep;
|
|
||||||
sentence = "" + (22 / 7) + " is a decent approximation of π";
|
|
||||||
sep = "[.\\/\\- ]";
|
|
||||||
dates = /\d+#{sep}\d+#{sep}\d+/g;
|
|
|
@ -5,7 +5,7 @@ yearsOld = {
|
||||||
ida: 9,
|
ida: 9,
|
||||||
tim: 11
|
tim: 11
|
||||||
};
|
};
|
||||||
ages = (function() {
|
ages = function() {
|
||||||
_results = [];
|
_results = [];
|
||||||
for (child in yearsOld) {
|
for (child in yearsOld) {
|
||||||
if (!__hasProp.call(yearsOld, child)) continue;
|
if (!__hasProp.call(yearsOld, child)) continue;
|
||||||
|
@ -13,4 +13,4 @@ ages = (function() {
|
||||||
_results.push(child + " is " + age);
|
_results.push(child + " is " + age);
|
||||||
}
|
}
|
||||||
return _results;
|
return _results;
|
||||||
})();
|
}();
|
|
@ -24,11 +24,11 @@ race = function() {
|
||||||
if (typeof elvis != "undefined" && elvis !== null) {
|
if (typeof elvis != "undefined" && elvis !== null) {
|
||||||
alert("I knew it!");
|
alert("I knew it!");
|
||||||
}
|
}
|
||||||
cubes = ((function() {
|
cubes = (function() {
|
||||||
_results = [];
|
_results = [];
|
||||||
for (_i = 0, _len = list.length; _i < _len; _i++) {
|
for (_i = 0, _len = list.length; _i < _len; _i++) {
|
||||||
num = list[_i];
|
num = list[_i];
|
||||||
_results.push(math.cube(num));
|
_results.push(math.cube(num));
|
||||||
}
|
}
|
||||||
return _results;
|
return _results;
|
||||||
})());
|
}());
|
|
@ -1,8 +1,8 @@
|
||||||
var countdown, num, _results;
|
var countdown, num, _results;
|
||||||
countdown = ((function() {
|
countdown = (function() {
|
||||||
_results = [];
|
_results = [];
|
||||||
for (num = 10; num >= 1; num--) {
|
for (num = 10; num >= 1; num--) {
|
||||||
_results.push(num);
|
_results.push(num);
|
||||||
}
|
}
|
||||||
return _results;
|
return _results;
|
||||||
})());
|
}());
|
|
@ -8,10 +8,10 @@ if (this.studyingEconomics) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
num = 6;
|
num = 6;
|
||||||
lyrics = (function() {
|
lyrics = function() {
|
||||||
_results = [];
|
_results = [];
|
||||||
while (num -= 1) {
|
while (num -= 1) {
|
||||||
_results.push(num + " little monkeys, jumping on the bed. One fell out and bumped his head.");
|
_results.push(num + " little monkeys, jumping on the bed. One fell out and bumped his head.");
|
||||||
}
|
}
|
||||||
return _results;
|
return _results;
|
||||||
})();
|
}();
|
File diff suppressed because one or more lines are too long
213
index.html
213
index.html
|
@ -42,8 +42,8 @@
|
||||||
<a href="#switch">The Switch Statement</a>
|
<a href="#switch">The Switch Statement</a>
|
||||||
<a href="#try">Try/Catch/Finally</a>
|
<a href="#try">Try/Catch/Finally</a>
|
||||||
<a href="#comparisons">Chained Comparisons</a>
|
<a href="#comparisons">Chained Comparisons</a>
|
||||||
<a href="#interpolation">String and RegExp Interpolation</a>
|
<a href="#strings">String Interpolation, Heredocs, and Block Comments</a>
|
||||||
<a href="#heredocs">Multiline Strings, Heredocs, and Block Comments</a>
|
<a href="#regexes">Extended Regular Expressions</a>
|
||||||
<a href="#cake">Cake, and Cakefiles</a>
|
<a href="#cake">Cake, and Cakefiles</a>
|
||||||
<a href="#scripts">"text/coffeescript" Script Tags</a>
|
<a href="#scripts">"text/coffeescript" Script Tags</a>
|
||||||
<a href="#examples">Examples</a>
|
<a href="#examples">Examples</a>
|
||||||
|
@ -94,17 +94,17 @@
|
||||||
<p>
|
<p>
|
||||||
CoffeeScript is a little language that compiles into JavaScript. Underneath
|
CoffeeScript is a little language that compiles into JavaScript. Underneath
|
||||||
all of those embarrassing braces and semicolons, JavaScript has always had
|
all of those embarrassing braces and semicolons, JavaScript has always had
|
||||||
a gorgeous object model at its heart. CoffeeScript is an attempt to expose
|
a gorgeous object model at its heart. CoffeeScript is an attempt to expose
|
||||||
the good parts of JavaScript in a simple way.
|
the good parts of JavaScript in a simple way.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The golden rule of CoffeeScript is: <i>"It's just JavaScript"</i>. The code
|
The golden rule of CoffeeScript is: <i>"It's just JavaScript"</i>. The code
|
||||||
compiles one-to-one into the equivalent JS, and there is
|
compiles one-to-one into the equivalent JS, and there is
|
||||||
no interpretation at runtime. You can use any existing JavaScript library
|
no interpretation at runtime. You can use any existing JavaScript library
|
||||||
seamlessly (and vice-versa). The compiled output is readable and pretty-printed,
|
seamlessly (and vice-versa). The compiled output is readable and pretty-printed,
|
||||||
passes through <a href="http://www.javascriptlint.com/">JavaScript Lint</a>
|
passes through <a href="http://www.javascriptlint.com/">JavaScript Lint</a>
|
||||||
without warnings, and can be run by any JavaScript implementation.
|
without warnings, and can be run by any JavaScript implementation.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
@ -173,14 +173,14 @@ math <span class="Keyword">=</span> {
|
||||||
<span class="Keyword">if</span> (<span class="Keyword">typeof</span> elvis <span class="Keyword">!</span><span class="Keyword">=</span> <span class="String"><span class="String">"</span>undefined<span class="String">"</span></span> <span class="Keyword">&</span><span class="Keyword">&</span> elvis <span class="Keyword">!</span><span class="Keyword">==</span> <span class="BuiltInConstant">null</span>) {
|
<span class="Keyword">if</span> (<span class="Keyword">typeof</span> elvis <span class="Keyword">!</span><span class="Keyword">=</span> <span class="String"><span class="String">"</span>undefined<span class="String">"</span></span> <span class="Keyword">&</span><span class="Keyword">&</span> elvis <span class="Keyword">!</span><span class="Keyword">==</span> <span class="BuiltInConstant">null</span>) {
|
||||||
<span class="LibraryFunction">alert</span>(<span class="String"><span class="String">"</span>I knew it!<span class="String">"</span></span>);
|
<span class="LibraryFunction">alert</span>(<span class="String"><span class="String">"</span>I knew it!<span class="String">"</span></span>);
|
||||||
}
|
}
|
||||||
cubes <span class="Keyword">=</span> ((<span class="Storage">function</span>() {
|
cubes <span class="Keyword">=</span> (<span class="Storage">function</span>() {
|
||||||
_results <span class="Keyword">=</span> [];
|
_results <span class="Keyword">=</span> [];
|
||||||
<span class="Keyword">for</span> (_i <span class="Keyword">=</span> <span class="Number">0</span>, _len <span class="Keyword">=</span> list.<span class="LibraryConstant">length</span>; _i <span class="Keyword"><</span> _len; _i<span class="Keyword">++</span>) {
|
<span class="Keyword">for</span> (_i <span class="Keyword">=</span> <span class="Number">0</span>, _len <span class="Keyword">=</span> list.<span class="LibraryConstant">length</span>; _i <span class="Keyword"><</span> _len; _i<span class="Keyword">++</span>) {
|
||||||
num <span class="Keyword">=</span> list[_i];
|
num <span class="Keyword">=</span> list[_i];
|
||||||
_results.<span class="LibraryFunction">push</span>(math.cube(num));
|
_results.<span class="LibraryFunction">push</span>(math.cube(num));
|
||||||
}
|
}
|
||||||
<span class="Keyword">return</span> _results;
|
<span class="Keyword">return</span> _results;
|
||||||
})());
|
}());
|
||||||
</pre><button onclick='javascript: var cubes, list, math, num, number, opposite, race, square, _i, _len, _results;
|
</pre><button onclick='javascript: var cubes, list, math, num, number, opposite, race, square, _i, _len, _results;
|
||||||
var __slice = Array.prototype.slice;
|
var __slice = Array.prototype.slice;
|
||||||
number = 42;
|
number = 42;
|
||||||
|
@ -207,14 +207,14 @@ race = function() {
|
||||||
if (typeof elvis != "undefined" && elvis !== null) {
|
if (typeof elvis != "undefined" && elvis !== null) {
|
||||||
alert("I knew it!");
|
alert("I knew it!");
|
||||||
}
|
}
|
||||||
cubes = ((function() {
|
cubes = (function() {
|
||||||
_results = [];
|
_results = [];
|
||||||
for (_i = 0, _len = list.length; _i < _len; _i++) {
|
for (_i = 0, _len = list.length; _i < _len; _i++) {
|
||||||
num = list[_i];
|
num = list[_i];
|
||||||
_results.push(math.cube(num));
|
_results.push(math.cube(num));
|
||||||
}
|
}
|
||||||
return _results;
|
return _results;
|
||||||
})());;alert(cubes);'>run: cubes</button><br class='clear' /></div>
|
}());;alert(cubes);'>run: cubes</button><br class='clear' /></div>
|
||||||
|
|
||||||
<h2>
|
<h2>
|
||||||
<span id="installation" class="bookmark"></span>
|
<span id="installation" class="bookmark"></span>
|
||||||
|
@ -222,17 +222,17 @@ cubes = ((function() {
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The CoffeeScript compiler
|
The CoffeeScript compiler
|
||||||
<a href="documentation/docs/grammar.html">is itself written in CoffeeScript</a>,
|
<a href="documentation/docs/grammar.html">is itself written in CoffeeScript</a>,
|
||||||
using the <a href="http://jison.org">Jison parser generator</a>. The command-line
|
using the <a href="http://jison.org">Jison parser generator</a>. The command-line
|
||||||
version of <tt>coffee</tt> is available as a <a href="http://nodejs.org/">Node.js</a> utility.
|
version of <tt>coffee</tt> is available as a <a href="http://nodejs.org/">Node.js</a> utility.
|
||||||
The core compiler however, does not depend on Node, and can be run in any
|
The core compiler however, does not depend on Node, and can be run in any
|
||||||
JavaScript environment, or in the browser (see "Try CoffeeScript", above).
|
JavaScript environment, or in the browser (see "Try CoffeeScript", above).
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
To install, first make sure you have a working copy of the latest tagged version of
|
To install, first make sure you have a working copy of the latest tagged version of
|
||||||
<a href="http://nodejs.org/">Node.js</a>, and <a href="http://npmjs.org">NPM</a>
|
<a href="http://nodejs.org/">Node.js</a>, and <a href="http://npmjs.org">NPM</a>
|
||||||
(the Node Package Manager). You can then install CoffeeScript with NPM:
|
(the Node Package Manager). You can then install CoffeeScript with NPM:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
@ -240,7 +240,7 @@ cubes = ((function() {
|
||||||
npm install coffee-script</pre>
|
npm install coffee-script</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
If you'd prefer to install the latest master version of CoffeeScript, you
|
If you'd prefer to install the latest master version of CoffeeScript, you
|
||||||
can clone the CoffeeScript
|
can clone the CoffeeScript
|
||||||
<a href="http://github.com/jashkenas/coffee-script">source repository</a>
|
<a href="http://github.com/jashkenas/coffee-script">source repository</a>
|
||||||
from GitHub, or download
|
from GitHub, or download
|
||||||
|
@ -251,11 +251,11 @@ npm install coffee-script</pre>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
sudo bin/cake install</pre>
|
sudo bin/cake install</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Both of these provide the <tt>coffee</tt> command, which can execute
|
Both of these provide the <tt>coffee</tt> command, which can execute
|
||||||
coffee scripts, compile <tt>.coffee</tt> files into <tt>.js</tt>, and
|
coffee scripts, compile <tt>.coffee</tt> files into <tt>.js</tt>, and
|
||||||
provides an interactive REPL. The <tt>coffee</tt> command takes the
|
provides an interactive REPL. The <tt>coffee</tt> command takes the
|
||||||
following options:
|
following options:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
@ -408,7 +408,7 @@ coffee --bare --print --stdio</pre>
|
||||||
arguments:<br /><tt>print "coffee"</tt>. The implicit call wraps forward
|
arguments:<br /><tt>print "coffee"</tt>. The implicit call wraps forward
|
||||||
to the end of the line or block expression.
|
to the end of the line or block expression.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Within object literals, indentation can be used to create nested objects.
|
Within object literals, indentation can be used to create nested objects.
|
||||||
</p>
|
</p>
|
||||||
|
@ -435,6 +435,31 @@ square = function(x) {
|
||||||
cube = function(x) {
|
cube = function(x) {
|
||||||
return square(x) * x;
|
return square(x) * x;
|
||||||
};;alert(cube(5));'>run: cube(5)</button><br class='clear' /></div>
|
};;alert(cube(5));'>run: cube(5)</button><br class='clear' /></div>
|
||||||
|
<p>
|
||||||
|
Functions may also have default values for arguments.
|
||||||
|
</p>
|
||||||
|
<div class='code'><pre class="idle"><span class="FunctionName">fill </span><span class="Keyword">=</span> <span class="FunctionArgument">(container, liquid = "coffee")</span> <span class="Storage">-></span>
|
||||||
|
<span class="String"><span class="String">"</span>Filling the <span class="String"><span class="String">#{</span>container<span class="String">}</span></span> with <span class="String"><span class="String">#{</span>liquid<span class="String">}</span></span>...<span class="String">"</span></span>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</pre><pre class="idle"><span class="Storage">var</span> fill;
|
||||||
|
<span class="FunctionName">fill</span> = <span class="Storage">function</span>(<span class="FunctionArgument">container, liquid</span>) {
|
||||||
|
<span class="Keyword">if</span> (liquid <span class="Keyword">==</span> <span class="BuiltInConstant">null</span>) {
|
||||||
|
liquid <span class="Keyword">=</span> <span class="String"><span class="String">"</span>coffee<span class="String">"</span></span>;
|
||||||
|
}
|
||||||
|
<span class="Keyword">return</span> <span class="String"><span class="String">"</span>Filling the <span class="String">"</span></span> <span class="Keyword">+</span> container <span class="Keyword">+</span> <span class="String"><span class="String">"</span> with <span class="String">"</span></span> <span class="Keyword">+</span> liquid <span class="Keyword">+</span> <span class="String"><span class="String">"</span>...<span class="String">"</span></span>;
|
||||||
|
};
|
||||||
|
</pre><button onclick='javascript: var fill;
|
||||||
|
fill = function(container, liquid) {
|
||||||
|
if (liquid == null) {
|
||||||
|
liquid = "coffee";
|
||||||
|
}
|
||||||
|
return "Filling the " + container + " with " + liquid + "...";
|
||||||
|
};;alert(fill("cup"));'>run: fill("cup")</button><br class='clear' /></div>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<span id="objects_and_arrays" class="bookmark"></span>
|
<span id="objects_and_arrays" class="bookmark"></span>
|
||||||
|
@ -498,7 +523,7 @@ kids = {
|
||||||
<p>
|
<p>
|
||||||
In JavaScript, you can't use reserved words, like <tt>class</tt>, as properties
|
In JavaScript, you can't use reserved words, like <tt>class</tt>, as properties
|
||||||
of an object, without quoting them as strings. CoffeeScript notices reserved words
|
of an object, without quoting them as strings. CoffeeScript notices reserved words
|
||||||
used as keys in objects and quotes them for you, so you don't have to worry
|
used as keys in objects and quotes them for you, so you don't have to worry
|
||||||
about it (say, when using jQuery).
|
about it (say, when using jQuery).
|
||||||
</p>
|
</p>
|
||||||
<div class='code'><pre class="idle">$(<span class="String"><span class="String">'</span>.account<span class="String">'</span></span>).attr class: <span class="String"><span class="String">'</span>active<span class="String">'</span></span>
|
<div class='code'><pre class="idle">$(<span class="String"><span class="String">'</span>.account<span class="String">'</span></span>).attr class: <span class="String"><span class="String">'</span>active<span class="String">'</span></span>
|
||||||
|
@ -643,11 +668,11 @@ options <span class="Keyword">||</span> (options <span class="Keyword">=</span>
|
||||||
You can use <tt>in</tt> to test for array presence, and <tt>of</tt> to
|
You can use <tt>in</tt> to test for array presence, and <tt>of</tt> to
|
||||||
test for JavaScript object-key presence.
|
test for JavaScript object-key presence.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
All together now:
|
All together now:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<table class="definitions">
|
<table class="definitions">
|
||||||
<tr><th>CoffeeScript</th><th>JavaScript</th></tr>
|
<tr><th>CoffeeScript</th><th>JavaScript</th></tr>
|
||||||
<tr><td><tt>is</tt></td><td><tt>===</tt></td></tr>
|
<tr><td><tt>is</tt></td><td><tt>===</tt></td></tr>
|
||||||
|
@ -661,7 +686,7 @@ options <span class="Keyword">||</span> (options <span class="Keyword">=</span>
|
||||||
<tr><td><tt>of</tt></td><td><tt>in</tt></td></tr>
|
<tr><td><tt>of</tt></td><td><tt>in</tt></td></tr>
|
||||||
<tr><td><tt>in</tt></td><td>(no JS equivalent)</td></tr>
|
<tr><td><tt>in</tt></td><td>(no JS equivalent)</td></tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<div class='code'><pre class="idle">launch() <span class="Keyword">if</span> ignition <span class="Keyword">is</span> <span class="BuiltInConstant">on</span>
|
<div class='code'><pre class="idle">launch() <span class="Keyword">if</span> ignition <span class="Keyword">is</span> <span class="BuiltInConstant">on</span>
|
||||||
|
|
||||||
volume <span class="Keyword">=</span> <span class="Number">10</span> <span class="Keyword">if</span> band <span class="Keyword">isnt</span> SpinalTap
|
volume <span class="Keyword">=</span> <span class="Number">10</span> <span class="Keyword">if</span> band <span class="Keyword">isnt</span> SpinalTap
|
||||||
|
@ -784,13 +809,13 @@ lyrics <span class="Keyword">=</span> <span class="Keyword">while</span> num <sp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
num <span class="Keyword">=</span> <span class="Number">6</span>;
|
num <span class="Keyword">=</span> <span class="Number">6</span>;
|
||||||
lyrics <span class="Keyword">=</span> (<span class="Storage">function</span>() {
|
<span class="FunctionName">lyrics</span> = <span class="Storage">function</span>() {
|
||||||
_results <span class="Keyword">=</span> [];
|
_results <span class="Keyword">=</span> [];
|
||||||
<span class="Keyword">while</span> (num <span class="Keyword">-</span><span class="Keyword">=</span> <span class="Number">1</span>) {
|
<span class="Keyword">while</span> (num <span class="Keyword">-</span><span class="Keyword">=</span> <span class="Number">1</span>) {
|
||||||
_results.<span class="LibraryFunction">push</span>(num <span class="Keyword">+</span> <span class="String"><span class="String">"</span> little monkeys, jumping on the bed. One fell out and bumped his head.<span class="String">"</span></span>);
|
_results.<span class="LibraryFunction">push</span>(num <span class="Keyword">+</span> <span class="String"><span class="String">"</span> little monkeys, jumping on the bed. One fell out and bumped his head.<span class="String">"</span></span>);
|
||||||
}
|
}
|
||||||
<span class="Keyword">return</span> _results;
|
<span class="Keyword">return</span> _results;
|
||||||
})();
|
}();
|
||||||
</pre><button onclick='javascript: var lyrics, num, _results;
|
</pre><button onclick='javascript: var lyrics, num, _results;
|
||||||
if (this.studyingEconomics) {
|
if (this.studyingEconomics) {
|
||||||
while (supply > demand) {
|
while (supply > demand) {
|
||||||
|
@ -801,13 +826,13 @@ if (this.studyingEconomics) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
num = 6;
|
num = 6;
|
||||||
lyrics = (function() {
|
lyrics = function() {
|
||||||
_results = [];
|
_results = [];
|
||||||
while (num -= 1) {
|
while (num -= 1) {
|
||||||
_results.push(num + " little monkeys, jumping on the bed. One fell out and bumped his head.");
|
_results.push(num + " little monkeys, jumping on the bed. One fell out and bumped his head.");
|
||||||
}
|
}
|
||||||
return _results;
|
return _results;
|
||||||
})();;alert(lyrics.join("\n"));'>run: lyrics.join("\n")</button><br class='clear' /></div>
|
}();;alert(lyrics.join("\n"));'>run: lyrics.join("\n")</button><br class='clear' /></div>
|
||||||
<p>
|
<p>
|
||||||
For readability, the <b>until</b> keyword is equivalent to <tt>while not</tt>,
|
For readability, the <b>until</b> keyword is equivalent to <tt>while not</tt>,
|
||||||
and the <b>loop</b> keyword is equivalent to <tt>while true</tt>.
|
and the <b>loop</b> keyword is equivalent to <tt>while true</tt>.
|
||||||
|
@ -860,21 +885,21 @@ _ref <span class="Keyword">=</span> [<span class="String"><span class="String">'
|
||||||
<div class='code'><pre class="idle">countdown <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">countdown <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>])
|
||||||
|
|
||||||
</pre><pre class="idle"><span class="Storage">var</span> countdown, num, _results;
|
</pre><pre class="idle"><span class="Storage">var</span> countdown, num, _results;
|
||||||
countdown <span class="Keyword">=</span> ((<span class="Storage">function</span>() {
|
countdown <span class="Keyword">=</span> (<span class="Storage">function</span>() {
|
||||||
_results <span class="Keyword">=</span> [];
|
_results <span class="Keyword">=</span> [];
|
||||||
<span class="Keyword">for</span> (num <span class="Keyword">=</span> <span class="Number">10</span>; num <span class="Keyword">>=</span> <span class="Number">1</span>; num<span class="Keyword">--</span>) {
|
<span class="Keyword">for</span> (num <span class="Keyword">=</span> <span class="Number">10</span>; num <span class="Keyword">>=</span> <span class="Number">1</span>; num<span class="Keyword">--</span>) {
|
||||||
_results.<span class="LibraryFunction">push</span>(num);
|
_results.<span class="LibraryFunction">push</span>(num);
|
||||||
}
|
}
|
||||||
<span class="Keyword">return</span> _results;
|
<span class="Keyword">return</span> _results;
|
||||||
})());
|
}());
|
||||||
</pre><button onclick='javascript: var countdown, num, _results;
|
</pre><button onclick='javascript: var countdown, num, _results;
|
||||||
countdown = ((function() {
|
countdown = (function() {
|
||||||
_results = [];
|
_results = [];
|
||||||
for (num = 10; num >= 1; num--) {
|
for (num = 10; num >= 1; num--) {
|
||||||
_results.push(num);
|
_results.push(num);
|
||||||
}
|
}
|
||||||
return _results;
|
return _results;
|
||||||
})());;alert(countdown);'>run: countdown</button><br class='clear' /></div>
|
}());;alert(countdown);'>run: countdown</button><br class='clear' /></div>
|
||||||
<p>
|
<p>
|
||||||
Comprehensions can also be used to iterate over the keys and values in
|
Comprehensions can also be used to iterate over the keys and values in
|
||||||
an object. Use <tt>of</tt> to signal comprehension over the properties of
|
an object. Use <tt>of</tt> to signal comprehension over the properties of
|
||||||
|
@ -891,7 +916,7 @@ yearsOld <span class="Keyword">=</span> {
|
||||||
ida: <span class="Number">9</span>,
|
ida: <span class="Number">9</span>,
|
||||||
tim: <span class="Number">11</span>
|
tim: <span class="Number">11</span>
|
||||||
};
|
};
|
||||||
ages <span class="Keyword">=</span> (<span class="Storage">function</span>() {
|
<span class="FunctionName">ages</span> = <span class="Storage">function</span>() {
|
||||||
_results <span class="Keyword">=</span> [];
|
_results <span class="Keyword">=</span> [];
|
||||||
<span class="Keyword">for</span> (child <span class="Keyword">in</span> yearsOld) {
|
<span class="Keyword">for</span> (child <span class="Keyword">in</span> yearsOld) {
|
||||||
<span class="Keyword">if</span> (<span class="Keyword">!</span>__hasProp.<span class="LibraryFunction">call</span>(yearsOld, child)) <span class="Keyword">continue</span>;
|
<span class="Keyword">if</span> (<span class="Keyword">!</span>__hasProp.<span class="LibraryFunction">call</span>(yearsOld, child)) <span class="Keyword">continue</span>;
|
||||||
|
@ -899,7 +924,7 @@ ages <span class="Keyword">=</span> (<span class="Storage">function</span>() {
|
||||||
_results.<span class="LibraryFunction">push</span>(child <span class="Keyword">+</span> <span class="String"><span class="String">"</span> is <span class="String">"</span></span> <span class="Keyword">+</span> age);
|
_results.<span class="LibraryFunction">push</span>(child <span class="Keyword">+</span> <span class="String"><span class="String">"</span> is <span class="String">"</span></span> <span class="Keyword">+</span> age);
|
||||||
}
|
}
|
||||||
<span class="Keyword">return</span> _results;
|
<span class="Keyword">return</span> _results;
|
||||||
})();
|
}();
|
||||||
</pre><button onclick='javascript: var age, ages, child, yearsOld, _results;
|
</pre><button onclick='javascript: var age, ages, child, yearsOld, _results;
|
||||||
var __hasProp = Object.prototype.hasOwnProperty;
|
var __hasProp = Object.prototype.hasOwnProperty;
|
||||||
yearsOld = {
|
yearsOld = {
|
||||||
|
@ -907,7 +932,7 @@ yearsOld = {
|
||||||
ida: 9,
|
ida: 9,
|
||||||
tim: 11
|
tim: 11
|
||||||
};
|
};
|
||||||
ages = (function() {
|
ages = function() {
|
||||||
_results = [];
|
_results = [];
|
||||||
for (child in yearsOld) {
|
for (child in yearsOld) {
|
||||||
if (!__hasProp.call(yearsOld, child)) continue;
|
if (!__hasProp.call(yearsOld, child)) continue;
|
||||||
|
@ -915,7 +940,7 @@ ages = (function() {
|
||||||
_results.push(child + " is " + age);
|
_results.push(child + " is " + age);
|
||||||
}
|
}
|
||||||
return _results;
|
return _results;
|
||||||
})();;alert(ages.join(", "));'>run: ages.join(", ")</button><br class='clear' /></div>
|
}();;alert(ages.join(", "));'>run: ages.join(", ")</button><br class='clear' /></div>
|
||||||
<p>
|
<p>
|
||||||
By default, object comprehensions are safe, and use a <tt>hasOwnProperty</tt>
|
By default, object comprehensions are safe, and use a <tt>hasOwnProperty</tt>
|
||||||
check to make sure that you're dealing with properties on the current
|
check to make sure that you're dealing with properties on the current
|
||||||
|
@ -997,24 +1022,24 @@ six = (one = 1) + (two = 2) + (three = 3);;alert(six);'>run: six</button><br cla
|
||||||
globals <span class="Keyword">=</span> (name <span class="Keyword">for</span> name <span class="Keyword">of</span> window)[<span class="Number">0</span>...<span class="Number">10</span>]
|
globals <span class="Keyword">=</span> (name <span class="Keyword">for</span> name <span class="Keyword">of</span> window)[<span class="Number">0</span>...<span class="Number">10</span>]
|
||||||
</pre><pre class="idle"><span class="Storage">var</span> globals, name, _results;
|
</pre><pre class="idle"><span class="Storage">var</span> globals, name, _results;
|
||||||
<span class="Storage">var</span> __hasProp <span class="Keyword">=</span> <span class="LibraryClassType">Object</span>.<span class="LibraryConstant">prototype</span>.hasOwnProperty;
|
<span class="Storage">var</span> __hasProp <span class="Keyword">=</span> <span class="LibraryClassType">Object</span>.<span class="LibraryConstant">prototype</span>.hasOwnProperty;
|
||||||
globals <span class="Keyword">=</span> ((<span class="Storage">function</span>() {
|
globals <span class="Keyword">=</span> (<span class="Storage">function</span>() {
|
||||||
_results <span class="Keyword">=</span> [];
|
_results <span class="Keyword">=</span> [];
|
||||||
<span class="Keyword">for</span> (name <span class="Keyword">in</span> <span class="LibraryClassType">window</span>) {
|
<span class="Keyword">for</span> (name <span class="Keyword">in</span> <span class="LibraryClassType">window</span>) {
|
||||||
<span class="Keyword">if</span> (<span class="Keyword">!</span>__hasProp.<span class="LibraryFunction">call</span>(<span class="LibraryClassType">window</span>, name)) <span class="Keyword">continue</span>;
|
<span class="Keyword">if</span> (<span class="Keyword">!</span>__hasProp.<span class="LibraryFunction">call</span>(<span class="LibraryClassType">window</span>, name)) <span class="Keyword">continue</span>;
|
||||||
_results.<span class="LibraryFunction">push</span>(name);
|
_results.<span class="LibraryFunction">push</span>(name);
|
||||||
}
|
}
|
||||||
<span class="Keyword">return</span> _results;
|
<span class="Keyword">return</span> _results;
|
||||||
})()).<span class="LibraryFunction">slice</span>(<span class="Number">0</span>, <span class="Number">10</span>);
|
}()).<span class="LibraryFunction">slice</span>(<span class="Number">0</span>, <span class="Number">10</span>);
|
||||||
</pre><button onclick='javascript: var globals, name, _results;
|
</pre><button onclick='javascript: var globals, name, _results;
|
||||||
var __hasProp = Object.prototype.hasOwnProperty;
|
var __hasProp = Object.prototype.hasOwnProperty;
|
||||||
globals = ((function() {
|
globals = (function() {
|
||||||
_results = [];
|
_results = [];
|
||||||
for (name in window) {
|
for (name in window) {
|
||||||
if (!__hasProp.call(window, name)) continue;
|
if (!__hasProp.call(window, name)) continue;
|
||||||
_results.push(name);
|
_results.push(name);
|
||||||
}
|
}
|
||||||
return _results;
|
return _results;
|
||||||
})()).slice(0, 10);;alert(globals);'>run: globals</button><br class='clear' /></div>
|
}()).slice(0, 10);;alert(globals);'>run: globals</button><br class='clear' /></div>
|
||||||
<p>
|
<p>
|
||||||
As well as silly things, like passing a <b>try/catch</b> statement directly
|
As well as silly things, like passing a <b>try/catch</b> statement directly
|
||||||
into a function call:
|
into a function call:
|
||||||
|
@ -1025,20 +1050,20 @@ globals = ((function() {
|
||||||
<span class="Keyword">catch</span> error
|
<span class="Keyword">catch</span> error
|
||||||
<span class="String"><span class="String">"</span>And the error is ... <span class="String">"</span></span> <span class="Keyword">+</span> error
|
<span class="String"><span class="String">"</span>And the error is ... <span class="String">"</span></span> <span class="Keyword">+</span> error
|
||||||
)
|
)
|
||||||
</pre><pre class="idle"><span class="LibraryFunction">alert</span>((<span class="Storage">function</span>() {
|
</pre><pre class="idle"><span class="LibraryFunction">alert</span>(<span class="Storage">function</span>() {
|
||||||
<span class="Keyword">try</span> {
|
<span class="Keyword">try</span> {
|
||||||
<span class="Keyword">return</span> nonexistent / <span class="Storage">void</span> <span class="Number">0</span>;
|
<span class="Keyword">return</span> nonexistent / <span class="Storage">void</span> <span class="Number">0</span>;
|
||||||
} <span class="Keyword">catch</span> (error) {
|
} <span class="Keyword">catch</span> (error) {
|
||||||
<span class="Keyword">return</span> <span class="String"><span class="String">"</span>And the error is ... <span class="String">"</span></span> <span class="Keyword">+</span> error;
|
<span class="Keyword">return</span> <span class="String"><span class="String">"</span>And the error is ... <span class="String">"</span></span> <span class="Keyword">+</span> error;
|
||||||
}
|
}
|
||||||
})());
|
}());
|
||||||
</pre><button onclick='javascript: alert((function() {
|
</pre><button onclick='javascript: alert(function() {
|
||||||
try {
|
try {
|
||||||
return nonexistent / void 0;
|
return nonexistent / void 0;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return "And the error is ... " + error;
|
return "And the error is ... " + error;
|
||||||
}
|
}
|
||||||
})());;'>run</button><br class='clear' /></div>
|
}());;'>run</button><br class='clear' /></div>
|
||||||
<p>
|
<p>
|
||||||
There are a handful of statements in JavaScript that can't be meaningfully
|
There are a handful of statements in JavaScript that can't be meaningfully
|
||||||
converted into expressions, namely <tt>break</tt>, <tt>continue</tt>,
|
converted into expressions, namely <tt>break</tt>, <tt>continue</tt>,
|
||||||
|
@ -1117,6 +1142,10 @@ zip <span class="Keyword">=</span> <span class="Keyword">typeof</span> lottery.d
|
||||||
set the superclass, assign prototypal properties, and define the constructor,
|
set the superclass, assign prototypal properties, and define the constructor,
|
||||||
in a single assignable expression.
|
in a single assignable expression.
|
||||||
</p>
|
</p>
|
||||||
|
<p>
|
||||||
|
Constructor functions are named, to better support reflection. In the
|
||||||
|
example below for the first class, <tt>this.constructor.name is "Animal"</tt>.
|
||||||
|
</p>
|
||||||
<div class='code'><pre class="idle"><span class="Storage">class</span> <span class="TypeName">Animal</span>
|
<div class='code'><pre class="idle"><span class="Storage">class</span> <span class="TypeName">Animal</span>
|
||||||
<span class="FunctionName">constructor</span><span class="Keyword">:</span> <span class="FunctionArgument">(@name)</span> <span class="Storage">-></span>
|
<span class="FunctionName">constructor</span><span class="Keyword">:</span> <span class="FunctionArgument">(@name)</span> <span class="Storage">-></span>
|
||||||
|
|
||||||
|
@ -1246,8 +1275,11 @@ tom.move();;'>run</button><br class='clear' /></div>
|
||||||
return this.replace(/_/g, "-");
|
return this.replace(/_/g, "-");
|
||||||
};;alert("one_two".dasherize());'>run: "one_two".dasherize()</button><br class='clear' /></div>
|
};;alert("one_two".dasherize());'>run: "one_two".dasherize()</button><br class='clear' /></div>
|
||||||
<p>
|
<p>
|
||||||
Finally, you may assign Class-level (static) properties within a class
|
Finally class definitions are blocks of executable code, which make for interesting
|
||||||
definition by using<br /><tt>@property: value</tt>
|
metaprogramming possibilities. Because in the context of a class definition,
|
||||||
|
<tt>this</tt> is the class object itself (the constructor function), you
|
||||||
|
can assign static properties by using <br /><tt>@property: value</tt>, and call
|
||||||
|
functions defined in parent classes: <tt>@attr 'title', type: 'text'</tt>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
@ -1505,41 +1537,27 @@ cholesterol = 127;
|
||||||
healthy = 200 > cholesterol && cholesterol > 60;;alert(healthy);'>run: healthy</button><br class='clear' /></div>
|
healthy = 200 > cholesterol && cholesterol > 60;;alert(healthy);'>run: healthy</button><br class='clear' /></div>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<span id="interpolation" class="bookmark"></span>
|
<span id="strings" class="bookmark"></span>
|
||||||
<b class="header">String and RegExp Interpolation</b>
|
<b class="header">String Interpolation, Heredocs, and Block Comments</b>
|
||||||
Ruby-style string interpolation is included in CoffeeScript. Double-quoted
|
Ruby-style string interpolation is included in CoffeeScript. Double-quoted
|
||||||
strings allow for interpolated values, while single-quoted strings are literal.
|
strings allow for interpolated values, using <tt>#{ ... }</tt>,
|
||||||
|
and single-quoted strings are literal.
|
||||||
</p>
|
</p>
|
||||||
<div class='code'><pre class="idle">author <span class="Keyword">=</span> <span class="String"><span class="String">"</span>Wittgenstein<span class="String">"</span></span>
|
<div class='code'><pre class="idle">author <span class="Keyword">=</span> <span class="String"><span class="String">"</span>Wittgenstein<span class="String">"</span></span>
|
||||||
quote <span class="Keyword">=</span> <span class="String"><span class="String">"</span>A picture is a fact. -- <span class="String"><span class="String">#{</span>author<span class="String">}</span></span><span class="String">"</span></span>
|
quote <span class="Keyword">=</span> <span class="String"><span class="String">"</span>A picture is a fact. -- <span class="String"><span class="String">#{</span> author <span class="String">}</span></span><span class="String">"</span></span>
|
||||||
</pre><pre class="idle"><span class="Storage">var</span> author, quote;
|
|
||||||
|
sentence <span class="Keyword">=</span> <span class="String"><span class="String">"</span><span class="String"><span class="String">#{</span> <span class="Number">22</span> <span class="Keyword">/</span> <span class="Number">7</span> <span class="String">}</span></span> is a decent approximation of π<span class="String">"</span></span>
|
||||||
|
|
||||||
|
|
||||||
|
</pre><pre class="idle"><span class="Storage">var</span> author, quote, sentence;
|
||||||
author <span class="Keyword">=</span> <span class="String"><span class="String">"</span>Wittgenstein<span class="String">"</span></span>;
|
author <span class="Keyword">=</span> <span class="String"><span class="String">"</span>Wittgenstein<span class="String">"</span></span>;
|
||||||
quote <span class="Keyword">=</span> <span class="String"><span class="String">"</span>A picture is a fact. -- <span class="String">"</span></span> <span class="Keyword">+</span> author;
|
quote <span class="Keyword">=</span> <span class="String"><span class="String">"</span>A picture is a fact. -- <span class="String">"</span></span> <span class="Keyword">+</span> author;
|
||||||
</pre><button onclick='javascript: var author, quote;
|
|
||||||
author = "Wittgenstein";
|
|
||||||
quote = "A picture is a fact. -- " + author;;alert(quote);'>run: quote</button><br class='clear' /></div>
|
|
||||||
<p>
|
|
||||||
And arbitrary expressions can be interpolated by using brackets <tt>#{ ... }</tt><br />
|
|
||||||
Interpolation works the same way within regular expressions.
|
|
||||||
</p>
|
|
||||||
<div class='code'><pre class="idle">sentence <span class="Keyword">=</span> <span class="String"><span class="String">"</span><span class="String"><span class="String">#{</span> <span class="Number">22</span> <span class="Keyword">/</span> <span class="Number">7</span> <span class="String">}</span></span> is a decent approximation of π<span class="String">"</span></span>
|
|
||||||
|
|
||||||
sep <span class="Keyword">=</span> <span class="String"><span class="String">"</span>[.<span class="UserDefinedConstant">\\</span>/<span class="UserDefinedConstant">\\</span>- ]<span class="String">"</span></span>
|
|
||||||
dates <span class="Keyword">=</span> <span class="String">/\d+#{sep}\d+#{sep}\d+/g</span>
|
|
||||||
|
|
||||||
|
|
||||||
</pre><pre class="idle"><span class="Storage">var</span> dates, sentence, sep;
|
|
||||||
sentence <span class="Keyword">=</span> <span class="String"><span class="String">"</span><span class="String">"</span></span> <span class="Keyword">+</span> (<span class="Number">22</span> / <span class="Number">7</span>) <span class="Keyword">+</span> <span class="String"><span class="String">"</span> is a decent approximation of π<span class="String">"</span></span>;
|
sentence <span class="Keyword">=</span> <span class="String"><span class="String">"</span><span class="String">"</span></span> <span class="Keyword">+</span> (<span class="Number">22</span> / <span class="Number">7</span>) <span class="Keyword">+</span> <span class="String"><span class="String">"</span> is a decent approximation of π<span class="String">"</span></span>;
|
||||||
sep <span class="Keyword">=</span> <span class="String"><span class="String">"</span>[.<span class="UserDefinedConstant">\\</span>/<span class="UserDefinedConstant">\\</span>- ]<span class="String">"</span></span>;
|
</pre><button onclick='javascript: var author, quote, sentence;
|
||||||
dates <span class="Keyword">=</span><span class="String"> <span class="String">/</span><span class="UserDefinedConstant">\d</span>+#{sep}<span class="UserDefinedConstant">\d</span>+#{sep}<span class="UserDefinedConstant">\d</span>+<span class="String">/</span>g</span>;
|
author = "Wittgenstein";
|
||||||
</pre><button onclick='javascript: var dates, sentence, sep;
|
quote = "A picture is a fact. -- " + author;
|
||||||
sentence = "" + (22 / 7) + " is a decent approximation of π";
|
sentence = "" + (22 / 7) + " is a decent approximation of π";;alert(sentence);'>run: sentence</button><br class='clear' /></div>
|
||||||
sep = "[.\\/\\- ]";
|
|
||||||
dates = /\d+#{sep}\d+#{sep}\d+/g;;alert(sentence);'>run: sentence</button><br class='clear' /></div>
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<span id="heredocs" class="bookmark"></span>
|
|
||||||
<b class="header">Multiline Strings, Heredocs, and Block Comments</b>
|
|
||||||
Multiline strings are allowed in CoffeeScript.
|
Multiline strings are allowed in CoffeeScript.
|
||||||
</p>
|
</p>
|
||||||
<div class='code'><pre class="idle">mobyDick <span class="Keyword">=</span> <span class="String"><span class="String">"</span>Call me Ishmael. Some years ago --</span>
|
<div class='code'><pre class="idle">mobyDick <span class="Keyword">=</span> <span class="String"><span class="String">"</span>Call me Ishmael. Some years ago --</span>
|
||||||
|
@ -1587,6 +1605,29 @@ html <span class="Keyword">=</span> <span class="String"><span class="String">'<
|
||||||
<span class="Comment"><span class="Comment">*/</span></span>
|
<span class="Comment"><span class="Comment">*/</span></span>
|
||||||
</pre><br class='clear' /></div>
|
</pre><br class='clear' /></div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<span id="regexes" class="bookmark"></span>
|
||||||
|
<b class="header">Extended Regular Expressions</b>
|
||||||
|
Similar to "heredocs" and "herecomments", CoffeeScript supports "heregexes" —
|
||||||
|
extended regular expressions that ignore internal whitespace and can contain
|
||||||
|
comments, after Perl's <tt>/x</tt> modifier, but delimited by <tt>///</tt>.
|
||||||
|
They go a long way towards making complex regular expressions readable.
|
||||||
|
To quote from the CoffeeScript source:
|
||||||
|
</p>
|
||||||
|
<div class='code'><pre class="idle">OPERATOR <span class="Keyword">=</span> <span class="String">/// ^ (</span>
|
||||||
|
<span class="String"> ?: [-=]> <span class="Comment"><span class="Comment">#</span> function</span></span>
|
||||||
|
<span class="String"> | [-+*/%<>&|^!?=]= <span class="Comment"><span class="Comment">#</span> compound assign / compare</span></span>
|
||||||
|
<span class="String"> | >>>=? <span class="Comment"><span class="Comment">#</span> zero-fill right shift</span></span>
|
||||||
|
<span class="String"> | ([-+:])\1 <span class="Comment"><span class="Comment">#</span> doubles</span></span>
|
||||||
|
<span class="String"> | ([&|<>])\2=? <span class="Comment"><span class="Comment">#</span> logic / shift</span></span>
|
||||||
|
<span class="String"> | \?\. <span class="Comment"><span class="Comment">#</span> soak access</span></span>
|
||||||
|
<span class="String"> | \.{2,3} <span class="Comment"><span class="Comment">#</span> range or splat</span></span>
|
||||||
|
<span class="String">) ///</span>
|
||||||
|
</pre><pre class="idle"><span class="Storage">var</span> OPERATOR;
|
||||||
|
OPERATOR <span class="Keyword">=</span><span class="String"> <span class="String">/</span>^(?:[-=]>|[-+*<span class="UserDefinedConstant">\/</span>%<>&|^!?=]=|>>>=?|([-+:])<span class="UserDefinedConstant">\1</span>|([&|<>])<span class="UserDefinedConstant">\2</span>=?|<span class="UserDefinedConstant">\?</span><span class="UserDefinedConstant">\.</span>|<span class="UserDefinedConstant">\.</span>{2,3})<span class="String">/</span></span>;
|
||||||
|
</pre><br class='clear' /></div>
|
||||||
|
|
||||||
|
|
||||||
<h2>
|
<h2>
|
||||||
<span id="cake" class="bookmark"></span>
|
<span id="cake" class="bookmark"></span>
|
||||||
Cake, and Cakefiles
|
Cake, and Cakefiles
|
||||||
|
@ -1645,7 +1686,7 @@ task(<span class="String"><span class="String">'</span>build:parser<span class="
|
||||||
While it's not recommended for serious use, CoffeeScripts may be included
|
While it's not recommended for serious use, CoffeeScripts may be included
|
||||||
directly within the browser using <tt><script type="text/coffeescript"></tt>
|
directly within the browser using <tt><script type="text/coffeescript"></tt>
|
||||||
tags. The source includes a compressed and minified version of the compiler
|
tags. The source includes a compressed and minified version of the compiler
|
||||||
(<a href="extras/coffee-script.js">Download current version here, 43k when gzipped</a>)
|
(<a href="extras/coffee-script.js">Download current version here, 39k when gzipped</a>)
|
||||||
as <tt>extras/coffee-script.js</tt>. Include this file on a page with
|
as <tt>extras/coffee-script.js</tt>. Include this file on a page with
|
||||||
inline CoffeeScript tags, and it will compile and evaluate them in order.
|
inline CoffeeScript tags, and it will compile and evaluate them in order.
|
||||||
</p>
|
</p>
|
||||||
|
@ -1663,15 +1704,15 @@ task(<span class="String"><span class="String">'</span>build:parser<span class="
|
||||||
run within a closure wrapper, so if you want to expose global variables or
|
run within a closure wrapper, so if you want to expose global variables or
|
||||||
functions, attach them to the <tt>window</tt> object.
|
functions, attach them to the <tt>window</tt> object.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h2>
|
<h2>
|
||||||
<span id="examples" class="bookmark"></span>
|
<span id="examples" class="bookmark"></span>
|
||||||
Examples
|
Examples
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<b>frank06</b>'s <a href="http://riakjs.org/">riak-js</a>, a Node.js client for
|
<b>frank06</b>'s <a href="http://riakjs.org/">riak-js</a>, a Node.js client for
|
||||||
<a href="http://www.basho.com/Riak.html">Riak</a>, with support for HTTP
|
<a href="http://www.basho.com/Riak.html">Riak</a>, with support for HTTP
|
||||||
and Protocol Buffers.
|
and Protocol Buffers.
|
||||||
</li>
|
</li>
|
||||||
|
@ -1689,11 +1730,11 @@ task(<span class="String"><span class="String">'</span>build:parser<span class="
|
||||||
the Bolo tank game for modern browsers.
|
the Bolo tank game for modern browsers.
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<b>josh</b>'s <a href="http://josh.github.com/nack/">nack</a>, a Node.js-powered
|
<b>josh</b>'s <a href="http://josh.github.com/nack/">nack</a>, a Node.js-powered
|
||||||
<a href="http://rack.rubyforge.org/">Rack</a> server.
|
<a href="http://rack.rubyforge.org/">Rack</a> server.
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<b>sstephenson</b>'s <a href="http://sstephenson.github.com/strscan-js/">StringScanner</a>,
|
<b>sstephenson</b>'s <a href="http://sstephenson.github.com/strscan-js/">StringScanner</a>,
|
||||||
a simple tokenizer and lexical scanner for JavaScript strings.
|
a simple tokenizer and lexical scanner for JavaScript strings.
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -1836,6 +1877,18 @@ task(<span class="String"><span class="String">'</span>build:parser<span class="
|
||||||
Change Log
|
Change Log
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<b class="header" style="margin-top: 20px;">0.9.5</b>
|
||||||
|
0.9.5 should be considered the first release candidate for CoffeeScript 1.0.
|
||||||
|
There have been a large number of internal changes since the previous release,
|
||||||
|
many contributed from <b>satyr</b>'s <a href="http://github.com/satyr/coco">Coco</a>
|
||||||
|
dialect of CoffeeScript. Heregexes (extended regexes) were added. Functions
|
||||||
|
can now have default arguments. Class bodies are now executable code.
|
||||||
|
Improved syntax errors for invalid CoffeeScript code. <tt>undefined</tt> now
|
||||||
|
works like <tt>null</tt>, and cannot be assigned a new value. Object literals
|
||||||
|
can now take dynamic keys, like this: <tt>{(key): value}</tt>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<b class="header" style="margin-top: 20px;">0.9.4</b>
|
<b class="header" style="margin-top: 20px;">0.9.4</b>
|
||||||
CoffeeScript now uses appropriately-named temporary variables, and recycles
|
CoffeeScript now uses appropriately-named temporary variables, and recycles
|
||||||
|
|
|
@ -6,7 +6,9 @@
|
||||||
return eval(CoffeeScript.compile(code, options));
|
return eval(CoffeeScript.compile(code, options));
|
||||||
};
|
};
|
||||||
CoffeeScript.run = function(code, options) {
|
CoffeeScript.run = function(code, options) {
|
||||||
options == null && (options = {});
|
if (options == null) {
|
||||||
|
options = {};
|
||||||
|
}
|
||||||
options.bare = true;
|
options.bare = true;
|
||||||
return Function(CoffeeScript.compile(code, options))();
|
return Function(CoffeeScript.compile(code, options))();
|
||||||
};
|
};
|
||||||
|
|
|
@ -18,7 +18,9 @@
|
||||||
exports.VERSION = '0.9.5';
|
exports.VERSION = '0.9.5';
|
||||||
exports.helpers = require('./helpers');
|
exports.helpers = require('./helpers');
|
||||||
exports.compile = compile = function(code, options) {
|
exports.compile = compile = function(code, options) {
|
||||||
options == null && (options = {});
|
if (options == null) {
|
||||||
|
options = {};
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
return (parser.parse(lexer.tokenize(code))).compile(options);
|
return (parser.parse(lexer.tokenize(code))).compile(options);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|
12
lib/lexer.js
12
lib/lexer.js
|
@ -12,7 +12,9 @@
|
||||||
function Lexer() {}
|
function Lexer() {}
|
||||||
Lexer.prototype.tokenize = function(code, opts) {
|
Lexer.prototype.tokenize = function(code, opts) {
|
||||||
var i;
|
var i;
|
||||||
opts == null && (opts = {});
|
if (opts == null) {
|
||||||
|
opts = {};
|
||||||
|
}
|
||||||
code = code.replace(/\r/g, '').replace(TRAILING_SPACES, '');
|
code = code.replace(/\r/g, '').replace(TRAILING_SPACES, '');
|
||||||
this.code = code;
|
this.code = code;
|
||||||
this.line = opts.line || 0;
|
this.line = opts.line || 0;
|
||||||
|
@ -447,7 +449,9 @@
|
||||||
};
|
};
|
||||||
Lexer.prototype.balancedString = function(str, delimited, options) {
|
Lexer.prototype.balancedString = function(str, delimited, options) {
|
||||||
var i, open, pair, stack, _i, _len, _ref;
|
var i, open, pair, stack, _i, _len, _ref;
|
||||||
options == null && (options = {});
|
if (options == null) {
|
||||||
|
options = {};
|
||||||
|
}
|
||||||
stack = [delimited[0]];
|
stack = [delimited[0]];
|
||||||
for (i = 1, _ref = str.length; (1 <= _ref ? i < _ref : i > _ref); (1 <= _ref ? i += 1 : i -= 1)) {
|
for (i = 1, _ref = str.length; (1 <= _ref ? i < _ref : i > _ref); (1 <= _ref ? i += 1 : i -= 1)) {
|
||||||
switch (str.charAt(i)) {
|
switch (str.charAt(i)) {
|
||||||
|
@ -475,7 +479,9 @@
|
||||||
};
|
};
|
||||||
Lexer.prototype.interpolateString = function(str, options) {
|
Lexer.prototype.interpolateString = function(str, options) {
|
||||||
var expr, heredoc, i, inner, interpolated, letter, nested, pi, regex, tag, tokens, value, _len, _ref, _ref2, _this;
|
var expr, heredoc, i, inner, interpolated, letter, nested, pi, regex, tag, tokens, value, _len, _ref, _ref2, _this;
|
||||||
options == null && (options = {});
|
if (options == null) {
|
||||||
|
options = {};
|
||||||
|
}
|
||||||
heredoc = options.heredoc, regex = options.regex;
|
heredoc = options.heredoc, regex = options.regex;
|
||||||
tokens = [];
|
tokens = [];
|
||||||
pi = 0;
|
pi = 0;
|
||||||
|
|
18
lib/nodes.js
18
lib/nodes.js
|
@ -96,8 +96,12 @@
|
||||||
};
|
};
|
||||||
Base.prototype.toString = function(idt, name) {
|
Base.prototype.toString = function(idt, name) {
|
||||||
var tree;
|
var tree;
|
||||||
idt == null && (idt = '');
|
if (idt == null) {
|
||||||
name == null && (name = this.constructor.name);
|
idt = '';
|
||||||
|
}
|
||||||
|
if (name == null) {
|
||||||
|
name = this.constructor.name;
|
||||||
|
}
|
||||||
tree = '\n' + idt + name;
|
tree = '\n' + idt + name;
|
||||||
if (this.soak) {
|
if (this.soak) {
|
||||||
tree += '?';
|
tree += '?';
|
||||||
|
@ -208,7 +212,9 @@
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
Expressions.prototype.compile = function(o, level) {
|
Expressions.prototype.compile = function(o, level) {
|
||||||
o == null && (o = {});
|
if (o == null) {
|
||||||
|
o = {};
|
||||||
|
}
|
||||||
if (o.scope) {
|
if (o.scope) {
|
||||||
return Expressions.__super__.compile.call(this, o, level);
|
return Expressions.__super__.compile.call(this, o, level);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1259,7 +1265,7 @@
|
||||||
if (param.value) {
|
if (param.value) {
|
||||||
lit = new Literal(ref.name.value + ' == null');
|
lit = new Literal(ref.name.value + ' == null');
|
||||||
val = new Assign(new Value(param.name), param.value, '=');
|
val = new Assign(new Value(param.name), param.value, '=');
|
||||||
exprs.push(new Op('&&', lit, val));
|
exprs.push(new If(lit, val));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!splats) {
|
if (!splats) {
|
||||||
|
@ -1941,7 +1947,9 @@
|
||||||
exports.If = If = function() {
|
exports.If = If = function() {
|
||||||
function If(condition, body, options) {
|
function If(condition, body, options) {
|
||||||
this.body = body;
|
this.body = body;
|
||||||
options == null && (options = {});
|
if (options == null) {
|
||||||
|
options = {};
|
||||||
|
}
|
||||||
this.condition = options.invert ? condition.invert() : condition;
|
this.condition = options.invert ? condition.invert() : condition;
|
||||||
this.elseBody = null;
|
this.elseBody = null;
|
||||||
this.isChain = false;
|
this.isChain = false;
|
||||||
|
|
|
@ -71,7 +71,9 @@
|
||||||
};
|
};
|
||||||
buildRule = function(shortFlag, longFlag, description, options) {
|
buildRule = function(shortFlag, longFlag, description, options) {
|
||||||
var match;
|
var match;
|
||||||
options == null && (options = {});
|
if (options == null) {
|
||||||
|
options = {};
|
||||||
|
}
|
||||||
match = longFlag.match(OPTIONAL);
|
match = longFlag.match(OPTIONAL);
|
||||||
longFlag = longFlag.match(LONG_FLAG)[1];
|
longFlag = longFlag.match(LONG_FLAG)[1];
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -543,7 +543,7 @@ OPERATOR = /// ^ (
|
||||||
| ([-+:])\1 # doubles
|
| ([-+:])\1 # doubles
|
||||||
| ([&|<>])\2=? # logic / shift
|
| ([&|<>])\2=? # logic / shift
|
||||||
| \?\. # soak access
|
| \?\. # soak access
|
||||||
| \.{2,3} # range or splat
|
| \.{2,3} # range or splat
|
||||||
) ///
|
) ///
|
||||||
|
|
||||||
WHITESPACE = /^[^\n\S]+/
|
WHITESPACE = /^[^\n\S]+/
|
||||||
|
|
|
@ -1018,7 +1018,7 @@ exports.Code = class Code extends Base
|
||||||
if param.value
|
if param.value
|
||||||
lit = new Literal ref.name.value + ' == null'
|
lit = new Literal ref.name.value + ' == null'
|
||||||
val = new Assign new Value(param.name), param.value, '='
|
val = new Assign new Value(param.name), param.value, '='
|
||||||
exprs.push new Op '&&', lit, val
|
exprs.push new If lit, val
|
||||||
vars.push ref unless splats
|
vars.push ref unless splats
|
||||||
scope.startLevel()
|
scope.startLevel()
|
||||||
wasEmpty = @body.isEmpty()
|
wasEmpty = @body.isEmpty()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue