master 53fc0026d147 cached
147 files
334.9 KB
106.4k tokens
1 requests
Download .txt
Showing preview only (370K chars total). Download the full file or copy to clipboard to get everything.
Repository: coffeescript-cookbook/coffeescript-cookbook.github.io
Branch: master
Commit: 53fc0026d147
Files: 147
Total size: 334.9 KB

Directory structure:
gitextract_ml6e9x2u/

├── .gitignore
├── .ruby-gemset
├── .ruby-version
├── Gemfile
├── LICENSE-CC-BY.textile
├── Procfile
├── README.md
├── _config.yml
├── _data/
│   └── chapters.yml
├── _layouts/
│   ├── chapter.html
│   ├── default.html
│   └── recipe.html
├── authors-guide.md
├── authors.md
├── chapters/
│   ├── ajax/
│   │   ├── ajax_request_without_jquery.md
│   │   └── index.html
│   ├── arrays/
│   │   ├── check-type-is-array.md
│   │   ├── concatenating-arrays.md
│   │   ├── creating-a-dictionary-object-from-an-array.md
│   │   ├── creating-a-string-from-an-array.md
│   │   ├── define-ranges.md
│   │   ├── filtering-arrays.md
│   │   ├── index.html
│   │   ├── list-comprehensions.md
│   │   ├── mapping-arrays.md
│   │   ├── max-array-value.md
│   │   ├── reducing-arrays.md
│   │   ├── removing-duplicate-elements-from-arrays.md
│   │   ├── reversing-arrays.md
│   │   ├── shuffling-array-elements.md
│   │   ├── testing-every-element.md
│   │   ├── using-arrays-to-swap-variables.md
│   │   ├── where-for-arrays-of-objects.md
│   │   └── zip-function.md
│   ├── classes_and_objects/
│   │   ├── chaining.md
│   │   ├── class-methods-and-instance-methods.md
│   │   ├── class-variables-and-instance-variables.md
│   │   ├── cloning.md
│   │   ├── index.html
│   │   ├── mixins.md
│   │   ├── object-literal.md
│   │   └── type-function.md
│   ├── databases/
│   │   ├── index.html
│   │   ├── mongodb.md
│   │   └── sqlite.md
│   ├── dates_and_times/
│   │   ├── date-of-easter.md
│   │   ├── date-of-thanksgiving.md
│   │   ├── days-between-two-dates.md
│   │   ├── finding-last-day-of-the-month.md
│   │   ├── finding-last-or-next-month.md
│   │   ├── index.html
│   │   └── moon-phase-for-date.md
│   ├── design_patterns/
│   │   ├── adapter.md
│   │   ├── bridge.md
│   │   ├── builder.md
│   │   ├── command.md
│   │   ├── decorator.md
│   │   ├── factory_method.md
│   │   ├── index.html
│   │   ├── interpreter.md
│   │   ├── memento.md
│   │   ├── observer.md
│   │   ├── singleton.md
│   │   ├── strategy.md
│   │   └── template_method.md
│   ├── functions/
│   │   ├── debounce.md
│   │   ├── index.html
│   │   ├── parentheses.md
│   │   ├── recursion.md
│   │   └── splat_arguments.md
│   ├── index.html
│   ├── jquery/
│   │   ├── ajax.md
│   │   ├── callback-bindings-jquery.md
│   │   ├── index.html
│   │   └── plugin.md
│   ├── math/
│   │   ├── constants.md
│   │   ├── fast-fibonacci.md
│   │   ├── fast-inv-square.md
│   │   ├── generating-predictable-random-numbers.md
│   │   ├── generating-random-numbers.md
│   │   ├── index.html
│   │   ├── radians-degrees.md
│   │   ├── random-integer.md
│   │   └── working-with-exponents-and-logarithms.md
│   ├── metaprogramming/
│   │   ├── detecting-and-replacing-functions.md
│   │   ├── extending-built-in-objects.md
│   │   └── index.html
│   ├── networking/
│   │   ├── basic-client.md
│   │   ├── basic-http-client.md
│   │   ├── basic-http-server.md
│   │   ├── basic-server.md
│   │   ├── bi-directional-client.md
│   │   ├── bi-directional-server.md
│   │   └── index.html
│   ├── regular_expressions/
│   │   ├── heregexes.md
│   │   ├── index.html
│   │   ├── replacing-html-tags-with-html-named-entities.md
│   │   ├── replacing-substrings.md
│   │   └── searching-for-substrings.md
│   ├── strings/
│   │   ├── capitalizing-words.md
│   │   ├── finding-substrings.md
│   │   ├── generating-a-unique-id.md
│   │   ├── index.html
│   │   ├── interpolation.md
│   │   ├── lowercasing-a-string.md
│   │   ├── matching-strings.md
│   │   ├── repeating.md
│   │   ├── replacing-sub-strings.md
│   │   ├── splitting-a-string.md
│   │   ├── trimming-whitespace-from-a-string.md
│   │   └── uppercasing-a-string.md
│   ├── syntax/
│   │   ├── code_reuse_on_client_and_server.md
│   │   ├── comparing_ranges.md
│   │   ├── embedding_javascript.md
│   │   ├── for_loops.md
│   │   └── index.html
│   └── testing/
│       ├── index.html
│       ├── testing_with_jasmine.md
│       └── testing_with_nodeunit.md
├── contributing.md
├── css/
│   ├── autumn.css
│   ├── borland.css
│   ├── bw.css
│   ├── colorful.css
│   ├── default.css
│   ├── emacs.css
│   ├── friendly.css
│   ├── fruity.css
│   ├── manni.css
│   ├── murphy.css
│   ├── native.css
│   ├── pastie.css
│   ├── perldoc.css
│   ├── solarized-light.css
│   ├── style.css
│   ├── tango.css
│   ├── trac.css
│   ├── vim.css
│   └── vs.css
├── designers-guide.md
├── developers-guide.md
├── index.html
├── js/
│   └── scripts.js
├── license.md
├── recipe-template.md
├── terms-of-use.md
└── wanted-recipes.md

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
.rvmrc
_site

*.swp
*.swo

.DS_Store

# IntelliJ IDEA / WebStorm
/.idea/
/*.iml

================================================
FILE: .ruby-gemset
================================================
coffeescript-cookbook


================================================
FILE: .ruby-version
================================================
1.9.3


================================================
FILE: Gemfile
================================================
source 'https://rubygems.org'

group :development do
  gem "github-pages"
  gem "tzinfo-data"

  gem "foreman"
  gem "serve"
end


================================================
FILE: LICENSE-CC-BY.textile
================================================
---
layout: default
title: "Creative Commons License: Attribution 3.0 Unported (CC BY 3.0)"
---

License

THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.

BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS.

1. Definitions

"Adaptation" means a work based upon the Work, or upon the Work and other pre-existing works, such as a translation, adaptation, derivative work, arrangement of music or other alterations of a literary or artistic work, or phonogram or performance and includes cinematographic adaptations or any other form in which the Work may be recast, transformed, or adapted including in any form recognizably derived from the original, except that a work that constitutes a Collection will not be considered an Adaptation for the purpose of this License. For the avoidance of doubt, where the Work is a musical work, performance or phonogram, the synchronization of the Work in timed-relation with a moving image ("synching") will be considered an Adaptation for the purpose of this License.
"Collection" means a collection of literary or artistic works, such as encyclopedias and anthologies, or performances, phonograms or broadcasts, or other works or subject matter other than works listed in Section 1(f) below, which, by reason of the selection and arrangement of their contents, constitute intellectual creations, in which the Work is included in its entirety in unmodified form along with one or more other contributions, each constituting separate and independent works in themselves, which together are assembled into a collective whole. A work that constitutes a Collection will not be considered an Adaptation (as defined above) for the purposes of this License.
"Distribute" means to make available to the public the original and copies of the Work or Adaptation, as appropriate, through sale or other transfer of ownership.
"Licensor" means the individual, individuals, entity or entities that offer(s) the Work under the terms of this License.
"Original Author" means, in the case of a literary or artistic work, the individual, individuals, entity or entities who created the Work or if no individual or entity can be identified, the publisher; and in addition (i) in the case of a performance the actors, singers, musicians, dancers, and other persons who act, sing, deliver, declaim, play in, interpret or otherwise perform literary or artistic works or expressions of folklore; (ii) in the case of a phonogram the producer being the person or legal entity who first fixes the sounds of a performance or other sounds; and, (iii) in the case of broadcasts, the organization that transmits the broadcast.
"Work" means the literary and/or artistic work offered under the terms of this License including without limitation any production in the literary, scientific and artistic domain, whatever may be the mode or form of its expression including digital form, such as a book, pamphlet and other writing; a lecture, address, sermon or other work of the same nature; a dramatic or dramatico-musical work; a choreographic work or entertainment in dumb show; a musical composition with or without words; a cinematographic work to which are assimilated works expressed by a process analogous to cinematography; a work of drawing, painting, architecture, sculpture, engraving or lithography; a photographic work to which are assimilated works expressed by a process analogous to photography; a work of applied art; an illustration, map, plan, sketch or three-dimensional work relative to geography, topography, architecture or science; a performance; a broadcast; a phonogram; a compilation of data to the extent it is protected as a copyrightable work; or a work performed by a variety or circus performer to the extent it is not otherwise considered a literary or artistic work.
"You" means an individual or entity exercising rights under this License who has not previously violated the terms of this License with respect to the Work, or who has received express permission from the Licensor to exercise rights under this License despite a previous violation.
"Publicly Perform" means to perform public recitations of the Work and to communicate to the public those public recitations, by any means or process, including by wire or wireless means or public digital performances; to make available to the public Works in such a way that members of the public may access these Works from a place and at a place individually chosen by them; to perform the Work to the public by any means or process and the communication to the public of the performances of the Work, including by public digital performance; to broadcast and rebroadcast the Work by any means including signs, sounds or images.
"Reproduce" means to make copies of the Work by any means including without limitation by sound or visual recordings and the right of fixation and reproducing fixations of the Work, including storage of a protected performance or phonogram in digital form or other electronic medium.

2. Fair Dealing Rights. Nothing in this License is intended to reduce, limit, or restrict any uses free from copyright or rights arising from limitations or exceptions that are provided for in connection with the copyright protection under copyright law or other applicable laws.

3. License Grant. Subject to the terms and conditions of this License, Licensor hereby grants You a worldwide, royalty-free, non-exclusive, perpetual (for the duration of the applicable copyright) license to exercise the rights in the Work as stated below:

to Reproduce the Work, to incorporate the Work into one or more Collections, and to Reproduce the Work as incorporated in the Collections;
to create and Reproduce Adaptations provided that any such Adaptation, including any translation in any medium, takes reasonable steps to clearly label, demarcate or otherwise identify that changes were made to the original Work. For example, a translation could be marked "The original work was translated from English to Spanish," or a modification could indicate "The original work has been modified.";
to Distribute and Publicly Perform the Work including as incorporated in Collections; and,
to Distribute and Publicly Perform Adaptations.
For the avoidance of doubt:

Non-waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme cannot be waived, the Licensor reserves the exclusive right to collect such royalties for any exercise by You of the rights granted under this License;
Waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme can be waived, the Licensor waives the exclusive right to collect such royalties for any exercise by You of the rights granted under this License; and,
Voluntary License Schemes. The Licensor waives the right to collect royalties, whether individually or, in the event that the Licensor is a member of a collecting society that administers voluntary licensing schemes, via that society, from any exercise by You of the rights granted under this License.
The above rights may be exercised in all media and formats whether now known or hereafter devised. The above rights include the right to make such modifications as are technically necessary to exercise the rights in other media and formats. Subject to Section 8(f), all rights not expressly granted by Licensor are hereby reserved.

4. Restrictions. The license granted in Section 3 above is expressly made subject to and limited by the following restrictions:

You may Distribute or Publicly Perform the Work only under the terms of this License. You must include a copy of, or the Uniform Resource Identifier (URI) for, this License with every copy of the Work You Distribute or Publicly Perform. You may not offer or impose any terms on the Work that restrict the terms of this License or the ability of the recipient of the Work to exercise the rights granted to that recipient under the terms of the License. You may not sublicense the Work. You must keep intact all notices that refer to this License and to the disclaimer of warranties with every copy of the Work You Distribute or Publicly Perform. When You Distribute or Publicly Perform the Work, You may not impose any effective technological measures on the Work that restrict the ability of a recipient of the Work from You to exercise the rights granted to that recipient under the terms of the License. This Section 4(a) applies to the Work as incorporated in a Collection, but this does not require the Collection apart from the Work itself to be made subject to the terms of this License. If You create a Collection, upon notice from any Licensor You must, to the extent practicable, remove from the Collection any credit as required by Section 4(b), as requested. If You create an Adaptation, upon notice from any Licensor You must, to the extent practicable, remove from the Adaptation any credit as required by Section 4(b), as requested.
If You Distribute, or Publicly Perform the Work or any Adaptations or Collections, You must, unless a request has been made pursuant to Section 4(a), keep intact all copyright notices for the Work and provide, reasonable to the medium or means You are utilizing: (i) the name of the Original Author (or pseudonym, if applicable) if supplied, and/or if the Original Author and/or Licensor designate another party or parties (e.g., a sponsor institute, publishing entity, journal) for attribution ("Attribution Parties") in Licensor's copyright notice, terms of service or by other reasonable means, the name of such party or parties; (ii) the title of the Work if supplied; (iii) to the extent reasonably practicable, the URI, if any, that Licensor specifies to be associated with the Work, unless such URI does not refer to the copyright notice or licensing information for the Work; and (iv) , consistent with Section 3(b), in the case of an Adaptation, a credit identifying the use of the Work in the Adaptation (e.g., "French translation of the Work by Original Author," or "Screenplay based on original Work by Original Author"). The credit required by this Section 4 (b) may be implemented in any reasonable manner; provided, however, that in the case of a Adaptation or Collection, at a minimum such credit will appear, if a credit for all contributing authors of the Adaptation or Collection appears, then as part of these credits and in a manner at least as prominent as the credits for the other contributing authors. For the avoidance of doubt, You may only use the credit required by this Section for the purpose of attribution in the manner set out above and, by exercising Your rights under this License, You may not implicitly or explicitly assert or imply any connection with, sponsorship or endorsement by the Original Author, Licensor and/or Attribution Parties, as appropriate, of You or Your use of the Work, without the separate, express prior written permission of the Original Author, Licensor and/or Attribution Parties.
Except as otherwise agreed in writing by the Licensor or as may be otherwise permitted by applicable law, if You Reproduce, Distribute or Publicly Perform the Work either by itself or as part of any Adaptations or Collections, You must not distort, mutilate, modify or take other derogatory action in relation to the Work which would be prejudicial to the Original Author's honor or reputation. Licensor agrees that in those jurisdictions (e.g. Japan), in which any exercise of the right granted in Section 3(b) of this License (the right to make Adaptations) would be deemed to be a distortion, mutilation, modification or other derogatory action prejudicial to the Original Author's honor and reputation, the Licensor will waive or not assert, as appropriate, this Section, to the fullest extent permitted by the applicable national law, to enable You to reasonably exercise Your right under Section 3(b) of this License (right to make Adaptations) but not otherwise.

5. Representations, Warranties and Disclaimer

UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.

6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

7. Termination

This License and the rights granted hereunder will terminate automatically upon any breach by You of the terms of this License. Individuals or entities who have received Adaptations or Collections from You under this License, however, will not have their licenses terminated provided such individuals or entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of this License.
Subject to the above terms and conditions, the license granted here is perpetual (for the duration of the applicable copyright in the Work). Notwithstanding the above, Licensor reserves the right to release the Work under different license terms or to stop distributing the Work at any time; provided, however that any such election will not serve to withdraw this License (or any other license that has been, or is required to be, granted under the terms of this License), and this License will continue in full force and effect unless terminated as stated above.

8. Miscellaneous

Each time You Distribute or Publicly Perform the Work or a Collection, the Licensor offers to the recipient a license to the Work on the same terms and conditions as the license granted to You under this License.
Each time You Distribute or Publicly Perform an Adaptation, Licensor offers to the recipient a license to the original Work on the same terms and conditions as the license granted to You under this License.
If any provision of this License is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this License, and without further action by the parties to this agreement, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
No term or provision of this License shall be deemed waived and no breach consented to unless such waiver or consent shall be in writing and signed by the party to be charged with such waiver or consent.
This License constitutes the entire agreement between the parties with respect to the Work licensed here. There are no understandings, agreements or representations with respect to the Work not specified here. Licensor shall not be bound by any additional provisions that may appear in any communication from You. This License may not be modified without the mutual written agreement of the Licensor and You.
The rights granted under, and the subject matter referenced, in this License were drafted utilizing the terminology of the Berne Convention for the Protection of Literary and Artistic Works (as amended on September 28, 1979), the Rome Convention of 1961, the WIPO Copyright Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996 and the Universal Copyright Convention (as revised on July 24, 1971). These rights and subject matter take effect in the relevant jurisdiction in which the License terms are sought to be enforced according to the corresponding provisions of the implementation of those treaty provisions in the applicable national law. If the standard suite of rights granted under applicable copyright law includes additional rights not granted under this License, such additional rights are deemed to be included in the License; this License is not intended to restrict the license of any rights under applicable law.


================================================
FILE: Procfile
================================================
jekyll: bundle exec jekyll build --watch
serve: bundle exec serve 4000 development _site


================================================
FILE: README.md
================================================
CoffeeScript Cookbook
=============

CoffeeScript Cookbook is a community run website for the CoffeeScript language.
We want you to write recipes and make the site better!

Contributing
-----------

You can find details about contributing [on the site](http://coffeescript-cookbook.github.io/contributing). For now here is a simple formula:

1. Fork the repository at [GitHub](http://github.com/coffeescript-cookbook/coffeescript-cookbook.github.com)
2. Do awesomeness!
3. Send a pull request to [coffeescript-cookbook](http://github.com/coffeescript-cookbook/coffeescript-cookbook.github.com)
4. If we merge your pull request, you get commit access. BAM. Go back to step 2 and stay there as long as you want.

Here are some relevant links from the site.

* [Contributing](http://coffeescript-cookbook.github.io/contributing)
* [Recipe Template](http://coffeescript-cookbook.github.io/recipe-template)
* [Author's Guide](http://coffeescript-cookbook.github.io/authors-guide)
* [Developer's Guide](http://coffeescript-cookbook.github.io/developers-guide)
* [Designer's Guide](http://coffeescript-cookbook.github.io/designers-guide)

Jekyll
------

CoffeeScript Cookbook is currently implemented as a jekyll site. Jekyll is awesome.

* [Site](http://jekyllrb.com/)
* [Code](https://github.com/mojombo/jekyll)
* [Wiki](https://github.com/mojombo/jekyll/wiki)

License
-------

This site and all contributions are [licensed](http://coffeescript-cookbook.github.io/LICENSE-CC-BY) under the Creative Commons Attribution 3.0 Unported (CC BY 3.0) license. By submitting information to this site you agree to grant this license to all users of the site, and that your editing of the authors page constitutes satisfactory attribution.

================================================
FILE: _config.yml
================================================
baseurl: ''
safe: true
highlighter: pygments
lsi: false
markdown: redcarpet
exclude:
  - README.md
  - CNAME
  - TODO.md
  - script
  - Procfile
  - Gemfile
  - Gemfile.lock


================================================
FILE: _data/chapters.yml
================================================
---
- Syntax
- Classes and Objects
- Strings
- Arrays
- Dates and Times
- Math
- Functions
- Metaprogramming
- jQuery
- Ajax
- Regular Expressions
- Networking
- Design Patterns
- Databases
- Testing


================================================
FILE: _layouts/chapter.html
================================================
<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>CoffeeScript Cookbook &raquo; {{ page.title }}</title>
    <link type="image/x-icon" rel="shortcut icon" href="{{ site.baseurl }}/images/favicon.ico">
    <link rel="stylesheet" href="{{ site.baseurl }}/css/style.css" type="text/css">
  </head>
  <body>

    <section class="container">

      <header class="header">
        <h1><a class="" href="{{ site.baseurl }}/"><span class="entypo">&oacute;</span><span class="title ir">CoffeeScript Cookbook</span></a></h1>
      </header>

      <section class="content">

        <article class="content-block">
          <h2>{{ page.title }}</h2>
          {{ content }}
        </article>

        <footer class="footer content-block">
          <p>Don't see the recipe you want? Add it yourself by reading the <a href="{{ site.baseurl }}/contributing">Contributor's Guide</a>, or request it by adding it to <a href="{{ site.baseurl }}/wanted-recipes">Wanted Recipes</a>.</p>
          <a href="{{ site.baseurl }}/license"><img src="{{ site.baseurl }}/images/cc_by_badge.png" /></a>
        </footer>

      </section>

    </section>

    <aside id="sidebar">

      <section class="sidebar-block block-short">
        <nav class="navigation pages-nav home-nav">
          <h6><a class="nav-link" href="{{ site.baseurl }}/"><span class="entypo">&oacute;</span>CoffeeScript Cookbook</a></h6>
          <small class="thin dimmed">(last updated {{ site.time | date: "%d %B, %Y" }})</small>
        </nav>
      </section>

      <section class="sidebar-block">
        <nav class="navigation pages-nav">
          <ul class="plain-list inline-list">
            <li><a class="nav-link" href="{{ site.baseurl }}/contributing"><span class="entypo">6</span>Contribute</a></li>
            <li><a class="nav-link" href="{{ site.baseurl }}/authors"><span class="entypo">,</span>Authors</a></li>
            <li><a class="nav-link" href="{{ site.baseurl }}/license"><span class="entypo">&copy;</span>License</a></li>
          </ul>
        </nav>
      </section>

      <section class="sidebar-block">
        <h5 class="sidebar-title">Chapters Index</h5>
        <ol class="navigation chapters-list">
          {% for chapter in site.data.chapters %}
            {% capture url %}/chapters/{{ chapter | replace: ' ', '_' | downcase }}{% endcapture %}
            {% capture indexurl %}{{ url }}/index.html{% endcapture %}
            <li class="chapter">
              <div class="sidebar-subtitle{% if page.url == indexurl %} page-active{% endif %}"><strong><a class="chapter-title" href="{{ site.baseurl }}{{ url }}">{{ chapter }}</a></strong></div>
              <ul class="pseudo-list recipes-list">
                {% for site_page in site.pages %}
                  {% if site_page.url contains url %}
                    {% unless site_page.url == indexurl %}
                      <li class="list-item recipe{% if page.url == site_page.url %} page-active{% endif %}"><a class="recipe-title" href="{{ site.baseurl }}{{ site_page.url | replace: '.html', '' }}">{{ site_page.title }}</a></li>
                    {% endunless %}
                  {% endif %}
                {% endfor %}
              </ul>
            </li>
          {% endfor %}
        </ol>
      </section>

    </aside>

    <script type="text/javascript" src="{{ site.baseurl }}/js/scripts.js"></script>

 </body>
</html>


================================================
FILE: _layouts/default.html
================================================
<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>CoffeeScript Cookbook &raquo; {{ page.title }}</title>
    <link type="image/x-icon" rel="shortcut icon" href="{{ site.baseurl }}/images/favicon.ico">
    <link rel="stylesheet" href="{{ site.baseurl }}/css/style.css" type="text/css">
  </head>
  <body>

    <section class="container">

      <header class="header">
        <h1><a class="" href="{{ site.baseurl }}/"><span class="entypo">&oacute;</span><span class="title ir">CoffeeScript Cookbook</span></a></h1>
      </header>

      <section class="content">

        <article class="content-block">{{ content }}</article>

        <footer class="footer content-block">
          <p>Don't see a recipe you want? See an entire missing chapter? Add it yourself by reading the <a href="{{ site.baseurl }}/contributing">Contributor's Guide</a>, or request it by adding it to <a href="{{ site.baseurl }}/wanted-recipes">Wanted Recipes</a>.</p>
          <a href="{{ site.baseurl }}/license"><img src="{{ site.baseurl }}/images/cc_by_badge.png" /></a>
        </footer>

      </section>

    </section>

    <aside id="sidebar">

      <section class="sidebar-block block-short">
        <nav class="navigation pages-nav home-nav">
          <h6><a class="nav-link" href="{{ site.baseurl }}/"><span class="entypo">&oacute;</span>CoffeeScript Cookbook</a></h6>
          <small class="thin dimmed">(last updated {{ site.time | date: "%d %B, %Y" }})</small>
        </nav>
      </section>

      <section class="sidebar-block">
        <nav class="navigation pages-nav">
          <ul class="plain-list inline-list">
            <li><a class="nav-link" href="{{ site.baseurl }}/contributing"><span class="entypo">6</span>Contribute</a></li>
            <li><a class="nav-link" href="{{ site.baseurl }}/authors"><span class="entypo">,</span>Authors</a></li>
            <li><a class="nav-link" href="{{ site.baseurl }}/license"><span class="entypo">&copy;</span>License</a></li>
          </ul>
        </nav>
      </section>

      <section class="sidebar-block">
        <h5 class="sidebar-title">Chapters Index</h5>
        <ol class="navigation chapters-list">
          {% for chapter in site.data.chapters %}
            {% capture url %}/chapters/{{ chapter | replace: ' ', '_' | downcase }}{% endcapture %}
            {% capture indexurl %}{{ url }}/index.html{% endcapture %}
            <li class="chapter">
              <div class="sidebar-subtitle{% if page.url == indexurl %} page-active{% endif %}"><strong><a class="chapter-title" href="{{ site.baseurl }}{{ url }}">{{ chapter }}</a></strong></div>
              <ul class="pseudo-list recipes-list">
                {% for site_page in site.pages %}
                  {% if site_page.url contains url %}
                    {% unless site_page.url == indexurl %}
                      <li class="list-item recipe{% if page.url == site_page.url %} page-active{% endif %}"><a class="recipe-title" href="{{ site.baseurl }}{{ site_page.url | replace: '.html', '' }}">{{ site_page.title }}</a></li>
                    {% endunless %}
                  {% endif %}
                {% endfor %}
              </ul>
            </li>
          {% endfor %}
        </ol>
      </section>

    </aside>

    <script type="text/javascript" src="{{ site.baseurl }}/js/scripts.js"></script>

 </body>
</html>


================================================
FILE: _layouts/recipe.html
================================================
<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>CoffeeScript Cookbook &raquo; {{ page.title }}</title>
    <link type="image/x-icon" rel="shortcut icon" href="{{ site.baseurl }}/images/favicon.ico">
    <link rel="stylesheet" href="{{ site.baseurl }}/css/style.css" type="text/css">
  </head>
  <body>

    <section class="container">

      <header class="header">
        <h1><a class="" href="{{ site.baseurl }}/"><span class="entypo">&oacute;</span><span class="title ir">CoffeeScript Cookbook</span></a></h1>
      </header>

      <section class="content">

        <article class="content-block recipe-content">
          <h1>{{ page.title }}</h1>
          {{ content }}
        </article>

        <footer class="footer">
          <p>Is this recipe wrong, incomplete, or non idiomatic? Help fix it by reading the <a href="{{ site.baseurl }}/contributing">Contributor's Guide</a>!</p>
          <a href="{{ site.baseurl }}/license"><img src="{{ site.baseurl }}/images/cc_by_badge.png" /></a>
        </footer>
      </section>

    </section>

    <aside id="sidebar">

      <section class="sidebar-block block-short">
        <nav class="navigation pages-nav home-nav">
          <h6><a class="nav-link" href="{{ site.baseurl }}/"><span class="entypo">&oacute;</span>CoffeeScript Cookbook</a></h6>
          <small class="thin dimmed">(last updated {{ site.time | date: "%d %B, %Y" }})</small>
        </nav>
      </section>

      <section class="sidebar-block">
        <nav class="navigation pages-nav">
          <ul class="plain-list inline-list">
            <li><a class="nav-link" href="{{ site.baseurl }}/contributing"><span class="entypo">6</span>Contribute</a></li>
            <li><a class="nav-link" href="{{ site.baseurl }}/authors"><span class="entypo">,</span>Authors</a></li>
            <li><a class="nav-link" href="{{ site.baseurl }}/license"><span class="entypo">&copy;</span>License</a></li>
          </ul>
        </nav>
      </section>

      <section class="sidebar-block">
        <h5 class="sidebar-title">Chapters Index</h5>
        <ol class="navigation chapters-list">
          {% for chapter in site.data.chapters %}
            {% capture url %}/chapters/{{ chapter | replace: ' ', '_' | downcase }}{% endcapture %}
            {% capture indexurl %}{{ url }}/index.html{% endcapture %}
            <li class="chapter">
              <div class="sidebar-subtitle{% if page.url == indexurl %} page-active{% endif %}"><strong><a class="chapter-title" href="{{ site.baseurl }}{{ url }}">{{ chapter }}</a></strong></div>
              <ul class="pseudo-list recipes-list">
                {% for site_page in site.pages %}
                  {% if site_page.url contains url %}
                    {% unless site_page.url == indexurl %}
                      <li class="list-item recipe{% if page.url == site_page.url %} page-active{% endif %}"><a class="recipe-title" href="{{ site.baseurl }}{{ site_page.url | replace: '.html', '' }}">{{ site_page.title }}</a></li>
                    {% endunless %}
                  {% endif %}
                {% endfor %}
              </ul>
            </li>
          {% endfor %}
        </ol>
      </section>

    </aside>

    <script type="text/javascript" src="{{ site.baseurl }}/js/scripts.js"></script>

 </body>
</html>


================================================
FILE: authors-guide.md
================================================
---
layout: default
title: Author's Guide
---
# Author's Guide

## tl;dr: Look at Other Recipes, and Blend In

Look at the source of other recipe pages and follow that page structure. Start with the [Developer's Guide]({{ site.baseurl }}/developers-guide) to get a test version of the cookbook up and running on your machine, and get to work!

## General Guidelines

* Feel free to add new pages, or even chapters. Just keep them organized. _(See "How to Add a Chapter" below)_
* Try to write well-styled, idiomatic CoffeeScript.
* Try to stay within the Problem/Solution/Discussion format. If you can't think of a good problem for your recipe... hang onto it for a while.
* Sharing code that you think might only be used rarely is fine. Sharing esoteric code tricks is less so. There's a difference between sharing a translator for an obscure format and sharing a weird bit-shifting trick that does fast but inaccurate multiplication.
* Don't forget to add your name to the authors page!

## Use Cookbook Problem/Solution/Discussion Format

A typical cookbook page will have three sections (four if you count the title):

* **Problem** A one- or two-sentence description of the problem, such as "You want to access parts of a string" or "You want to format a floating point number as currency, with a leading dollar sign, two digits of precision and comma-separated triples." Where possible, phrase the problem as though speaking directly to the reader: "You want to...", "You have an X but you want a Y", etc.
* **Solution** State the solution as briefly as possible, ideally as a single sentence that identifies the strategy you would use, and give example code. It's tempting to explain the solution, but don't do it yet. Remember that the reader will look this solution up many times after the first time, and that they will be looking for a quick reference each time. You're going to explain the solution in the **Discussion**, and the first time reader will read your solution, think about it, and then proceed to the discussion if necessary. For example, for "accessing parts of a string", a good Solution sentence might be "Use CoffeeScript's array range subscripts, or JavaScript's slice function."
* **Discussion** Here you should explain why your solution works, or give further examples such as edge cases. If your solution can break on some edge cases, be sure to note them here. For example, if a percentage function crashes when given a zero, you could note this in the discussion and give a workaround. NOTE: If your solution has really dangerous edge cases, so dangerous that you would include them in the solution, please consider whether your recipe should be included at all. Remember, this Cookbook is for good code!

## Copyright Issues

Do not post code that is copyrighted by another user, unless you have permission to use that code AND to relicense that code under the [CC BY 3.0]({{ site.baseurl }}/license) license. If you DO have permission and the author would like credit, please add them to the [authors]({{ site.baseurl }}/authors) page.

Also, just a stylistic note, please do not yank code directly from [http://coffeescript.org/](http://coffeescript.org/) and post it with little or no discussion. The CoffeeScript Cookbook is not affiliated with them. We think they're awesome and want them to like us, too! Make sure that anything taken from [http://coffeescript.org/](http://coffeescript.org/) is permissible use and that it stands alone as a valid recipe. If the recipe is too terse, consider adding more examples and discussion.

## Tag the page with Jekyll frontmatter

...that's a lot of fancy words that mean "don't forget to put the layout, chapter and page title at the top of the file in a YAML block". For example, the string interpolation page begins with

{% highlight text %}
---
layout: recipe
title: String Interpolation
chapter: Strings
---
{% endhighlight %}

## Use Liquid highlighting templates

Turn on syntax highlighting for CoffeeScript with `highlight coffeescript`.

test2

&lbrace;% highlight coffeescript %&rbrace;
&#35; Calculate the square of a number
square = (x) -> x * x

square(16)
&#35; => 256
&lbrace;% endhighlight %&rbrace;

This produces the following:

{% highlight coffeescript %}
# Calculate the square of a number
square = (x) -> x * x

square(16)
# => 256
{% endhighlight %}

## Include Output

After writing an important expression, show the reader what the output would be by adding it with a `# =>` on the following line. Once we get automated script testing working up in this joint, we'll actually load up your recipe snippets and evaluate its expressions against the output comment you wrote. (In other words, `# =>` tells the reader what the output will be, but it tells automated checker what the assertEquals should be)

{% highlight coffeescript %}
# right
[1,2,3].map (x) -> x * 2
# => [ 2, 4, 6 ]

# very wrong!
[1,2,3].map (x) -> x * 2

# right; only add for important/results statements
evens = x for x in [0..10] by 2
evens.some (x) -> x == 6
# => true

# less wrong; may require tweaking the automatic checker
[1,2,3].map (x) -> x * 2 # => [ 2, 4, 6 ]

# less wrong (possibly not wrong at all--the output merely does not match what the coffee interpreter renders)
[1,2,3].map (x) -> x * 2
# => [2,4,6]
{% endhighlight %}

Not all snippets evaluate to something useful. For example, array.forEach has side effects but does not return anything. Also, the console.log() and alert() commands are also side-effect-only commands that return nothing. When possible, try to have your snippets evaluate to something inspectable, and leave displaying to the console or browser out of it. (Unless your snippet is _about_ displaying to the console or browser.)

When in doubt about what output to show, try evaluating your snippet in the coffee interpreter and see what IT thinks. Ideally your output should match, or at least be machine-comparable.

# Grindy HOWTOs

## How to Add a Recipe

Create a new markdown page (or copy the [Recipe Template]({{ site.baseurl }}/recipe-template). The filename should be about the problem, e.g. `finding-last-day-of-the-month.md` or `reversing-arrays.md`. In your file, start with the following template:

{% highlight text %}
---
layout: recipe
title: Title of The Recipe
chapter: Chapter Name
---

## Problem

You have a problem.

## Solution

Do this about it.

## Discussion

Here's why.
{% endhighlight %}

One fussy little bit, the chapter name should match the directory the chapter is in, otherwise the page won't render correctly. For example, if you're writing a recipe for arrays, make sure the chapter is "Arrays", not "arrays" or "aray" ...or especially not "Chapter Name".

## How to Add a Chapter

* Open chapters/index.html and your chapter's name to the yaml list of chapters.
* cd into chapters/ and create the directory for the chapter name. Downcase the name and replace spaces with underscores.
* add an index.html file that uses `layout: chapter`. For convenience, just copy the index.html from another chapter and update the yaml frontmatter to reflect the name of your new chapter.

For example, to add a chapter called "Dates and Times", you would add it to the chapters array:

{% highlight yaml %}
chapters:
- Syntax
- Objects
- Arrays
- Dates and Times
{% endhighlight %}

...and then create that chapter in the file system:

{% highlight bash %}
cd chapters
mkdir dates_and_times
{% endhighlight %}

Now create a new page in that chapter (remember to add its YAML front matter) and once jekyll regenerates the chapter index, your new page should appear.

# FAQ

## I Have a Weird Recipe. Should I Share It?

Maybe! The real question is, is it really useful, or is it just clever? If you have a formatter for a weird Albanian GIS format, that's a real problem that almost nobody would ever have -- but when somebody DOES have that problem, they REALLY need a solution. If you have a bit shifting trick that can swap two numbers using three xor-equals operations, that's a really clever solution but it's not very good CoffeeScript. (For one thing, `x ^= y ^= x ^= y` is not idiomatic, while `[x,y]=[y,x]` is. For another, there's a bug in that code. And once you fix it, there's another bug caused by extrapolating this register trick to a reference-based language where -- look, it's just a bad idea, okay?)

If you have a cool but weird recipe, ask yourself if a reader would genuinely find it useful. Here are two very good questions to consider:

* Does it really solve a problem that an actual person might have?
* If somebody really does have that problem, would your recipe really be the best solution?

If the answer to either question is no, you might have some code that is a "clever solution in search of a problem". If in doubt, ask.

## What If My Recipe is Inefficient/Too Big/Too Slow?

If it solves a problem to which the alternative is to _not_ solve the problem, share it. Let the reader decide if they want to use it. Sometimes we want tight efficient code, other times we want a robust feature set. If the code has abysmal performance characteristics, be sure to warn the reader in the Discussion.

## Can I Edit An Existing Recipe?

Yes. Please improve anything and everything! Be sure to test your changes and make sure that your solution really is better.

## I Have a Really Efficient Solution, But It's Not As Readable As the Existing Recipe. Should I Add It?

See the "Weird Recipe" note above. Do real people in the real world ever hit the performance constraint? If so, then by all means, add your strategy to the existing solution, and be sure to explain why your solution is not idiomatic. If a reader really has that problem, they'll be glad for the extra options.

## I Have A Problem/Solution, But It's Basically Just JavaScript. Should I Add It?

Yes! CoffeeScript compiles to JavaScript, and that means that some of its functionality comes straight from JavaScript. (For example, see [Reversing Arrays]({{ site.baseurl }}/chapters/arrays/reversing-arrays).) But if you're programming in CoffeeScript and you need to reverse an array, this Cookbook should stand ready to tell you it's available to you in CoffeeScript -- even if it's just a straight call into a JavaScript library.

## I Found a Typo. Is That Enough of a Fix? Does That Count?

Absolutely!


================================================
FILE: authors.md
================================================
---
layout: default
title: Authors
---

# Authors

The following people are totally rad and awesome because they have contributed recipes!

* David Brady *ratgeyser@gmail.com*
* John Ford *jwford@gmail.com*
* Steven Reid *steven @ reidnorthwest . com*
* David Moulton *dave@themoultons.net*
* Sebastian Slomski *sebastian@simple-systems.org*
* Aaron Weinberger *aw9994@cs.ship.edu*
* James C. Holder *coffeescriptcookbook.com@thirdtruck.org*
* Jason Giedymin *jasong@apache.org*
* Phil Cohen *github@phlippers.net*
* João Moreno *coffeecb @joaomoreno .com*
* Jeff Pickhardt *pickhardt (at) gmail (dot) com*
* Frederic Hemberger
* Mike Hatfield *oakraven13@gmail.com*
* [Anton Rissanen](http://github.com/antris) *hello@anton.fi*
* Calum Robertson *http://github.com/randusr836*
* Jake Burkhead *https://github.com/jlburkhead*
* [Alex Johnson](https://github.com/nonsensery)
* ...You! What are you waiting for? Check out the [contributing]({{ site.baseurl }}/contributing) section and get cracking!

# Developers

*The following people are amazingly rad and awesome because they have helped fix the code for the site!*

* David Brady *ratgeyser@gmail.com*
* Mike Moore *mike@blowmage.com*
* Peter Hellberg *peter@c7.se*
* Jamie Gaskins *jgaskins@gmail.com*
* Sami Pussinen *me@samipussinen.com*
* [Devin Weaver (@sukima)](https://github.com/sukima)
* ...You! What are you waiting for? Check out the [contributing]({{ site.baseurl }}/contributing) section and get cracking!

# Designers

The following people are astonishingly rad and awesome because they did great design for the site!

* [Amsul](http://github.com/amsul) reach@amsul.ca
* ...You! Check out the [contributing]({{ site.baseurl }}/contributing) section and get cracking!


================================================
FILE: chapters/ajax/ajax_request_without_jquery.md
================================================
---
layout: recipe
title: Ajax Request Without jQuery
chapter: Ajax
---
## Problem

You want to load data from your server via AJAX without using the jQuery library.

## Solution

You will use the native <a href="http://en.wikipedia.org/wiki/XMLHttpRequest" target="_blank">XMLHttpRequest</a> object.

Let's set up a simple test HTML page with a button.

{% highlight html %}
<!DOCTYPE HTML>
<html lang="en-US">
<head>
	<meta charset="UTF-8">
	<title>XMLHttpRequest Tester</title>
</head>
<body>
	<h1>XMLHttpRequest Tester</h1>
	<button id="loadDataButton">Load Data</button>

	<script type="text/javascript" src="XMLHttpRequest.js"></script>
</body>
</html>
{% endhighlight %}

When the button is clicked, we want to send an Ajax request to the server to retrieve some data.  For this sample, we have a small JSON file.

{% highlight javascript %}
// data.json
{
  message: "Hello World"
}
{% endhighlight %}

Next, create the CoffeeScript file to hold the page logic.  The code in this file creates a function to be called when the Load Data button is clicked.

{% highlight coffeescript linenos %}
# XMLHttpRequest.coffee
loadDataFromServer = ->
  req = new XMLHttpRequest()

  req.addEventListener 'readystatechange', ->
    if req.readyState is 4                        # ReadyState Complete
      successResultCodes = [200, 304]
      if req.status in successResultCodes
        data = eval '(' + req.responseText + ')'
        console.log 'data message: ', data.message
      else
        console.log 'Error loading data...'

  req.open 'GET', 'data.json', false
  req.send()

loadDataButton = document.getElementById 'loadDataButton'
loadDataButton.addEventListener 'click', loadDataFromServer, false
{% endhighlight %}

## Discussion

In the above code we grab a handle to the button in our HTML (line 16) and add a *click* event listener (line 17).  In our event listener, we define our callback function as loadDataFromServer.

We define our loadDataFromServer callback beginning on line 2.

We create a XMLHttpRequest request object (line 3) and add a *readystatechange* event handler.  This fires whenever the request's readyState changes.

In the event handler we check to see if the readyState = 4, indicating the request has completed.  Then, we check the request status value.  Both 200 or 304 represent a successful request.  Anything else represents an error condition.

If the request was indeed successful, we eval the JSON returned from the server and assign it to a data variable.  At this point, we can use the returned data in any way we need to.

The last thing we need to do is actually make our request.

Line 13 opens a 'GET' request to retrieve the data.json file.

Line 14 sends our request to the server.

## Older Browser Support

If your application needs to target older versions of Internet Explorer, you will need to ensure the XMLHttpRequest object exists.  You can do this by including this code before creating the XMLHttpRequest instance.

{% highlight coffeescript %}
if (typeof @XMLHttpRequest == "undefined")
  console.log 'XMLHttpRequest is undefined'
  @XMLHttpRequest = ->
    try
      return new ActiveXObject("Msxml2.XMLHTTP.6.0")
    catch error
    try
      return new ActiveXObject("Msxml2.XMLHTTP.3.0")
    catch error
    try
      return new ActiveXObject("Microsoft.XMLHTTP")
    catch error
    throw new Error("This browser does not support XMLHttpRequest.")
{% endhighlight %}

This code ensures the XMLHttpRequest object is available in the global namespace.


================================================
FILE: chapters/ajax/index.html
================================================
---
layout: chapter
title: Ajax
chapter: Ajax
---

{% capture url %}/chapters/{{ page.chapter | replace: ' ', '_' | downcase }}{% endcapture %}
{% capture indexurl %}{{ url }}/index.html{% endcapture %}

<ul>
{% for page in site.pages %}
  {% if page.url contains url %}
    {% unless page.url == indexurl %}
  <li><a href="{{ site.baseurl }}{{ page.url | replace: '.html', '' }}">{{ page.title }}</a></li>
    {% endunless %}
  {% endif %}
{% endfor %}
</ul>


================================================
FILE: chapters/arrays/check-type-is-array.md
================================================
---
layout: recipe
title: Check if type of value is an Array
chapter: Arrays
---
## Problem

You want to check if a value is an `Array`.

{% highlight coffeescript %}
myArray = []
console.log typeof myArray // outputs 'object'
{% endhighlight %}

The `typeof` operator gives a faulty output for arrays.

## Solution

Use the following code:

{% highlight coffeescript %}
typeIsArray = Array.isArray || ( value ) -> return {}.toString.call( value ) is '[object Array]'
{% endhighlight %}

To use this, just call `typeIsArray` as such:

{% highlight coffeescript %}
myArray = []
typeIsArray myArray // outputs true
{% endhighlight %}

## Discussion

The method above has been adopted from "the Miller Device". An alternative is to use Douglas Crockford's snippet:

{% highlight coffeescript %}
typeIsArray = ( value ) ->
    value and
        typeof value is 'object' and
        value instanceof Array and
        typeof value.length is 'number' and
        typeof value.splice is 'function' and
        not ( value.propertyIsEnumerable 'length' )
{% endhighlight %}


================================================
FILE: chapters/arrays/concatenating-arrays.md
================================================
---
layout: recipe
title: Concatenating Arrays
chapter: Arrays
---
## Problem

You want to join two arrays together.

## Solution

There are two standard options for concatenating arrays in JavaScript.

The first is to use JavaScript's Array `concat()` method:

{% highlight coffeescript %}
array1 = [1, 2, 3]
array2 = [4, 5, 6]
array3 = array1.concat array2
# => [1, 2, 3, 4, 5, 6]
{% endhighlight %}

Note that `array1` is _not_ modified by the operation. The concatenated array is returned as a new object.

If you want to merge two arrays without creating a new object, you can use the following technique:

{% highlight coffeescript %}
array1 = [1, 2, 3]
array2 = [4, 5, 6]
Array::push.apply array1, array2
array1
# => [1, 2, 3, 4, 5, 6]
{% endhighlight %}

In the example above, the `Array.prototype.push.apply(a, b)` approach modifies `array1` in place without creating a new array object.

We can simplify the pattern above using CoffeeScript by creating a new `merge()` method for Arrays.

{% highlight coffeescript %}
Array::merge = (other) -> Array::push.apply @, other

array1 = [1, 2, 3]
array2 = [4, 5, 6]
array1.merge array2
array1
# => [1, 2, 3, 4, 5, 6]
{% endhighlight %}

Alternatively, we can pass a CoffeeScript splat (`array2...`) directly into `push()`, avoiding the Array prototype.

{% highlight coffeescript %}
array1 = [1, 2, 3]
array2 = [4, 5, 6]
array1.push array2...
array1
# => [1, 2, 3, 4, 5, 6]
{% endhighlight %}

A more idiomatic approach is to use the splat operator (`...`) directly in an array literal. This can be used to concatenate any number of arrays.

{% highlight coffeescript %}
array1 = [1, 2, 3]
array2 = [4, 5, 6]
array3 = [array1..., array2...]
array3
# => [1, 2, 3, 4, 5, 6]
{% endhighlight %}

## Discussion

CoffeeScript lacks a special syntax for joining arrays, but `concat()` and `push()` are standard JavaScript methods.


================================================
FILE: chapters/arrays/creating-a-dictionary-object-from-an-array.md
================================================
---
layout: recipe
title: Creating a dictionary Object from an Array
chapter: Arrays
---
## Problem

You have an Array of Objects, such as:

{% highlight coffeescript %}
cats = [
  {
    name: "Bubbles"
    age: 1
  },
  {
    name: "Sparkle"
    favoriteFood: "tuna"
  }
]
{% endhighlight %}

But you want to access it as a dictionary by key, like `cats["Bubbles"]`.

## Solution

You need to convert your array into an Object. Use reduce for this.

{% highlight coffeescript %}
# key = The key by which to index the dictionary
Array::toDict = (key) ->
  @reduce ((dict, obj) -> dict[ obj[key] ] = obj if obj[key]?; return dict), {}
{% endhighlight %}

To use this:

{% highlight coffeescript %}
  catsDict = cats.toDict('name')
  catsDict["Bubbles"]
  # => { age: 1, name: "Bubbles" }
{% endhighlight %}

## Discussion

Alternatively, you can use an Array comprehension:

{% highlight coffeescript %}
Array::toDict = (key) ->
  dict = {}
  dict[obj[key]] = obj for obj in this when obj[key]?
  dict
{% endhighlight %}

If you use Underscore.js, you can create a mixin:

{% highlight coffeescript %}
_.mixin toDict: (arr, key) ->
    throw new Error('_.toDict takes an Array') unless _.isArray arr
    _.reduce arr, ((dict, obj) -> dict[ obj[key] ] = obj if obj[key]?; return dict), {}
catsDict = _.toDict(cats, 'name')
catsDict["Sparkle"]
# => { favoriteFood: "tuna", name: "Sparkle" }
{% endhighlight %}

================================================
FILE: chapters/arrays/creating-a-string-from-an-array.md
================================================
---
layout: recipe
title: Creating a String from an Array
chapter: Arrays
---
## Problem

You want to create a string from an array.

## Solution

Use JavaScript's Array toString() method:

{% highlight coffeescript %}
["one", "two", "three"].toString()
# => 'one,two,three'
{% endhighlight %}

## Discussion

`toString()` is a standard JavaScript method. Don't forget the parentheses.


================================================
FILE: chapters/arrays/define-ranges.md
================================================
---
layout: recipe
title: Define Ranges Array
chapter: Arrays
---
## Problem

You want to define a range in an array.

## Solution

There are two ways to define a range of array elements in CoffeeScript.

{% highlight coffeescript %}

# inclusive
myArray = [1..10]
# => [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]

{% endhighlight %}

{% highlight coffeescript %}

# exclusive
myArray = [1...10]
# => [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]

{% endhighlight %}

We can also reverse the range of element by writing it this way.

{% highlight coffeescript %}

myLargeArray = [10..1]
# => [ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 ]

{% endhighlight %}

{% highlight coffeescript %}
myLargeArray = [10...1]
# => [ 10, 9, 8, 7, 6, 5, 4, 3, 2 ]

{% endhighlight %}

## Discussion

Inclusive ranges are defined by the '..' operator and include the last value.

Exclusive ranges are defined by '...', and always omit the last value.



================================================
FILE: chapters/arrays/filtering-arrays.md
================================================
---
layout: recipe
title: Filtering Arrays
chapter: Arrays
---
## Problem

You want to be able to filter arrays based on a boolean condition.

## Solution

Use Array.filter (ECMAScript 5):

{% highlight coffeescript %}
array = [1..10]

array.filter (x) -> x > 5
# => [6,7,8,9,10]
{% endhighlight %}

In pre-EC5 implementations, extend the Array prototype to add a filter function which will take a callback and perform a comprehension over itself, collecting all elements for which the callback is true. Be sure to check if the function is already implemented before overwriting it:

{% highlight coffeescript %}
# Extending Array's prototype
unless Array::filter
  Array::filter = (callback) ->
    element for element in this when callback(element)

array = [1..10]

# Filter odd elements
filtered_array = array.filter (x) -> x % 2 == 0
# => [2,4,6,8,10]

# Filter elements less than or equal to 5:
gt_five = (x) -> x > 5
filtered_array = array.filter gt_five
# => [6,7,8,9,10]
{% endhighlight %}

## Discussion

This is similar to using ruby's Array#select method.


================================================
FILE: chapters/arrays/index.html
================================================
---
layout: chapter
title: Arrays
chapter: Arrays
---

{% capture url %}/chapters/{{ page.chapter | replace: ' ', '_' | downcase }}{% endcapture %}
{% capture indexurl %}{{ url }}/index.html{% endcapture %}

<ul>
{% for page in site.pages %}
  {% if page.url contains url %}
    {% unless page.url == indexurl %}
  <li><a href="{{ site.baseurl }}{{ page.url | replace: '.html', '' }}">{{ page.title }}</a></li>
    {% endunless %}
  {% endif %}
{% endfor %}
</ul>


================================================
FILE: chapters/arrays/list-comprehensions.md
================================================
---
layout: recipe
title: List Comprehensions
chapter: Arrays
---
## Problem

You have an array of objects and want to map them to another array, similar to Python's list comprehensions.

## Solution

Use a list comprehension, but don't forget about [mapping arrays]({{ site.baseurl }}/chapters/arrays/mapping-arrays).

{% highlight coffeescript %}
electric_mayhem = [ { name: "Doctor Teeth", instrument: "piano" },
                    { name: "Janice", instrument: "lead guitar" },
                    { name: "Sgt. Floyd Pepper", instrument: "bass" },
                    { name: "Zoot", instrument: "sax" },
                    { name: "Lips", instrument: "trumpet" },
                    { name: "Animal", instrument: "drums" } ]

names = (muppet.name for muppet in electric_mayhem)
# => [ 'Doctor Teeth', 'Janice', 'Sgt. Floyd Pepper', 'Zoot', 'Lips', 'Animal' ]
{% endhighlight %}

## Discussion

Because CoffeeScript directly support list comprehensions, they work pretty much as advertised wherever you would use one in Python. For simple mappings, list comprehensions are much more readable. For complicated transformations or for chained mappings, [mapping arrays]({{ site.baseurl }}/chapters/arrays/mapping-arrays) might be more elegant.


================================================
FILE: chapters/arrays/mapping-arrays.md
================================================
---
layout: recipe
title: Mapping Arrays
chapter: Arrays
---
## Problem

You have an array of objects and want to map them to another array, similar to Ruby's map.

## Solution

Use map() with an anonymous function, but don't forget about <a href="{{ site.baseurl }}/chapters/arrays/list-comprehensions">list comprehensions</a>.

{% highlight coffeescript %}
electric_mayhem = [ { name: "Doctor Teeth", instrument: "piano" },
                    { name: "Janice", instrument: "lead guitar" },
                    { name: "Sgt. Floyd Pepper", instrument: "bass" },
                    { name: "Zoot", instrument: "sax" },
                    { name: "Lips", instrument: "trumpet" },
                    { name: "Animal", instrument: "drums" } ]

names = electric_mayhem.map (muppet) -> muppet.name
# => [ 'Doctor Teeth', 'Janice', 'Sgt. Floyd Pepper', 'Zoot', 'Lips', 'Animal' ]
{% endhighlight %}

## Discussion

Because CoffeeScript has clean support for anonymous functions, mapping an array in CoffeeScript is nearly as easy as it is in Ruby.

Maps are are good way to handle complicated transforms and chained mappings in CoffeeScript. If your transformation is as simple as the one above, however, it may read more cleanly as a <a href="{{ site.baseurl }}/chapters/arrays/list-comprehensions">list comprehension</a>.


================================================
FILE: chapters/arrays/max-array-value.md
================================================
---
layout: recipe
title: Max Array Value
chapter: Arrays
---
## Problem

You need to find the largest value contained in an array.

## Solution

You can use Math.max() JavaScript method along with splats.

{% highlight coffeescript %}
Math.max [12, 32, 11, 67, 1, 3]...
# => 67
{% endhighlight %}

Alternatively, it's possible to use ES5 `reduce` method. For backward compatibility with older JavaScript implementations, use the above.

{% highlight coffeescript %}
# ECMAScript 5
[12,32,11,67,1,3].reduce (a,b) -> Math.max a, b
# => 67
{% endhighlight %}

## Discussion

`Math.max` compares every argument and returns the largest number from arguments. The ellipsis (`...`) converts every array value into argument which is given to the function. You can also use it with other functions which take variable amount of arguments, such as `console.log`.


================================================
FILE: chapters/arrays/reducing-arrays.md
================================================
---
layout: recipe
title: Reducing Arrays
chapter: Arrays
---
## Problem

You have an array of objects and want to reduce them to a value, similar to Ruby's `reduce()` and `reduceRight()`.

## Solution

You can simply use Array's `reduce()` and `reduceRight()` methods along with an anonymous function, keeping the code clean and readable. The reduction may be something simple such as using the `+` operator with numbers or strings.

{% highlight coffeescript %}
[1,2,3,4].reduce (x,y) -> x + y
# => 10
{% endhighlight %}

{% highlight coffeescript %}
["words", "of", "bunch", "A"].reduceRight (x, y) -> x + " " + y
# => 'A bunch of words'
{% endhighlight %}

Or it may be something more complex such as aggregating elements from a list into a combined object.

{% highlight coffeescript %}
people = [
    { name: 'alec', age: 10 }
    { name: 'bert', age: 16 }
    { name: 'chad', age: 17 }
]

people.reduce (x, y) ->
    x[y.name]= y.age
    x
, {}
# => { alec: 10, bert: 16, chad: 17 }
{% endhighlight %}

## Discussion

Javascript introduced `reduce` and `reduceRight` in version 1.8. Coffeescript provides a natural and simple way to express anonymous functions. Both go together cleanly in the problem of merging a collection's items into a combined result.


================================================
FILE: chapters/arrays/removing-duplicate-elements-from-arrays.md
================================================
---
layout: recipe
title: Removing Duplicate Elements from Arrays
chapter: Arrays
---
## Problem

You want to remove duplicate elements from an array.

## Solution

{% highlight coffeescript %}
Array::unique = ->
  output = {}
  output[@[key]] = @[key] for key in [0...@length]
  value for key, value of output

[1,1,2,2,2,3,4,5,6,6,6,"a","a","b","d","b","c"].unique()
# => [ 1, 2, 3, 4, 5, 6, 'a', 'b', 'd', 'c' ]
{% endhighlight %}

## Discussion

There are many implementations of the `unique` method in JavaScript. This one is based on "The fastest method to find unique items in array" found [here](http://www.shamasis.net/2009/09/fast-algorithm-to-find-unique-items-in-javascript-array/).

**Note:** Although it's quite common in languages like Ruby, extending native objects is often considered bad practice in JavaScript (see: [Maintainable JavaScript: Don’t modify objects you don’t own](http://www.nczonline.net/blog/2010/03/02/maintainable-javascript-dont-modify-objects-you-down-own/); [Extending built-in native objects. Evil or not?](http://perfectionkills.com/extending-built-in-native-objects-evil-or-not/)).




================================================
FILE: chapters/arrays/reversing-arrays.md
================================================
---
layout: recipe
title: Reversing Arrays
chapter: Arrays
---
## Problem

You want to reverse an array.

## Solution

Use JavaScript's Array reverse() method:

{% highlight coffeescript %}
["one", "two", "three"].reverse()
# => ["three", "two", "one"]
{% endhighlight %}

## Discussion

`reverse()` is a standard JavaScript method. Don't forget the parentheses.


================================================
FILE: chapters/arrays/shuffling-array-elements.md
================================================
---
layout: recipe
title: Shuffling Array Elements
chapter: Arrays
---
## Problem

You want to shuffle the elements in an array.

## Solution

The [Fisher-Yates shuffle] is a highly efficient and completely unbiased way to randomize
the elements in an array. It's a fairly simple method: Start at the end of the list, and
swap the last element with a random element from earlier in the list. Go down one and 
repeat, until you're at the beginning of the list, with all of the shuffled elements 
at the end of the list. This [Fisher-Yates shuffle Visualization] may help you understand
the algorithm.

{% highlight coffeescript %}
shuffle = (source) ->
  # Arrays with < 2 elements do not shuffle well. Instead make it a noop.
  return source unless source.length >= 2
  # From the end of the list to the beginning, pick element `index`.
  for index in [source.length-1..1]
    # Choose random element `randomIndex` to the front of `index` to swap with.
    randomIndex = Math.floor Math.random() * (index + 1)
    # Swap `randomIndex` with `index`, using destructured assignment
    [source[index], source[randomIndex]] = [source[randomIndex], source[index]]
  source

shuffle([1..9])
# => [ 3, 1, 5, 6, 4, 8, 2, 9, 7 ]
{% endhighlight %}

[Fisher-Yates shuffle]: http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
[Fisher-Yates Shuffle Visualization]: http://bost.ocks.org/mike/shuffle/

## Discussion

### The Wrong Way to do it

There is a common--but terribly wrong way--to shuffle an array, by sorting by a random
number.

{% highlight coffeescript %}
shuffle = (a) -> a.sort -> 0.5 - Math.random()
{% endhighlight %}

If you do a sort randomly, it should give you a random order, right? Even [Microsoft used 
this random-sort algorithm][msftshuffle]. Turns out, [this random-sort algorithm produces
biased results][naive], because it only has the illusion of shuffling. Randomly sorting
will not result in a neat, tidy shuffle; it will result in a wild mass of inconsistent
sorting.

[msftshuffle]: http://www.robweir.com/blog/2010/02/microsoft-random-browser-ballot.html
[naive]: http://www.codinghorror.com/blog/2007/12/the-danger-of-naivete.html

### Optimizing for speed and space

The solution above isn't as fast, or as lean, as it can be. The list comprehension, when
transformed into Javascript, is far more complex than it needs to be, and the
destructured assignment is far slower than dealing with bare variables. The following
code is less idiomatic, and takes up more source-code space... but will compile down
smaller and run a bit faster:

{% highlight coffeescript %}
shuffle = (a) ->
  i = a.length
  while --i > 0
    j = ~~(Math.random() * (i + 1)) # ~~ is a common optimization for Math.floor
    t = a[j]
    a[j] = a[i]
    a[i] = t
  a
{% endhighlight %}

### Extending Javascript to include this shuffle.

The following code adds the shuffle function to the Array prototype, which means that
you are able to run it on any array you wish, in a much more direct manner.

{% highlight coffeescript %}
Array::shuffle ?= ->
  if @length > 1 then for i in [@length-1..1]
    j = Math.floor Math.random() * (i + 1)
    [@[i], @[j]] = [@[j], @[i]]
  this

[1..9].shuffle()
# => [ 3, 1, 5, 6, 4, 8, 2, 9, 7 ]
{% endhighlight %}

**Note:** Although it's quite common in languages like Ruby, extending native objects is 
often considered bad practice in JavaScript (see: [Maintainable JavaScript: Don’t modify 
objects you don’t own][dontown]; [Extending built-in native objects. Evil or not?]
[extendevil]). That being said, the code above is really quite safe to add. It only adds
`Array::shuffle` if it doesn't exist already, thanks to the existential assignment 
operator (`?=`). That way, we don't overwrite someone else's, or a native browser method.

Also, if you think you'll be using a lot of these utility functions, consider using a
utility library, like [Lo-dash](http://lodash.com/)^†. They include a lot of nifty
features, like maps and forEach, in a cross-browser, lean, high-performance way. 

^† [Underscore](http://underscorejs.org/) is also a good alternative to Lo-dash.

[dontown]: http://www.nczonline.net/blog/2010/03/02/maintainable-javascript-dont-modify-objects-you-down-own/
[extendevil]: http://perfectionkills.com/extending-built-in-native-objects-evil-or-not/


================================================
FILE: chapters/arrays/testing-every-element.md
================================================
---
layout: recipe
title: Testing Every Element
chapter: Arrays
---
## Problem

You want to be able to check that every element in an array meets a particular condition.

## Solution

Use Array.every (ECMAScript 5):

{% highlight coffeescript %}
evens = (x for x in [0..10] by 2)

evens.every (x)-> x % 2 == 0
# => true
{% endhighlight %}

Array.every was added to Mozilla's Javascript 1.6 and made standard with ECMAScript 5. If you to support browsers that do not implement EC5 then check out [`_.all` from underscore.js][underscore].

For a real world example, pretend you have a multiple select list that looks like:

{% highlight html %}
<select multiple id="my-select-list">
  <option>1</option>
  <option>2</option>
  <option>Red Car</option>
  <option>Blue Car</option>
</select>
{% endhighlight %}

Now you want to verify that the user selected only numbers. Let's use Array.every:

{% highlight coffeescript %}
validateNumeric = (item)->
  parseFloat(item) == parseInt(item) && !isNaN(item)

values = $("#my-select-list").val()

values.every validateNumeric
{% endhighlight %}

## Discussion

This is similar to using ruby's Array#all? method.

[underscore]: http://documentcloud.github.com/underscore/


================================================
FILE: chapters/arrays/using-arrays-to-swap-variables.md
================================================
---
layout: recipe
title: Using Arrays to Swap Variables
chapter: Arrays
---
## Problem

You want to use an array to swap variables.

## Solution

Use CoffeeScript's [destructuring assignment](http://jashkenas.github.com/coffee-script/#destructuring) syntax:

{% highlight coffeescript %}
a = 1
b = 3

[a, b] = [b, a]

a
# => 3

b
# => 1
{% endhighlight %}

## Discussion

Destructuring assignment allows swapping two values without the use of a temporary variable.

This can be useful when traversing arrays and ensuring iteration only happens over the shortest one:

{% highlight coffeescript %}

ray1 = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
ray2 = [ 5, 9, 14, 20 ]

intersection = (a, b) ->
  [a, b] = [b, a] if a.length > b.length
  value for value in a when value in b

intersection ray1, ray2
# => [ 5, 9 ]

intersection ray2, ray1
# => [ 5, 9 ]

{% endhighlight %}


================================================
FILE: chapters/arrays/where-for-arrays-of-objects.md
================================================
---
layout: recipe
title: where for arrays of objects
chapter: Arrays
---
## Problem

You want to get an array of objects that match your request for some properties

You have an Array of Objects, such as:

{% highlight coffeescript %}
cats = [
  {
    name: "Bubbles"
    favoriteFood: "mice"
    age: 1
  },
  {
    name: "Sparkle"
    favoriteFood: "tuna"
  },
  {
    name: "flyingCat"
    favoriteFood: "mice"
    age: 1
  }
]
{% endhighlight %}

You want to filter with some properties, like cats.where({ age: 1}) or cats.where({ age: 1, favoriteFood: "mice"})

## Solution

You can extend Array like this : 

{% highlight coffeescript %}
Array::where = (query) ->
    return [] if typeof query isnt "object"
    hit = Object.keys(query).length
    @filter (item) ->
        match = 0
        for key, val of query
            match += 1 if item[key] is val
        if match is hit then true else false

cats.where age:1
# => [ { name: 'Bubbles', favoriteFood: 'mice', age: 1 },{ name: 'flyingCat', favoriteFood: 'mice', age: 1 } ]

cats.where age:1, name: "Bubbles"
# => [ { name: 'Bubbles', favoriteFood: 'mice', age: 1 } ]

cats.where age:1, favoriteFood:"tuna"
# => []
{% endhighlight %}

## Discussion

This is an exact match. we could make it more flexible with a matcher function :

{% highlight coffeescript %}
Array::where = (query, matcher = (a,b) -> a is b) ->
    return [] if typeof query isnt "object"
    hit = Object.keys(query).length
    @filter (item) ->
        match = 0
        for key, val of query
            match += 1 if matcher(item[key], val)
        if match is hit then true else false

cats.where name:"bubbles"
# => []
# it's case sensitive

cats.where name:"bubbles", (a, b) -> "#{ a }".toLowerCase() is "#{ b }".toLowerCase()
# => [ { name: 'Bubbles', favoriteFood: 'mice', age: 1 } ]
# now it's case insensitive
{% endhighlight %}

it's more a method to deal with collection and it could be rename as "find" but popular libraries like underscore or lodash name it "where". 


================================================
FILE: chapters/arrays/zip-function.md
================================================
---
layout: recipe
title: Python-like Zip Function
chapter: Arrays
---
## Problem

You want to zip together multiple arrays into an array of arrays, similar to Python's zip function.  Python's zip function returns an array of tuples, where each tuple contains the i-th element from each of the argument arrays.

## Solution

Use the following CoffeeScript code:

{% highlight coffeescript %}
# Usage: zip(arr1, arr2, arr3, ...)
zip = () ->
  lengthArray = (arr.length for arr in arguments)
  length = Math.min(lengthArray...)
  for i in [0...length]
    arr[i] for arr in arguments

zip([0, 1, 2, 3], [0, -1, -2, -3])
# => [[0, 0], [1, -1], [2, -2], [3, -3]]
{% endhighlight %}


================================================
FILE: chapters/classes_and_objects/chaining.md
================================================
---
layout: recipe
title: Chaining Calls to an Object
chapter: Classes and Objects
---
## Problem

You want to call multiple methods on a single object without having to reference that object each time.

## Solution

Return the `this` (i.e. `@`) object after every chained method.

{% highlight coffeescript %}
class CoffeeCup
	constructor:  ->
		@properties=
			strength: 'medium'
			cream: false
			sugar: false
	strength: (newStrength) ->
		@properties.strength = newStrength
		this
	cream: (newCream) ->
		@properties.cream = newCream
		this
	sugar: (newSugar) ->
		@properties.sugar = newSugar
		this

morningCup = new CoffeeCup()

morningCup.properties # => { strength: 'medium', cream: false, sugar: false }

eveningCup = new CoffeeCup().strength('dark').cream(true).sugar(true)

eveningCup.properties # => { strength: 'dark', cream: true, sugar: true }

{% endhighlight %}

## Discussion

The jQuery library uses a similar approach by returning a selector object from every relevant method, modifying it as subsequent methods tweak the selection:

{% highlight coffeescript %}
$('p').filter('.topic').first()
{% endhighlight %}

For your own objects, a touch of metaprogramming can automate the setup process and explicitly state the purpose of returning *this*.

{% highlight coffeescript %}
addChainedAttributeAccessor = (obj, propertyAttr, attr) ->
	obj[attr] = (newValues...) ->
		if newValues.length == 0
			obj[propertyAttr][attr]
		else
			obj[propertyAttr][attr] = newValues[0]
			obj

class TeaCup
	constructor:  ->
		@properties=
			size: 'medium'
			type: 'black'
			sugar: false
			cream: false
		addChainedAttributeAccessor(this, 'properties', attr) for attr of @properties

earlgrey = new TeaCup().size('small').type('Earl Grey').sugar(false)

earlgrey.properties # => { size: 'small', type: 'Earl Grey', sugar: false, cream: false }

earlgrey.sugar true

earlgrey.sugar() # => true
{% endhighlight %}


================================================
FILE: chapters/classes_and_objects/class-methods-and-instance-methods.md
================================================
---
layout: recipe
title: Class Methods and Instance Methods
chapter: Classes and Objects
---
## Problem

You want to create class and instance methods.

## Solution

### Class Method

{% highlight coffeescript %}

class Songs
  @_titles: 0    # Although it's directly accessible, the leading _ defines it by convention as private property.

  @get_count: ->
    @_titles

  constructor: (@artist, @title) ->
    @constructor._titles++     # Refers to <Classname>._titles, in this case Songs.titles

Songs.get_count()
# => 0

song = new Songs("Rick Astley", "Never Gonna Give You Up")
Songs.get_count()
# => 1

song.get_count()
# => TypeError: Object <Songs> has no method 'get_count'

{% endhighlight %}

### Instance Method
{% highlight coffeescript %}

class Songs
  _titles: 0    # Although it's directly accessible, the leading _ defines it by convention as private property.

  get_count: ->
    @_titles

  constructor: (@artist, @title) ->
    @_titles++

song = new Songs("Rick Astley", "Never Gonna Give You Up")
song.get_count()
# => 1

Songs.get_count()
# => TypeError: Object function Songs(artist, title) ... has no method 'get_count'

{% endhighlight %}


## Discussion

Coffeescript will store class methods (also called static methods) on the object itself rather than on the object prototype (and thus on individual object instances), which conserves memory and gives a central location to store class-level values.


================================================
FILE: chapters/classes_and_objects/class-variables-and-instance-variables.md
================================================
---
layout: recipe
title: Class Variables and Instance Variables
chapter: Classes and Objects
---
## Problem

You want to create class variables and instance variables (properties).

## Solution

### Class Variables

{% highlight coffeescript %}
class Zoo
  @MAX_ANIMALS: 50
  MAX_ZOOKEEPERS: 3
  
  helpfulInfo: =>
    "Zoos may contain a maximum of #{@constructor.MAX_ANIMALS} animals and #{@MAX_ZOOKEEPERS} zoo keepers."

Zoo.MAX_ANIMALS
# => 50

Zoo.MAX_ZOOKEEPERS
# => undefined (it is a prototype member)

Zoo::MAX_ZOOKEEPERS
# => 3

zoo = new Zoo
zoo.MAX_ZOOKEEPERS
# => 3
zoo.helpfulInfo()
# => "Zoos may contain a maximum of 50 animals and 3 zoo keepers."

zoo.MAX_ZOOKEEPERS = "smelly"
zoo.MAX_ANIMALS = "seventeen"
zoo.helpfulInfo()
# => "Zoos may contain a maximum of 50 animals and smelly zoo keepers."
{% endhighlight %}


### Instance Variables

You have to define instance variables (i.e. properties) inside a class' method, initialize your defaults in the constructor.

{% highlight coffeescript %}
class Zoo
  constructor: ->
    @animals = [] # Here the instance variable is defined
    
  addAnimal: (name) ->
    @animals.push name


zoo = new Zoo()
zoo.addAnimal 'elephant'

otherZoo = new Zoo()
otherZoo.addAnimal 'lion'

zoo.animals
# => ['elephant']

otherZoo.animals
# => ['lion']
{% endhighlight %}

#### WARNING!
*Do not add the variable accidently to the prototype, by defining it outside the constructor* (Even if mentioned [elsewhere](http://arcturo.github.io/library/coffeescript/03_classes.html#content), this does not work as intended, due to the underlying JavaScript prototype concept).

{% highlight coffeescript %}
class BadZoo
  animals: []           # Translates to BadZoo.prototype.animals = []; and is thus shared between instances
    
  addAnimal: (name) ->
    @animals.push name  # Works due to the prototype concept of Javascript


zoo = new BadZoo()
zoo.addAnimal 'elephant'

otherZoo = new BadZoo()
otherZoo.addAnimal 'lion'

zoo.animals
# => ['elephant','lion'] # Oops...

otherZoo.animals
# => ['elephant','lion'] # Oops...

BadZoo::animals
# => ['elephant','lion'] # The value is stored in the prototype
{% endhighlight %}

## Discussion

Coffeescript will store the values of class variables on the class itself rather than on the prototype it defines. These are useful for defining variables on classes which can't be overwritten by instance attribute variables.


================================================
FILE: chapters/classes_and_objects/cloning.md
================================================
---
layout: recipe
title: Cloning an Object (Deep Copy)
chapter: Classes and Objects
---
## Problem

You want to clone an object with all its sub-objects.

## Solution

{% highlight coffeescript %}
clone = (obj) ->
  if not obj? or typeof obj isnt 'object'
    return obj

  if obj instanceof Date
    return new Date(obj.getTime()) 

  if obj instanceof RegExp
    flags = ''
    flags += 'g' if obj.global?
    flags += 'i' if obj.ignoreCase?
    flags += 'm' if obj.multiline?
    flags += 'y' if obj.sticky?
    return new RegExp(obj.source, flags) 

  newInstance = new obj.constructor()

  for key of obj
    newInstance[key] = clone obj[key]

  return newInstance

x =
  foo: 'bar'
  bar: 'foo'

y = clone(x)

y.foo = 'test'

console.log x.foo isnt y.foo, x.foo, y.foo
# => true, bar, test
{% endhighlight %}

## Discussion

The difference between copying an object through assignment and through this clone-function is how they handle references. The assignment only copies the object's reference, whereas the clone-function creates a complete new object by

* creating a new object like the source object,
* copying all attributes form the source object to the new object and
* repeating these steps for all sub-objects by calling the clone-function recursively.

Example of an assignment copy:

{% highlight coffeescript %}
x =
  foo: 'bar'
  bar: 'foo'

y = x

y.foo = 'test'

console.log x.foo isnt y.foo, x.foo, y.foo
# => false, test, test
{% endhighlight %}

As you can see, when you change `y` after the copy, you also change `x`.


================================================
FILE: chapters/classes_and_objects/index.html
================================================
---
layout: chapter
title: Classes and Objects
chapter: Classes and Objects
---

{% capture url %}/chapters/{{ page.chapter | replace: ' ', '_' | downcase }}{% endcapture %}
{% capture indexurl %}{{ url }}/index.html{% endcapture %}

<ul>
{% for page in site.pages %}
  {% if page.url contains url %}
    {% unless page.url == indexurl %}
  <li><a href="{{ site.baseurl }}{{ page.url | replace: '.html', '' }}">{{ page.title }}</a></li>
    {% endunless %}
  {% endif %}
{% endfor %}
</ul>


================================================
FILE: chapters/classes_and_objects/mixins.md
================================================
---
layout: recipe
title: Mixins for classes
chapter: Classes and Objects
---
## Problem

You have a few utility methods that you want to include in a number of different classes.

## Solution

Use a mixOf factory function that generates a mixed superclass for you.

{% highlight coffeescript %}
mixOf = (base, mixins...) ->
  class Mixed extends base
  for mixin in mixins by -1 #earlier mixins override later ones
    for name, method of mixin::
      Mixed::[name] = method
  Mixed

...

class DeepThought
  answer: ->
    42
    
class PhilosopherMixin
  pontificate: ->
    console.log "hmm..."
    @wise = yes

class DeeperThought extends mixOf DeepThought, PhilosopherMixin
  answer: ->
    @pontificate()
    super()
    
earth = new DeeperThought
earth.answer()
# hmm...
# => 42
{% endhighlight %}

## Discussion

This is intended for lightweight mixins. Thus you inherit methods of the
base and its ancestors, and those of the mixins, but not those of the ancestors of 
the mixins. Also, after declaring a mixed class, further changes in the mixins are not 
reflected.


================================================
FILE: chapters/classes_and_objects/object-literal.md
================================================
---
layout: recipe
title: Create an Object Literal if It Does Not Already Exist
chapter: Classes and Objects
---
## Problem

You want to initialize an object literal, but you do not want to overwrite the object if it already exists.

## Solution

Use the Existential operator

{% highlight coffeescript %}
window.MY_NAMESPACE ?= {}
{% endhighlight %}

## Discussion

This is equivalent to the following JavaScript:

{% highlight javascript %}
if(window.MY_NAMESPACE === null || window.MY_NAMESPACE === undefined) {
  window.MY_NAMESPACE = {};
}
{% endhighlight %}

## Problem

You want to make a conditonal assignment if it does not exists or if it is falsy (empty, 0, null, false)

## Solution

Use the Conditional assignment operator

{% highlight coffeescript %}
window.my_variable ||= {}
{% endhighlight %}

## Discussion

This is equivalent to the following JavaScript:

{% highlight javascript %}
window.my_variable = window.my_variable || {};
{% endhighlight %}

Common JavaScript technique, using conditional assignment to ensure that we have an object that is not falsy


================================================
FILE: chapters/classes_and_objects/type-function.md
================================================
---
layout: recipe
title: A CoffeeScript Type Function
chapter: Classes and Objects
---
## Problem

You'd like to know the type of a object without using typeof. (See http://javascript.crockford.com/remedial.html for more information on why typeof is pretty inferior.)

## Solution

Use the following function:

{% highlight coffeescript %}
  type = (obj) ->
    if obj == undefined or obj == null
      return String obj
    classToType = {
      '[object Boolean]': 'boolean',
      '[object Number]': 'number',
      '[object String]': 'string',
      '[object Function]': 'function',
      '[object Array]': 'array',
      '[object Date]': 'date',
      '[object RegExp]': 'regexp',
      '[object Object]': 'object'
    }
    return classToType[Object.prototype.toString.call(obj)]
{% endhighlight %}

## Discussion

This function was modeled on jQuery's [$.type function](http://api.jquery.com/jQuery.type/). 

Note that, as an alternative to type checking, you can often use duck typing and the existential operator together to eliminating the need to examine an object's type, in certain cases.  For example, here is exception-free code that pushes an element to an array, if myArray is in fact an array (or array-like, with a push function), and does nothing otherwise.

{% highlight coffeescript %}
myArray?.push? myValue
{% endhighlight %}


================================================
FILE: chapters/databases/index.html
================================================
---
layout: chapter
title: Databases
chapter: Databases
---

{% capture url %}/chapters/{{ page.chapter | replace: ' ', '_' | downcase }}{% endcapture %}
{% capture indexurl %}{{ url }}/index.html{% endcapture %}

<ul>
{% for page in site.pages %}
  {% if page.url contains url %}
    {% unless page.url == indexurl %}
  <li><a href="{{ site.baseurl }}{{ page.url | replace: '.html', '' }}">{{ page.title }}</a></li>
    {% endunless %}
  {% endif %}
{% endfor %}
</ul>


================================================
FILE: chapters/databases/mongodb.md
================================================
---
layout: recipe
title: MongoDB
chapter: Databases
---
## Problem

You need to interface with a MongoDB database.

## Solution

### For Node.js

### Setup
* [Install MongoDB](http://www.mongodb.org/display/DOCS/Quickstart) on your computer if you have not already.

* [Install the native MongoDB module](https://github.com/christkv/node-mongodb-native).

#### Saving Records

{% highlight coffeescript %}
mongo = require 'mongodb'

server = new mongo.Server "127.0.0.1", 27017, {}

client = new mongo.Db 'test', server, {w:1}

# save() updates existing records or inserts new ones as needed
exampleSave = (dbErr, collection) ->
	console.log "Unable to access database: #{dbErr}" if dbErr
	collection.save { _id: "my_favorite_latte", flavor: "honeysuckle" }, (err, docs) ->
		console.log "Unable to save record: #{err}" if err
		client.close()

client.open (err, database) ->
	client.collection 'coffeescript_example', exampleSave
{% endhighlight %}

#### Finding Records

{% highlight coffeescript %}
mongo = require 'mongodb'

server = new mongo.Server "127.0.0.1", 27017, {}

client = new mongo.Db 'test', server, {w:1}

exampleFind = (dbErr, collection) ->
	console.log "Unable to access database: #{dbErr}" if dbErr
	collection.find({ _id: "my_favorite_latte" }).nextObject (err, result) ->
		if err
			console.log "Unable to find record: #{err}"
		else
			console.log result # => {  id: "my_favorite_latte", flavor: "honeysuckle" }
		client.close()

client.open (err, database) ->
	client.collection 'coffeescript_example', exampleFind
{% endhighlight %}

### For Browsers

A [REST-based interface](https://github.com/tdegrunt/mongodb-rest) is in the works.  This will provide AJAX-based access.

## Discussion

This recipe breaks the *save* and *find* into separate examples in order to separate the MongoDB-specific concerns from the task of connection and callback management.  The [async module](https://github.com/caolan/async) can help with that.


================================================
FILE: chapters/databases/sqlite.md
================================================
---
layout: recipe
title: SQLite
chapter: Databases
---
## Problem

You need to interface with a [SQLite](http://www.sqlite.org/) database from inside of Node.js.

## Solution

Use the [SQLite module](http://code.google.com/p/node-sqlite/).

{% highlight coffeescript %}
sqlite = require 'sqlite'

db = new sqlite.Database

# The module uses asynchronous methods,
# so we chain the calls the db.execute
exampleCreate = ->
	db.execute "CREATE TABLE snacks (name TEXT(25), flavor TEXT(25))",
		(exeErr, rows) ->
			throw exeErr if exeErr
			exampleInsert()

exampleInsert = ->
	db.execute "INSERT INTO snacks (name, flavor) VALUES ($name, $flavor)",
		{ $name: "Potato Chips", $flavor: "BBQ" },
		(exeErr, rows) ->
			throw exeErr if exeErr
			exampleSelect()

exampleSelect = ->
	db.execute "SELECT name, flavor FROM snacks",
		(exeErr, rows) ->
			throw exeErr if exeErr
			console.log rows[0] # => { name: 'Potato Chips', flavor: 'BBQ' }

# :memory: creates a DB in RAM
# You can supply a filepath (like './example.sqlite') to create/open one on disk
db.open ":memory:", (openErr) ->
	throw openErr if openErr
	exampleCreate()
{% endhighlight %}

## Discussion

You can also prepare your SQL queries beforehand:

{% highlight coffeescript %}
sqlite = require 'sqlite'
async = require 'async' # Not required but added to make the example more concise

db = new sqlite.Database

createSQL = "CREATE TABLE drinks (name TEXT(25), price NUM)"

insertSQL = "INSERT INTO drinks (name, price) VALUES (?, ?)"

selectSQL = "SELECT name, price FROM drinks WHERE price < ?"

create = (onFinish) ->
	db.execute createSQL, (exeErr) ->
		throw exeErr if exeErr
		onFinish()
	
prepareInsert = (name, price, onFinish) ->
	db.prepare insertSQL, (prepErr, statement) ->
		statement.bindArray [name, price], (bindErr) ->
			statement.fetchAll (fetchErr, rows) -> # Called so that it executes the insert
				onFinish()

prepareSelect = (onFinish) ->
	db.prepare selectSQL, (prepErr, statement) ->
		statement.bindArray [1.00], (bindErr) ->
			statement.fetchAll (fetchErr, rows) ->
				console.log rows[0] # => { name: "Mia's Root Beer", price: 0.75 }
				onFinish()

db.open ":memory:", (openErr) ->
	async.series([
		(onFinish) -> create onFinish,
		(onFinish) -> prepareInsert "LunaSqueeze", 7.95, onFinish,
		(onFinish) -> prepareInsert "Viking Sparkling Grog", 4.00, onFinish,
		(onFinish) -> prepareInsert "Mia's Root Beer", 0.75, onFinish,
		(onFinish) -> prepareSelect onFinish
	])
{% endhighlight %}

The [SQLite version of SQL](http://www.sqlite.org/lang.html) and the [node-sqlite module documentation](https://github.com/orlandov/node-sqlite#readme) provide more complete information.



================================================
FILE: chapters/dates_and_times/date-of-easter.md
================================================
---
layout: recipe
title: Calculate the Date of Easter Sunday
chapter: Dates and Times
---
## Problem

You need to find the month and day of the Easter Sunday for given year.

## Solution

The following function returns array with two elements: month (1-12) and day of the Easter Sunday. If no arguments are given
result is for the current year.
This is an implementation of [Anonymous Gregorian algorithm](http://en.wikipedia.org/wiki/Computus#Anonymous_Gregorian_algorithm) in CoffeeScript.

{% highlight coffeescript %}

gregorianEaster = (year = (new Date).getFullYear()) ->
  a = year % 19
  b = ~~(year / 100)
  c = year % 100
  d = ~~(b / 4)
  e = b % 4
  f = ~~((b + 8) / 25)
  g = ~~((b - f + 1) / 3)
  h = (19 * a + b - d - g + 15) % 30
  i = ~~(c / 4)
  k = c % 4
  l = (32 + 2 * e + 2 * i - h - k) % 7
  m = ~~((a + 11 * h + 22 * l) / 451)
  n = h + l - 7 * m + 114
  month = ~~(n / 31)
  day = (n % 31) + 1
  [month, day]

{% endhighlight %}

## Discussion

NB! Javascript numbers months from 0 to 11 so .getMonth() for date in March will return 2, this function will return 3.
You can modify the function if you want this to be consistent.

The function uses ~~ trick instead of Math.floor().

{% highlight coffeescript %}

gregorianEaster()    # => [4, 24] (April 24th in 2011)
gregorianEaster 1972 # => [4, 2]

{% endhighlight %}


================================================
FILE: chapters/dates_and_times/date-of-thanksgiving.md
================================================
---
layout: recipe
title: Calculate the Date of Thanksgiving (USA and Canada)
chapter: Dates and Times
---
## Problem

You need to calculate when Thanksgiving is in a given year.

## Solution

The following functions return the day of Thanksgiving for a given year. If no year is given then current year is used.

In the USA Thanksgiving is celebrated on the fourth Thursday in November:

{% highlight coffeescript %}

thanksgivingDayUSA = (year = (new Date).getFullYear()) ->
  first = new Date year, 10, 1
  day_of_week = first.getDay()
  22 + (11 - day_of_week) % 7

{% endhighlight %}

In Canada it is the second Monday in October:

{% highlight coffeescript %}

thanksgivingDayCA = (year = (new Date).getFullYear()) ->
    first = new Date year, 9, 1
    day_of_week = first.getDay()
    8 + (8 - day_of_week) % 7

{% endhighlight %}

## Discussion

{% highlight coffeescript %}

thanksgivingDayUSA() #=> 24 (November 24th, 2011)

thanksgivingDayCA() # => 10 (October 10th, 2011)

thanksgivingDayUSA(2012) # => 22 (November 22nd)

thanksgivingDayCA(2012) # => 8 (October 8th)

{% endhighlight %}

The idea is very simple:
1. Find out what day of the week is the first day of respective month (November for USA, October for Canada).
2. Calculate offset from that day to the next occurrence of weekday required (Thursday for USA, Monday for Canada).
3. Add that offset to the first possible date of the holiday (22nd for USA Thanksgiving, 8th for Canada).


================================================
FILE: chapters/dates_and_times/days-between-two-dates.md
================================================
---
layout: recipe
title: Get Days Between Two Dates
chapter: Dates and Times
---
## Problem

You need to find how many seconds, minutes, hours, days, months or years have passed between two dates.

## Solution

Use JavaScript's Date function  getTime(). Which provides how much time in milliseconds have passed since 01/01/1970:

{% highlight coffeescript %}
DAY = 1000 * 60 * 60  * 24

d1 = new Date('02/01/2011')
d2 = new Date('02/06/2011')

days_passed = Math.round((d2.getTime() - d1.getTime()) / DAY)
{% endhighlight %}

## Discussion

Using milliseconds makes the life easier to avoid overflow mistakes with Dates. So we first calculate how many milliseconds are in a day.
Then, given two distinct dates, get the difference in milliseconds between two dates and then divide by how many milliseconds are in a day. It will return the days between two distinct dates.

If you'd like to calculate the hours between two date objects, you can do that by dividing the difference in milliseconds by the conversion of milliseconds to hours. The same goes for minutes and seconds.

{% highlight coffeescript %}
HOUR = 1000 * 60 * 60

d1 = new Date('02/01/2011 02:20')
d2 = new Date('02/06/2011 05:20')

hour_passed = Math.round((d2.getTime() - d1.getTime()) / HOUR)
{% endhighlight %}


================================================
FILE: chapters/dates_and_times/finding-last-day-of-the-month.md
================================================
---
layout: recipe
title: Finding the Last Day of the Month
chapter: Dates and Times
---
## Problem

You need to find the last day of the month, but don't want to keep a lookup table of the number of days in each month of the year.

## Solution

Use JavaScript's Date underflow to find the -1th day of the following month:

{% highlight coffeescript %}
now = new Date
lastDayOfTheMonth = new Date(1900+now.getYear(), now.getMonth()+1, 0)
{% endhighlight %}

## Discussion

JavaScript's Date constructor cheerfully handles overflow and underflow conditions, which makes date math very easy. Given this ease of manipulation, it doesn't make sense to worry about how many days are in a given month; just nudge the math around. In December, the solution above will actually ask for the 0th day of the 13th month of the current year, which works out to the day before the 1st day of January of NEXT year, which works out to the 31st day of December of the current year.


================================================
FILE: chapters/dates_and_times/finding-last-or-next-month.md
================================================
---
layout: recipe
title: Finding Last (or Next) Month
chapter: Dates and Times
---
## Problem

You need to calculate a relative date range like "last month" or "next month".

## Solution

Add or subtract from the current month, secure in the knowledge that JavaScript's Date constructor will fix up the math.

{% highlight coffeescript %}
# these examples were written in GMT-6
# Note that these examples WILL work in January!
now = new Date
# => "Sun, 08 May 2011 05:50:52 GMT"

lastMonthStart = new Date 1900+now.getYear(), now.getMonth()-1, 1
# => "Fri, 01 Apr 2011 06:00:00 GMT"

lastMonthEnd = new Date 1900+now.getYear(), now.getMonth(), 0
# => "Sat, 30 Apr 2011 06:00:00 GMT"
{% endhighlight %}

## Discussion

JavaScript Date objects will cheerfully handle underflows and overflows in the month and day fields, and will adjust the date object accordingly. You can ask for the 42nd of March, for example, and will get the 11th of April.

JavaScript Date objects store the year as the number of years since 1900, the month as an integer from 0 to 11, and the date (day of month) as an integer from 1 to 31. In the solution above, last_month_start is obtained by asking for the first day of a month in the current year, but the month is -1 to 10. If month is -1 the Date object will actually return December of the previous year:

{% highlight coffeescript %}
lastNewYearsEve = new Date 1900+now.getYear(), -1, 31
# => "Fri, 31 Dec 2010 07:00:00 GMT"
{% endhighlight %}

The same is true for overflows:

{% highlight coffeescript %}
thirtyNinthOfFourteember = new Date 1900+now.getYear(), 13, 39
# => "Sat, 10 Mar 2012 07:00:00 GMT"
{% endhighlight %}


================================================
FILE: chapters/dates_and_times/index.html
================================================
---
layout: chapter
title: Dates and Times
chapter: Dates and Times
---

{% capture url %}/chapters/{{ page.chapter | replace: ' ', '_' | downcase }}{% endcapture %}
{% capture indexurl %}{{ url }}/index.html{% endcapture %}

<ul>
{% for page in site.pages %}
  {% if page.url contains url %}
    {% unless page.url == indexurl %}
  <li><a href="{{ site.baseurl }}{{ page.url | replace: '.html', '' }}">{{ page.title }}</a></li>
    {% endunless %}
  {% endif %}
{% endfor %}
</ul>


================================================
FILE: chapters/dates_and_times/moon-phase-for-date.md
================================================
---
layout: recipe
title: Calculate Phase of the Moon for a Date
chapter: Dates and Times
---
## Problem

You want to find the current phase of the moon.

## Solution

The following code provides a method to calculate the phase of the moon for a given date.

{% highlight coffeescript %}
# moonPhase.coffee

# Moon-phase calculator
# Roger W. Sinnott, Sky & Telescope, June 16, 2006
# http://www.skyandtelescope.com/observing/objects/javascript/moon_phases
#
# Translated to CoffeeScript by Mike Hatfield @WebCoding4Fun

proper_ang = (big) ->
	tmp = 0
	if big > 0
		tmp = big / 360.0
		tmp = (tmp - (~~tmp)) * 360.0
	else
		tmp = Math.ceil(Math.abs(big / 360.0))
		tmp = big + tmp * 360.0

	tmp

jdn = (date) ->	
	month = date.getMonth()
	day = date.getDate()
	year = date.getFullYear()
	zone = date.getTimezoneOffset() / 1440

	mm = month
	dd = day
	yy = year

	yyy = yy
	mmm = mm
	if mm < 3
		yyy = yyy - 1
		mmm = mm + 12
     
	day = dd + zone + 0.5
	a = ~~( yyy / 100 )
	b = 2 - a + ~~( a / 4 )
	jd = ~~( 365.25 * yyy ) + ~~( 30.6001 * ( mmm+ 1 ) ) + day + 1720994.5
	jd + b if jd > 2299160.4999999
    
moonElong = (jd) ->
	dr    = Math.PI / 180
	rd    = 1 / dr
	meeDT = Math.pow((jd - 2382148), 2) / (41048480 * 86400)
	meeT  = (jd + meeDT - 2451545.0) / 36525
	meeT2 = Math.pow(meeT, 2)
	meeT3 = Math.pow(meeT, 3)
	meeD  = 297.85 + (445267.1115 * meeT) - (0.0016300 * meeT2) + (meeT3 / 545868)
	meeD  = (proper_ang meeD) * dr
	meeM1 = 134.96 + (477198.8676 * meeT) + (0.0089970 * meeT2) + (meeT3 / 69699)
	meeM1 = (proper_ang meeM1) * dr
	meeM  = 357.53 + (35999.0503 * meeT)
	meeM  = (proper_ang meeM) * dr

	elong = meeD * rd + 6.29 * Math.sin( meeM1 )
	elong = elong     - 2.10 * Math.sin( meeM )
	elong = elong     + 1.27 * Math.sin( 2*meeD - meeM1 )
	elong = elong     + 0.66 * Math.sin( 2*meeD )
	elong = proper_ang elong
	elong = Math.round elong

	moonNum = ( ( elong + 6.43 ) / 360 ) * 28
	moonNum = ~~( moonNum )

	if moonNum is 28 then 0 else moonNum

getMoonPhase = (age) ->
	moonPhase = "new Moon"
	moonPhase = "first quarter" if age > 3 and age < 11 
	moonPhase = "full Moon"     if age > 10 and age < 18
	moonPhase = "last quarter"  if age > 17 and age < 25

	if ((age is 1) or (age is 8) or (age is 15) or (age is 22))
		moonPhase = "1 day past " + moonPhase

	if ((age is 2) or (age is 9) or (age is 16) or (age is 23))
		moonPhase = "2 days past " + moonPhase

	if ((age is 3) or (age is 1) or (age is 17) or (age is 24))
		moonPhase = "3 days past " + moonPhase
	
	if ((age is 4) or (age is 11) or (age is 18) or (age is 25))
		moonPhase = "3 days before " + moonPhase
	
	if ((age is 5) or (age is 12) or (age is 19) or (age is 26))
		moonPhase = "2 days before " + moonPhase
	
	if ((age is 6) or (age is 13) or (age is 20) or (age is 27))
		moonPhase = "1 day before " + moonPhase
	
	moonPhase

MoonPhase = exports? and exports or @MoonPhase = {}

class MoonPhase.Calculator
	getMoonDays: (date) ->
		jd = jdn date 
		moonElong jd

	getMoonPhase: (date) ->		
		jd = jdn date 
		getMoonPhase( moonElong jd )
{% endhighlight %}

## Discussion

This code exposes a MoonPhase Calculator object with two methods.  Calculator -> getMoonPhase will return a text representation of the lunar phase for the date provided.

This can be used in both the browser and Node.js.

{% highlight console %}
$ node
> var MoonPhase = require('./moonPhase.js');
 undefined
> var calc = new MoonPhase.Calculator();
 undefined
> calc.getMoonPhase(new Date());
 'full moon'
> calc.getMoonPhase(new Date(1972, 6, 30));
 '3 days before last quarter'
{% endhighlight %}

================================================
FILE: chapters/design_patterns/adapter.md
================================================
---
layout: recipe
title: Adapter pattern
chapter: Design patterns
---
## Problem

Imagine you are traveling to a foreign country and once at your hotel room you realize your power cord socket is not compatible with the wall socket.
Luckily, you remembered you've brought your power adapter with you.
It will connect your power cord socket on one side and wall socket on the other side, allowing for communication between them.

The same situation may arise in code, when 2 (or more) instances (of classes, modules, etc.) want to talk to each other, but whose communication protocol (e.i. the language they use to communicate) is different from each other.
In such a situation, the [Adapter Pattern]({{ site.baseurl }}//en.wikipedia.org/wiki/Adapter_pattern) comes in handy. It will do the translation, from one side to the other.

## Solution

{% highlight coffeescript %}
# a fragment of 3-rd party grid component
class AwesomeGrid
	constructor: (@datasource)->
		@sort_order = 'ASC' 
		@sorter = new NullSorter # in this place we use NullObject pattern (another useful pattern)
	setCustomSorter: (@customSorter) ->
		@sorter = customSorter
	sort: () ->
		@datasource = @sorter.sort @datasource, @sort_order
		# don't forget to change sort order


class NullSorter
	sort: (data, order) -> # do nothing; it is just a stub
	
class RandomSorter
	sort: (data)->
		for i in [data.length-1..1] #let's shuffle the data a bit
    			j = Math.floor Math.random() * (i + 1)
    			[data[i], data[j]] = [data[j], data[i]]
		return data

class RandomSorterAdapter
	constructor: (@sorter) ->
	sort: (data, order) ->
		@sorter.sort data

agrid = new AwesomeGrid ['a','b','c','d','e','f']
agrid.setCustomSorter new RandomSorterAdapter(new RandomSorter)
agrid.sort() # sort data with custom sorter through adapter

{% endhighlight %}

## Discussion

Adapter is useful when you have to organize an interaction between two objects with different interfaces. It can happen when you use 3rd party libraries  or you work with legacy code. 
In any case be careful with adapter: it can be helpful but it can instigate design errors. 


================================================
FILE: chapters/design_patterns/bridge.md
================================================
---
layout: recipe
title: Bridge Pattern
chapter: Design Patterns
---
## Problem

You need to maintain a reliable interface for code that can change frequently or change between multiple implementations.

## Solution

Use the Bridge pattern as an intermediate between the different implementations and the rest of the code.

Assume that you developed an in-browser text editor that saves to the cloud.  Now, however, you need to port it to a stand-alone client that saves locally.

{% highlight coffeescript %}
class TextSaver
	constructor: (@filename, @options) ->
	save: (data) ->

class CloudSaver extends TextSaver
	constructor: (@filename, @options) ->
		super @filename, @options
	save: (data) ->
		# Assuming jQuery
		# Note the fat arrows
		$( =>
			$.post "#{@options.url}/#{@filename}", data, =>
				alert "Saved '#{data}' to #{@filename} at #{@options.url}."
		)

class FileSaver extends TextSaver
	constructor: (@filename, @options) ->
		super @filename, @options
		@fs = require 'fs'
	save: (data) ->
		@fs.writeFile @filename, data, (err) => # Note the fat arrow
			if err? then console.log err
			else console.log "Saved '#{data}' to #{@filename} in #{@options.directory}."

filename = "temp.txt"
data = "Example data"

saver = if window?
	new CloudSaver filename, url: 'http://localhost' # => Saved "Example data" to temp.txt at http://localhost
else if root?
	new FileSaver filename, directory: './' # => Saved "Example data" to temp.txt in ./

saver.save data
{% endhighlight %}

## Discussion

The Bridge pattern helps you to move the implementation-specific code out of sight so that you can focus on your program's specific code.  In the above example, the rest of your application can call `saver.save data` without regard for where the file ultimately ends up.


================================================
FILE: chapters/design_patterns/builder.md
================================================
---
layout: recipe
title: Builder Pattern
chapter: Design Patterns
---
## Problem

You need to prepare a complicated, multi-part object, but you expect to do it more than once or with varying configurations.

## Solution

Create a Builder to encapsulate the object production process.

The [Todo.txt](http://todotxt.com) format provides an advanced but still plain-text method for maintaining lists of to-do items.  Typing out each item by hand would provide exhausting and error-prone, however, so a TodoTxtBuilder class could save us the trouble:

{% highlight coffeescript %}
class TodoTxtBuilder
    constructor: (defaultParameters={ }) ->
        @date = new Date(defaultParameters.date) or new Date
        @contexts = defaultParameters.contexts or [ ]
        @projects = defaultParameters.projects or [ ]
        @priority =  defaultParameters.priority or undefined
    newTodo: (description, parameters={ }) ->
        date = (parameters.date and new Date(parameters.date)) or @date
        contexts = @contexts.concat(parameters.contexts or [ ])
        projects = @projects.concat(parameters.projects or [ ])
        priorityLevel = parameters.priority or @priority
        createdAt = [date.getFullYear(), date.getMonth()+1, date.getDate()].join("-")
        contextNames = ("@#{context}" for context in contexts when context).join(" ")
        projectNames = ("+#{project}" for project in projects when project).join(" ")
        priority = if priorityLevel then "(#{priorityLevel})" else ""
        todoParts = [priority, createdAt, description, contextNames, projectNames]
        (part for part in todoParts when part.length > 0).join " "

builder = new TodoTxtBuilder(date: "10/13/2011")

builder.newTodo "Wash laundry"

# => '2011-10-13 Wash laundry'

workBuilder = new TodoTxtBuilder(date: "10/13/2011", contexts: ["work"])

workBuilder.newTodo "Show the new design pattern to Lucy", contexts: ["desk", "xpSession"]

# => '2011-10-13 Show the new design pattern to Lucy @work @desk @xpSession'

workBuilder.newTodo "Remind Sean about the failing unit tests", contexts: ["meeting"], projects: ["compilerRefactor"], priority: 'A'

# => '(A) 2011-10-13 Remind Sean about the failing unit tests @work @meeting +compilerRefactor'

{% endhighlight %}

## Discussion

The TodoTxtBuilder class takes care of all the heavy lifting of text generation and lets the programmer focus on the unique elements of each to-do item.  Additionally, a command line tool or GUI could plug into this code and still retain support for later, more advanced versions of the format with ease.

### Pre-Construction

Instead of creating a new instance of the needed object from scratch every time, we shift the burden to a separate object that we can then tweak during the object creation process.

{% highlight coffeescript %}
builder = new TodoTxtBuilder(date: "10/13/2011")

builder.newTodo "Order new netbook"

# => '2011-10-13 Order new netbook'

builder.projects.push "summerVacation"

builder.newTodo "Buy suntan lotion"

# => '2011-10-13 Buy suntan lotion +summerVacation'

builder.contexts.push "phone"

builder.newTodo "Order tickets"

# => '2011-10-13 Order tickets @phone +summerVacation'

delete builder.contexts[0]

builder.newTodo "Fill gas tank"

# => '2011-10-13 Fill gas tank +summerVacation'
{% endhighlight %}

### Exercises

* Expand the project- and context-tag generation code to filter out duplicate entries.
* Some Todo.txt users like to insert project and context tags inside the description of their to-do items.  Add code to identify these tags and filter them out of the end tags.


================================================
FILE: chapters/design_patterns/command.md
================================================
---
layout: recipe
title: Command Pattern
chapter: Design Patterns
---
## Problem

You need to let another object handle when your private code is executed.

## Solution

Use the [Command pattern](http://en.wikipedia.org/wiki/Command_pattern) to pass along references to your functions.

{% highlight coffeescript %}
# Using a private variable to simulate external scripts or modules
incrementers = (() ->
	privateVar = 0

	singleIncrementer = () ->
		privateVar += 1

	doubleIncrementer = () ->
		privateVar += 2
	
	commands = 
		single: singleIncrementer
		double: doubleIncrementer
		value: -> privateVar
)()

class RunsAll
	constructor: (@commands...) ->
	run: -> command() for command in @commands

runner = new RunsAll(incrementers.single, incrementers.double, incrementers.single, incrementers.double)
runner.run()
incrementers.value() # => 6
{% endhighlight %}

## Discussion

With functions as first-class objects and with the function-bound variable scope inherited from Javascript, the CoffeeScript language makes the pattern nearly invisible.  In fact, any function passed along as callbacks can act as a *Command*.

The `jqXHR` object returned by jQuery AJAX methods uses this pattern.

{% highlight coffeescript %}
jqxhr = $.ajax
	url: "/"

logMessages = ""

jqxhr.success -> logMessages += "Success!\n"
jqxhr.error -> logMessages += "Error!\n"
jqxhr.complete -> logMessages += "Completed!\n"

# On a valid AJAX request:
# logMessages == "Success!\nCompleted!\n"
{% endhighlight %}



================================================
FILE: chapters/design_patterns/decorator.md
================================================
---
layout: recipe
title: Decorator Pattern
chapter: Design Patterns
---
## Problem

You have a set of data that you need to process in multiple, possibly varying ways.

## Solution

Use the Decorator pattern in order to structure how you apply the changes.

{% highlight coffeescript %}
miniMarkdown = (line) ->
    if match = line.match /^(#+)\s*(.*)$/
        headerLevel = match[1].length
        headerText = match[2]
        "<h#{headerLevel}>#{headerText}</h#{headerLevel}>"
    else
        if line.length > 0
            "<p>#{line}</p>"
        else
            ''

stripComments = (line) ->
    line.replace /\s*\/\/.*$/, '' # Removes one-line, double-slash C-style comments

class TextProcessor
    constructor: (@processors) ->

    reducer: (existing, processor) ->
        if processor
            processor(existing or '')
        else
            existing
    processLine: (text) ->
        @processors.reduce @reducer, text
    processString: (text) ->
        (@processLine(line) for line in text.split("\n")).join("\n")

exampleText = '''
              # A level 1 header
              A regular line
              // a comment
              ## A level 2 header
              A line // with a comment
              '''

processor = new TextProcessor [stripComments, miniMarkdown]

processor.processString exampleText

# => "<h1>A level 1 header</h1>\n<p>A regular line</p>\n\n<h2>A level 2 header</h2>\n<p>A line</p>"
{% endhighlight %}

### Results

{% highlight html %}
<h1>A level 1 header</h1>
<p>A regular line</p>

<h2>A level 1 header</h2>
<p>A line</p>
{% endhighlight %}

## Discussion

The TextProcessor serves the role of Decorator by binding the individual, specialized text processors together.  This frees up the miniMarkdown and stripComments components to focus on handling nothing but a single line of text.  Future developers only have to write functions that return a string and add it to the array of processors.

We can even modify the existing Decorator object on the fly:

{% highlight coffeescript %}
smilies =
    ':)' : "smile"
    ':D' : "huge_grin"
    ':(' : "frown"
    ';)' : "wink"

smilieExpander = (line) ->
    if line
        (line = line.replace symbol, "<img src='#{text}.png' alt='#{text}' />") for symbol, text of smilies
    line

processor.processors.unshift smilieExpander

processor.processString "# A header that makes you :) // you may even laugh"

# => "<h1>A header that makes you <img src='smile.png' alt='smile' /></h1>"

processor.processors.shift()

# => "<h1>A header that makes you :)</h1>"
{% endhighlight %}


================================================
FILE: chapters/design_patterns/factory_method.md
================================================
---
layout: recipe
title: Factory Method Pattern
chapter: Design Patterns
---
## Problem

You don't know what kind of object you will need until runtime.

## Solution

Use the [Factory Method](http://en.wikipedia.org/wiki/Factory_method_pattern) pattern and choose the object to be generated dynamically.

Say that you need to load a file into an editor but you don't know its format until the user chooses the file.  A class using the [Factory Method](http://en.wikipedia.org/wiki/Factory_method_pattern) pattern can serve up different parsers depending on the file's extension.

{% highlight coffeescript %}
class HTMLParser
	constructor: ->
		@type = "HTML parser"
class MarkdownParser
	constructor: ->
		@type = "Markdown parser"
class JSONParser
	constructor: ->
		@type = "JSON parser"

class ParserFactory
	makeParser: (filename) ->
		matches = filename.match /\.(\w*)$/
		extension = matches[1]
		switch extension
			when "html" then new HTMLParser
			when "htm" then new HTMLParser
			when "markdown" then new MarkdownParser
			when "md" then new MarkdownParser
			when "json" then new JSONParser

factory = new ParserFactory

factory.makeParser("example.html").type # => "HTML parser"

factory.makeParser("example.md").type # => "Markdown parser"

factory.makeParser("example.json").type # => "JSON parser"
{% endhighlight %}

## Discussion

In the example, you can ignore the specifics of the file's format and focus on the parsed content.  A more advanced Factory Method might, for instance, also search for versioning data within the file itself before returning a more precise parser (e.g. an HTML5 parser instead of an HTML v4 parser).


================================================
FILE: chapters/design_patterns/index.html
================================================
---
layout: chapter
title: Design Patterns
chapter: Design Patterns
---

{% capture url %}/chapters/{{ page.chapter | replace: ' ', '_' | downcase }}{% endcapture %}
{% capture indexurl %}{{ url }}/index.html{% endcapture %}

<ul>
{% for page in site.pages %}
  {% if page.url contains url %}
    {% unless page.url == indexurl %}
  <li><a href="{{ site.baseurl }}{{ page.url | replace: '.html', '' }}">{{ page.title }}</a></li>
    {% endunless %}
  {% endif %}
{% endfor %}
</ul>


================================================
FILE: chapters/design_patterns/interpreter.md
================================================
---
layout: recipe
title: Interpreter Pattern
chapter: Design Patterns
---
## Problem

Someone else needs to run parts of your code in a controlled fashion.  Alternately, your language of choice cannot express the problem domain in a concise fashion.

## Solution

Use the Interpreter pattern to create a domain-specific language that you translate into specific code.

Assume, for example, that the user wants to perform math inside of your application.  You could let them forward code to _eval_ but that would let them run arbitrary code.  Instead, you can provide a miniature "stack calculator" language that you parse separately in order to only run mathematical operations while reporting more useful error messages.

{% highlight coffeescript %}
class StackCalculator
	parseString: (string) ->
		@stack = [ ]
		for token in string.split /\s+/
			@parseToken token

		if @stack.length > 1
			throw "Not enough operators: numbers left over"
		else
			@stack[0]

	parseToken: (token, lastNumber) ->
		if isNaN parseFloat(token) # Assume that anything other than a number is an operator
			@parseOperator token
		else
			@stack.push parseFloat(token)

	parseOperator: (operator) ->
		if @stack.length < 2
			throw "Can't operate on a stack without at least 2 items"

		right = @stack.pop()
		left = @stack.pop()

		result = switch operator
			when "+" then left + right
			when "-" then left - right
			when "*" then left * right
			when "/"
				if right is 0
					throw "Can't divide by 0"
				else
					left / right
			else
				throw "Unrecognized operator: #{operator}"

		@stack.push result

calc = new StackCalculator

calc.parseString "5 5 +" # => { result: 10 }

calc.parseString "4.0 5.5 +" # => { result: 9.5 }

calc.parseString "5 5 + 5 5 + *" # => { result: 100 }

try
	calc.parseString "5 0 /"
catch error
	error # => "Can't divide by 0"

try
	calc.parseString "5 -"
catch error
	error # => "Can't operate on a stack without at least 2 items"

try
	calc.parseString "5 5 5 -"
catch error
	error # => "Not enough operators: numbers left over"

try
	calc.parseString "5 5 5 foo"
catch error
	error # => "Unrecognized operator: foo"
{% endhighlight %}

## Discussion

As an alternative to writing our own interpreter, you can co-op the existing CoffeeScript interpreter in a such a way that its normal syntax makes for more natural (and therefore more comprehensible) expressions of your algorithm.

{% highlight coffeescript %}
class Sandwich
	constructor: (@customer, @bread='white', @toppings=[], @toasted=false)->

white = (sw) ->
	sw.bread = 'white'
	sw

wheat = (sw) ->
	sw.bread = 'wheat'
	sw

turkey = (sw) ->
	sw.toppings.push 'turkey'
	sw

ham = (sw) ->
	sw.toppings.push 'ham'
	sw

swiss = (sw) ->
	sw.toppings.push 'swiss'
	sw

mayo = (sw) ->
	sw.toppings.push 'mayo'
	sw

toasted = (sw) ->
	sw.toasted = true
	sw

sandwich = (customer) ->
	new Sandwich customer

to = (customer) ->
	customer

send = (sw) ->
	toastedState = sw.toasted and 'a toasted' or 'an untoasted'

	toppingState = ''
	if sw.toppings.length > 0
		if sw.toppings.length > 1
			toppingState = " with #{sw.toppings[0..sw.toppings.length-2].join ', '} and #{sw.toppings[sw.toppings.length-1]}"
		else
			toppingState = " with #{sw.toppings[0]}"
	"#{sw.customer} requested #{toastedState}, #{sw.bread} bread sandwich#{toppingState}"

send sandwich to 'Charlie' # => "Charlie requested an untoasted, white bread sandwich"
send turkey sandwich to 'Judy' # => "Judy requested an untoasted, white bread sandwich with turkey"
send toasted ham turkey sandwich to 'Rachel' # => "Rachel requested a toasted, white bread sandwich with turkey and ham"
send toasted turkey ham swiss sandwich to 'Matt' # => "Matt requested a toasted, white bread sandwich with swiss, ham and turkey"
{% endhighlight %}

This example allows for layers of functions by how it returns the modified object so that outer functions can modify it in turn.  By borrowing a verb and the preposition _to_, the example lends natural grammar to the construction and ends up reading like an actual sentence when used correctly.  This way, both your CoffeeScript skills and your existing language skills can help catch code problems.


================================================
FILE: chapters/design_patterns/memento.md
================================================
---
layout: recipe
title: Memento Pattern
chapter: Design Patterns
---
## Problem

You want to anticipate the reversion of changes to an object.

## Solution

Use the [Memento pattern](http://en.wikipedia.org/wiki/Memento_pattern) to track changes to an object.  The class using the pattern will export a `memento` object stored elsewhere.

If you have application where the user can edit a text file, for example, they may want to undo their last action.  You can save the current state of the file before the user changes it and then roll back to that at a later point.

{% highlight coffeescript %}
class PreserveableText
	class Memento
		constructor: (@text) ->

	constructor: (@text) ->
	save: (newText) ->
		memento = new Memento @text
		@text = newText
		memento
	restore: (memento) ->
		@text = memento.text

pt = new PreserveableText "The original string"
pt.text # => "The original string"

memento = pt.save "A new string"
pt.text # => "A new string"

pt.save "Yet another string"
pt.text # => "Yet another string"

pt.restore memento
pt.text # => "The original string"
{% endhighlight %}

## Discussion

The Memento object returned by `PreserveableText#save` stores the important state information separately for safe-keeping.  You could even serialize this Memento in order to maintain an "undo" buffer on the hard disk or remotely for such data-intensive objects as edited images.


================================================
FILE: chapters/design_patterns/observer.md
================================================
---
layout: recipe
title: Observer Pattern
chapter: Design patterns
---
## Problem

You have to notify some objects about an event happen

## Solution

Use an [Observer Pattern](http://en.wikipedia.org/wiki/Observer_pattern)

{% highlight coffeescript %}

class PostOffice
	constructor: () ->
		@subscribers = []
	notifyNewItemReleased: (item) ->
		subscriber.callback(item) for subscriber in @subscribers when subscriber.item is item
	subscribe: (to, onNewItemReleased) ->
		@subscribers.push {'item':to, 'callback':onNewItemReleased}

class MagazineSubscriber
	onNewMagazine: (item) ->
		alert "I've got new "+item

class NewspaperSubscriber
	onNewNewspaper: (item) ->
		alert "I've got new "+item

postOffice = new PostOffice()
sub1 = new MagazineSubscriber()
sub2 = new NewspaperSubscriber()
postOffice.subscribe "Mens Health", sub1.onNewMagazine
postOffice.subscribe "Times", sub2.onNewNewspaper
postOffice.notifyNewItemReleased "Times"
postOffice.notifyNewItemReleased "Mens Health"

{% endhighlight %}

## Discussion

Here you have an observer object (PostOffice) and observable objects (MagazineSubscriber, NewspaperSubscriber).
To be notified about an event of publishing new periodical observable object should make subscription on PostOffice.
Every of subscribed objects is stored internally in the PostOffice array of subscriptions.
Every subscriber is notified on new concrete periodical is published.


================================================
FILE: chapters/design_patterns/singleton.md
================================================
---
layout: recipe
title: Singleton Pattern
chapter: Design Patterns
---
## Problem

Many times you only want one, and only one, instance of a class. For example, you may only need one class that creates server resources and you want to ensure that the one object can control those resources. Beware, however, because the singleton pattern can be easily abused to mimic unwanted global variables.


## Solution

The publicly available class only contains the method to get the one true instance. The instance is kept within the closure of that public object and is always returned.

This works because CoffeeScript allows you to define executable statements inside a class definition. However, because most CoffeeScript compiles into a [IIFE][] wrapper you do not have to place the private class inside the class definition if this style suits you. The later might be useful when developing modular code such as found in [CommonJS][] (Node.js) or [Require.js][] (See the discussion for an example).

[IIFE]: http://benalman.com/news/2010/11/immediately-invoked-function-expression/
[CommonJS]: http://www.commonjs.org/
[Require.js]: http://requirejs.org/

{% highlight coffeescript %}
class Singleton
  # You can add statements inside the class definition
  # which helps establish private scope (due to closures)
  # instance is defined as null to force correct scope
  instance = null
  # Create a private class that we can initialize however
  # defined inside this scope to force the use of the
  # singleton class.
  class PrivateClass
    constructor: (@message) ->
    echo: -> @message
  # This is a static method used to either retrieve the
  # instance or create a new one.
  @get: (message) ->
    instance ?= new PrivateClass(message)

a = Singleton.get "Hello A"
a.echo() # => "Hello A"

b = Singleton.get "Hello B"
b.echo() # => "Hello A"

Singleton.instance # => undefined
a.instance # => undefined
Singleton.PrivateClass # => undefined
{% endhighlight %}


## Discussion

See in the above example how all instances are outputting from the same instance of the Singleton class. You can also see that the PrivateClass and instance variable are not accessible outside the Singleton class. In essence the Singleton class provides a static method get which returns only one instance of PrivateClass and only one. It also hides the PrivateClass from the world so that you can not create your own.

The idea of hiding or making private the inner workings is preference. Especially since by default CoffeeScript wraps the compiled code inside it's own IIFE (closure) allowing you to define classes without worry that it might be accessible from outside the file. In this example, note that I am using the idiomatic module export feature to emphasize the publicly accessible portion of the module. (See this discussion for further explanation on [exporting to the global namespace][1]).

[1]: http://stackoverflow.com/questions/4214731/coffeescript-global-variables

{% highlight coffeescript %}
root = exports ? this

# Create a private class that we can initialize however
# defined inside the wrapper scope.
class ProtectedClass
  constructor: (@message) ->
  echo: -> @message

class Singleton
  # You can add statements inside the class definition
  # which helps establish private scope (due to closures)
  # instance is defined as null to force correct scope
  instance = null
  # This is a static method used to either retrieve the
  # instance or create a new one.
  @get: (message) ->
    instance ?= new ProtectedClass(message)

# Export Singleton as a module
root.Singleton = Singleton
{% endhighlight %}

Note how incredibly simple coffeescript makes this design pattern. For reference and discussion on nice javascript implementations, check out [Essential JavaScript Design Patterns For Beginners](http://addyosmani.com/resources/essentialjsdesignpatterns/book/).


================================================
FILE: chapters/design_patterns/strategy.md
================================================
---
layout: recipe
title: Strategy Pattern
chapter: Design Patterns
---
## Problem

You have more than one way to solve a problem but you need to choose (or even switch) between these methods at run time.

## Solution

Encapsulate your algorithms inside of Strategy objects.

Given an unsorted list, for example, we can change the sorting algorithm under different circumstances.

###The base class:

{% highlight coffeescript %}
StringSorter = (algorithm) ->
    sort: (list) -> algorithm list
{% endhighlight %}

###The strategies:

{% highlight coffeescript %}
bubbleSort = (list) ->
    anySwaps = false
    swapPass = ->
        for r in [0..list.length-2]
            if list[r] > list[r+1]
                anySwaps = true
                [list[r], list[r+1]] = [list[r+1], list[r]]

    swapPass()
    while anySwaps
        anySwaps = false
        swapPass()
    list

reverseBubbleSort = (list) ->
    anySwaps = false
    swapPass = ->
        for r in [list.length-1..1]
            if list[r] < list[r-1]
                anySwaps = true
                [list[r], list[r-1]] = [list[r-1], list[r]]

    swapPass()
    while anySwaps
        anySwaps = false
        swapPass()
    list
{% endhighlight %}

###Using the strategies:

{% highlight coffeescript %}
sorter = new StringSorter bubbleSort

unsortedList = ['e', 'b', 'd', 'c', 'x', 'a']

sorter.sort unsortedList

# => ['a', 'b', 'c', 'd', 'e', 'x']

unsortedList.push 'w'

# => ['a', 'b', 'c', 'd', 'e', 'x', 'w']

sorter.algorithm = reverseBubbleSort

sorter.sort unsortedList

# => ['a', 'b', 'c', 'd', 'e', 'w', 'x']
{% endhighlight %}

## Discussion

"No plan survives first contact with the enemy", nor users, but we can use the knowledge gained from changing circumstances to adapt.  Near the end of the example, for instance, the newest item in the array now lies out of order.  Knowing that detail, we can then speed the sort up by switching to an algorithm optimized for that exact scenario with nothing but a simple reassignment.

### Exercises

* Expand `StringSorter` into an `AlwaysSortedArray` class that implements all of the functionality of a regular array but which automatically sorts new items based on the method of insertion (e.g. `push` vs. `shift`).


================================================
FILE: chapters/design_patterns/template_method.md
================================================
---
layout: recipe
title: Template Method Pattern
chapter: Design Patterns
---
## Problem

Define the structure of an algorithm as a series of high-level steps, making it possible to specify the behaviour of each step, giving rise to a family of algorithms that have the same structure but different behaviours.

## Solution

Use the Template Method to describe the algorithm structure in a superclass, delegating the implementation of some steps to one or more concrete subclasses.

For example, imagine you wish to model the production of various types of document and each one may contain a header and a body.

{% highlight coffeescript %}
class Document
	produceDocument: ->
		@produceHeader()
		@produceBody()

	produceHeader: ->
	produceBody: ->

class DocWithHeader extends Document
	produceHeader: ->
		console.log "Producing header for DocWithHeader"

	produceBody: ->
		console.log "Producing body for DocWithHeader"

class DocWithoutHeader extends Document
	produceBody: ->
		console.log "Producing body for DocWithoutHeader"

docs = [new DocWithHeader, new DocWithoutHeader]
doc.produceDocument() for doc in docs
{% endhighlight %}

## Discussion

In this example, the algorithm consists of two steps describing document production: one for producing a document header and the second for producing the document body. An empty method implementation for each step is present in the superclass and polymorphism is exploited such that each concrete subclass can provide a different implementation for a step by overriding a step method. In this example,the DocWithHeader implements both the body and header steps, whereas the DocWithoutHeader only implements the body step.

The production of different types of document is then straightforward when document objects are stored in an array, and it is then a simple of matter of iterating over each document object and calling its produceDocument method.

================================================
FILE: chapters/functions/debounce.md
================================================
---
layout: recipe
title: Debounce Functions
chapter: Functions
---
## Problem

You want to execute a function only once, coalescing multiple sequential calls into a single execution at the beginning or end.

## Solution

With a named function:

{% highlight coffeescript %}
debounce: (func, threshold, execAsap) ->
  timeout = null
  (args...) ->
    obj = this
    delayed = ->
      func.apply(obj, args) unless execAsap
      timeout = null
    if timeout
      clearTimeout(timeout)
    else if (execAsap)
      func.apply(obj, args)
    timeout = setTimeout delayed, threshold || 100
{% endhighlight %}

{% highlight coffeescript %}
mouseMoveHandler: (e) ->
  @debounce((e) ->
    # Do something here, but only once 300 milliseconds after the mouse cursor stops.
  300)

someOtherHandler: (e) ->
  @debounce((e) ->
    # Do something here, but only once 250 milliseconds after initial execution.
  250, true)
{% endhighlight %}

## Discussion

Learn about [debouncing JavaScript methods](http://unscriptable.com/2009/03/20/debouncing-javascript-methods/) at John Hann's excellent blog article.



================================================
FILE: chapters/functions/index.html
================================================
---
layout: chapter
title: Functions
chapter: Functions
---

{% capture url %}/chapters/{{ page.chapter | replace: ' ', '_' | downcase }}{% endcapture %}
{% capture indexurl %}{{ url }}/index.html{% endcapture %}

<ul>
{% for page in site.pages %}
  {% if page.url contains url %}
    {% unless page.url == indexurl %}
  <li><a href="{{ site.baseurl }}{{ page.url | replace: '.html', '' }}">{{ page.title }}</a></li>
    {% endunless %}
  {% endif %}
{% endfor %}
</ul>


================================================
FILE: chapters/functions/parentheses.md
================================================
---
layout: recipe
title: When Function Parentheses Are Not Optional
chapter: Functions
---
## Problem

You want to call a function that takes no arguments, but don't want to use parentheses.

## Solution

Use parentheses anyway.

Another alternative is to utilize the do-notation like so:

{% highlight coffeescript %}
notify = -> alert "Hello, user!"
do notify if condition
{% endhighlight %}

This compiles to the following JavaScript:

{% highlight javascript %}
var notify;
notify = function() {
	return alert("Hello, user!");
};
if (condition) {
	notify();
}
{% endhighlight %}

## Discussion

Like Ruby, CoffeeScript allows you to drop parentheses to method calls. Unlike Ruby, however, CoffeeScript treats a bare function name as the pointer to the function. The practical upshot of this is that if you give no arguments to a method, CoffeeScript cannot tell if you want to call the function or use it as a reference.

Is this good or bad? It's just different. It creates an unexpected syntax case -- parentheses aren't _always_ optional -- but in exchange it gives you the ability to pass and receive functions fluently by name, something that's a bit clunky in Ruby.

This usage of the do-notation is a neat approach for CoffeeScript with parenphobia.
Some people simply prefer to write out the parentheses in the function call, though.


================================================
FILE: chapters/functions/recursion.md
================================================
---
layout: recipe
title: Recursive Functions
chapter: Functions
---
## Problem

You want to call a function from within that same function.

## Solution

With a named function:

{% highlight coffeescript %}
ping = ->
	console.log "Pinged"
	setTimeout ping, 1000
{% endhighlight %}

With an unnamed function, using @arguments.callee@:

{% highlight coffeescript %}
delay = 1000

setTimeout((->
	console.log "Pinged"
	setTimeout arguments.callee, delay
	), delay)
{% endhighlight %}

## Discussion

While `arguments.callee` allows for the recursion of anonymous functions and might have the advantage in a very memory-intensive application, named functions keep their purpose more explicit and make for more maintainable code.


================================================
FILE: chapters/functions/splat_arguments.md
================================================
---
layout: recipe
title: Splat Arguments
chapter: Functions
---
## Problem

Your function will be called with a varying number of arguments.

## Solution

Use _splats_.

{% highlight coffeescript %}
loadTruck = (firstDibs, secondDibs, tooSlow...) ->
	truck:
		driversSeat: firstDibs
		passengerSeat: secondDibs
		trunkBed: tooSlow

loadTruck("Amanda", "Joel")
# => { truck: { driversSeat: "Amanda", passengerSeat: "Joel", trunkBed: [] } }

loadTruck("Amanda", "Joel", "Bob", "Mary", "Phillip")
# => { truck: { driversSeat: "Amanda", passengerSeat: "Joel", trunkBed: ["Bob", "Mary", "Phillip"] } }
{% endhighlight %}

With a trailing argument:

{% highlight coffeescript %}
loadTruck = (firstDibs, secondDibs, tooSlow..., leftAtHome) ->
	truck:
		driversSeat: firstDibs
		passengerSeat: secondDibs
		trunkBed: tooSlow
	taxi:
		passengerSeat: leftAtHome

loadTruck("Amanda", "Joel", "Bob", "Mary", "Phillip", "Austin")
# => { truck: { driversSeat: 'Amanda', passengerSeat: 'Joel', trunkBed: [ 'Bob', 'Mary', 'Phillip' ] }, taxi: { passengerSeat: 'Austin' } }

loadTruck("Amanda")
# => { truck: { driversSeat: "Amanda", passengerSeat: undefined, trunkBed: [] }, taxi: undefined }
{% endhighlight %}

## Discussion

By adding an ellipsis (`...`) next to no more than one of a function's arguments, CoffeeScript will combine all of the argument values not captured by other named arguments into a list.  It will serve up an empty list even if some of the named arguments were not supplied.


================================================
FILE: chapters/index.html
================================================
---
layout: default
title: Cookbook
---

<article class="content-block">

  <h5 class="sidebar-title">Chapters</h5>

  <ol class="navigation chapters-list">
    {% for chapter in site.data.chapters %}
      {% capture url %}/chapters/{{ chapter | replace: ' ', '_' | downcase }}{% endcapture %}
      {% capture indexurl %}{{ url }}/index.html{% endcapture %}
      <li class="chapter">
        <h4><a class="chapter-title" href="{{ site.baseurl }}{{ url }}">{{ chapter }}</a></h4>
        <ul class="pseudo-list recipes-list">
          {% for page in site.pages %}
            {% if page.url contains url %}
              {% unless page.url == indexurl %}
                <li class="list-item recipe"><a class="recipe-title" href="{{ site.baseurl }}{{ page.url | replace: '.html', '' }}">{{ page.title }}</a></li>
              {% endunless %}
            {% endif %}
          {% endfor %}
        </ul>
      </li>
    {% endfor %}
  </ol>

</article>


================================================
FILE: chapters/jquery/ajax.md
================================================
---
layout: recipe
title: AJAX
chapter: jQuery
---
## Problem

You want to make AJAX calls using jQuery.

## Solution

{% highlight coffeescript %}
$ ?= require 'jquery' # For Node.js compatibility

$(document).ready ->
	# Basic Examples
	$.get '/', (data) ->
		$('body').append "Successfully got the page."

	$.post '/',
		userName: 'John Doe'
		favoriteFlavor: 'Mint'
		(data) -> $('body').append "Successfully posted to the page."

	# Advanced Settings
	$.ajax '/',
		type: 'GET'
		dataType: 'html'
		error: (jqXHR, textStatus, errorThrown) ->
			$('body').append "AJAX Error: #{textStatus}"
		success: (data, textStatus, jqXHR) ->
			$('body').append "Successful AJAX call: #{data}"

{% endhighlight %}

jQuery 1.5 and later have added a new, supplemental API for handling different callbacks.

{% highlight coffeescript %}
	request = $.get '/'
	request.success (data) -> $('body').append "Successfully got the page again."
	request.error (jqXHR, textStatus, errorThrown) -> $('body').append "AJAX Error: ${textStatus}."
{% endhighlight %}

## Discussion

The jQuery and $ variables can be used interchangeably. See also [Callback bindings]({{ site.baseurl }}/chapters/jquery/callback-bindings-jquery).


================================================
FILE: chapters/jquery/callback-bindings-jquery.md
================================================
---
layout: recipe
title: Callback Bindings # using => instead of ->
chapter: jQuery
---
## Problem

You want to bind a callback function to an object.

## Solution

{% highlight coffeescript %}
$ ->
  class Basket
    constructor: () ->
      @products = []

      $('.product').click (event) =>
        @add $(event.currentTarget).attr 'id'

    add: (product) ->
      @products.push product
      console.log @products

  new Basket()
{% endhighlight %}

## Discussion

By using the fat arrow (`=>`) instead of the normal arrow (`->`) the function gets
automatically bound to the object and can access the `@-variable`.


================================================
FILE: chapters/jquery/index.html
================================================
---
layout: chapter
title: jQuery
chapter: jQuery
---

{% capture url %}/chapters/{{ page.chapter | replace: ' ', '_' | downcase }}{% endcapture %}
{% capture indexurl %}{{ url }}/index.html{% endcapture %}

<ul>
{% for page in site.pages %}
  {% if page.url contains url %}
    {% unless page.url == indexurl %}
  <li><a href="{{ site.baseurl }}{{ page.url | replace: '.html', '' }}">{{ page.title }}</a></li>
    {% endunless %}
  {% endif %}
{% endfor %}
</ul>


================================================
FILE: chapters/jquery/plugin.md
================================================
---
layout: recipe
title: Create a jQuery Plugin
chapter: jQuery
---
## Problem

You'd like to create jQuery plugin using CoffeeScript

## Solution

{% highlight coffeescript %}
# Reference jQuery
$ = jQuery

# Adds plugin object to jQuery
$.fn.extend
  # Change pluginName to your plugin's name.
  pluginName: (options) ->
    # Default settings
    settings =
      option1: true
      option2: false
      debug: false

    # Merge default settings with options.
    settings = $.extend settings, options

    # Simple logger.
    log = (msg) ->
      console?.log msg if settings.debug

    # _Insert magic here._
    return @each ()->
      log "Preparing magic show."
      # You can use your settings in here now.
      log "Option 1 value: #{settings.option1}"
{% endhighlight %}

## Discussion

Here are a couple of examples of how to use your new plugin.

### JavaScript

{% highlight javascript %}
$("body").pluginName({
  debug: true
});

{% endhighlight %}

### CoffeeScript:

{% highlight coffeescript %}
$("body").pluginName
  debug: true

{% endhighlight %}


================================================
FILE: chapters/math/constants.md
================================================
---
layout: recipe
title: Math Constants
chapter: Math
---
## Problem

You need to use common mathematical constants like pi or e.

## Solution

Use Javascript's Math object to provide commonly needed mathematical constants.

{% highlight coffeescript %}
Math.PI
# => 3.141592653589793

# Note: Capitalization matters! This produces no output, it's undefined.
Math.Pi
# =>

Math.E
# => 2.718281828459045

Math.SQRT2
# => 1.4142135623730951

Math.SQRT1_2
# => 0.7071067811865476

# Natural log of 2. ln(2)
Math.LN2
# => 0.6931471805599453

Math.LN10
# => 2.302585092994046

Math.LOG2E
# => 1.4426950408889634

Math.LOG10E
# => 0.4342944819032518

{% endhighlight %}

## Discussion

For another example of how a math constant is used in a real world problem, refer to the [Converting Radians and Degrees]({{ site.baseurl }}/chapters/math/radians-degrees) section of this Math chapter.


================================================
FILE: chapters/math/fast-fibonacci.md
================================================
---
layout: recipe
title: Faster Fibonacci Algorithm
chapter: Math
---
## Problem

You would like to calculate a number N in the Fibonacci sequence but want
to do it quickly.

## Solution

The following solution (which can still be improved on) was originally
talked about on Robin Houston's blog.

Here are a few links talking about the algorithm and ways to improve it:
* [http://bosker.wordpress.com/2011/04/29/the-worst-algorithm-in-the-world/](http://bosker.wordpress.com/2011/04/29/the-worst-algorithm-in-the-world/)
* [http://www.math.rutgers.edu/~erowland/fibonacci](http://www.math.rutgers.edu/~erowland/fibonacci.html)
* [http://jsfromhell.com/classes/bignumber](http://jsfromhell.com/classes/bignumber)
* [http://www.math.rutgers.edu/~erowland/fibonacci](http://www.math.rutgers.edu/~erowland/fibonacci.html)
* [http://bigintegers.blogspot.com/2010/11/square-division-power-square-root](http://bigintegers.blogspot.com/2010/11/square-division-power-square-root.html)
* [http://bugs.python.org/issue3451](http://bugs.python.org/issue3451)

This code is in gist form here:
[https://gist.github.com/1032685](https://gist.github.com/1032685)

{% highlight coffeescript %}
###
Author: Jason Giedymin <jasong _a_t_ apache -dot- org>
        http://www.jasongiedymin.com
        https://github.com/JasonGiedymin

This CoffeeScript Javascript Fast Fibonacci code is
based on the python code from Robin Houston's blog.
See below links.

A few things I want to introduce in time are implementations of
Newtonian, Burnikel / Ziegler, and Binet's algorithms on top
of a Big Number framework.

Todo:
- https://github.com/substack/node-bigint
- BZ and Newton mods.
- Timing

###

MAXIMUM_JS_FIB_N = 1476

fib_bits = (n) ->
	#Represent an integer as an array of binary digits.

	bits = []
	while n > 0
    	[n, bit] = divmodBasic n, 2
    	bits.push bit

  	bits.reverse()
  	return bits

fibFast = (n) ->
	#Fast Fibonacci

	if n < 0
		console.log "Choose an number >= 0"
		return

	[a, b, c] = [1, 0, 1]

	for bit in fib_bits n
	    if bit
	    	[a, b] = [(a+c)*b, b*b + c*c]
	    else
	    	[a, b] = [a*a + b*b, (a+c)*b]

	    c = a + b
	  	return b

divmodNewton = (x, y) ->
	throw new Error "Method not yet implemented yet."

divmodBZ = () ->
	throw new Error "Method not yet implemented yet."

divmodBasic = (x, y) ->
	###
	Absolutely nothing special here. Maybe later versions will be Newtonian or
	Burnikel / Ziegler _if_ possible...
	###

	return [(q = Math.floor x/y), (r = if x < y then x else x % y)]

start = (new Date).getTime();
calc_value = fibFast(MAXIMUM_JS_FIB_N)
diff = (new Date).getTime() - start;
console.log "[#{calc_value}] took #{diff} ms."
{% endhighlight %}

## Discussion

Questions?


================================================
FILE: chapters/math/fast-inv-square.md
================================================
---
layout: recipe
title: Fast Inverse Square Root
chapter: Math
---
## Problem

You would like to calculate a the inverse square root of a number [quickly][5].

## Solution
Appearing in the Quake III Arena [source code][1], this strange algorithm uses
integer operations along with a 'magic number' to calculate floating point
approximation values of inverse square roots.

In this CoffeeScript variant I supply the original classic, and newer optimal
32 bit magic numbers found by [Chris Lomont][2]. Also supplied is the 64-bit
sized magic number.

Another feature included is the ability to alter the level of precision.
This is done by controlling the number of iterations for performing [Newton's
method][3].

Depending on the machine and level of precision this algorithm may still
provide performance increases over the classic.

To run this, compile the script with coffee:
    coffee -c script.coffee

Then copy & paste the compiled js code in to the JavaScript console of your
browser.

Note: You will need a browser which supports [typed-arrays][4].

References:
1. [ftp://ftp.idsoftware.com/idstuff/source/quake3-1.32b-source.zip](ftp://ftp.idsoftware.com/idstuff/source/quake3-1.32b-source.zip)
2. [http://www.lomont.org/Math/Papers/2003/InvSqrt.pdf](http://www.lomont.org/Math/Papers/2003/InvSqrt.pdf)
3. [http://en.wikipedia.org/wiki/Newton%27s_method](http://en.wikipedia.org/wiki/Newton%27s_method)
4. [https://developer.mozilla.org/en/JavaScript_typed_arrays](https://developer.mozilla.org/en/JavaScript_typed_arrays)
5. [http://en.wikipedia.org/wiki/Fast_inverse_square_root](http://en.wikipedia.org/wiki/Fast_inverse_square_root)

[1]: ftp://ftp.idsoftware.com/idstuff/source/quake3-1.32b-source.zip "ftp://ftp.idsoftware.com/idstuff/source/quake3-1.32b-source.zip"
[2]: http://www.lomont.org/Math/Papers/2003/InvSqrt.pdf "http://www.lomont.org/Math/Papers/2003/InvSqrt.pdf"
[3]: http://en.wikipedia.org/wiki/Newton%27s_method "http://en.wikipedia.org/wiki/Newton%27s_method"
[4]: https://developer.mozilla.org/en/JavaScript_typed_arrays "https://developer.mozilla.org/en/JavaScript_typed_arrays"
[5]: http://en.wikipedia.org/wiki/Fast_inverse_square_root "http://en.wikipedia.org/wiki/Fast_inverse_square_root"

This code is in gist form here:
[https://gist.github.com/1036533](https://gist.github.com/1036533)

{% highlight coffeescript %}
###

Author: Jason Giedymin <jasong _a_t_ apache -dot- org>
        http://www.jasongiedymin.com
        https://github.com/JasonGiedymin

Appearing in the Quake III Arena source code[1], this strange algorithm uses
integer operations along with a 'magic number' to calculate floating point
approximation values of inverse square roots[5].

In this CoffeeScript variant I supply the original classic, and newer optimal
32 bit magic numbers found by Chris Lomont[2]. Also supplied is the 64-bit
sized magic number.

Another feature included is the ability to alter the level of precision.
This is done by controlling the number of iterations for performing Newton's
method[3].

Depending on the machine and level of precision this algorithm may still
provide performance increases over the classic.

To run this, compile the script with coffee:
    coffee -c <this script>.coffee

Then copy & paste the compiled js code in to the JavaScript console of your
browser.

Note: You will need a browser which supports typed-arrays[4].

References: 
[1] ftp://ftp.idsoftware.com/idstuff/source/quake3-1.32b-source.zip
[2] http://www.lomont.org/Math/Papers/2003/InvSqrt.pdf
[3] http://en.wikipedia.org/wiki/Newton%27s_method
[4] https://developer.mozilla.org/en/JavaScript_typed_arrays
[5] http://en.wikipedia.org/wiki/Fast_inverse_square_root

###

approx_const_quake_32 = 0x5f3759df # See [1]
approx_const_32 = 0x5f375a86 # See [2]
approx_const_64 = 0x5fe6eb50c7aa19f9 # See [2]

fastInvSqrt_typed = (n, precision=1) ->
	# Using typed arrays. Right now only works in browsers.
	# Node.JS version coming soon.

    y = new Float32Array(1)
    i = new Int32Array(y.buffer)

    y[0] = n
    i[0] = 0x5f375a86 - (i[0] >> 1)
    
    for iter in [1...precision]
        y[0] = y[0] * (1.5 - ((n * 0.5) * y[0] * y[0]))
    
    return y[0]

### Sample single runs ###
testSingle = () ->
    example_n = 10

    console.log("Fast InvSqrt of 10, precision 1: #{fastInvSqrt_typed(example_n)}")
    console.log("Fast InvSqrt of 10, precision 5: #{fastInvSqrt_typed(example_n, 5)}")
    console.log("Fast InvSqrt of 10, precision 10: #{fastInvSqrt_typed(example_n, 10)}")
    console.log("Fast InvSqrt of 10, precision 20: #{fastInvSqrt_typed(example_n, 20)}")
    console.log("Classic of 10: #{1.0 / Math.sqrt(example_n)}")

testSingle()

{% endhighlight %}

## Discussion

Questions?


================================================
FILE: chapters/math/generating-predictable-random-numbers.md
================================================
---
layout: recipe
title: Generating Predictable Random Numbers
chapter: Math
---
## Problem

You need to generate a random number in a certain range, but you also need to be able to "seed" the generator to deliver predictable values.

## Solution

Write your own random number generator. There are a LOT of ways to do this. Here's a simple one. _This generator is +ABSOLUTELY NOT+ acceptable for cryptographic purposes!_

{% highlight coffeescript %}
class Rand
  # if created without a seed, uses current time as seed
  constructor: (@seed) ->
    # Knuth and Lewis' improvements to Park and Miller's LCPRNG
    @multiplier = 1664525
    @modulo = 4294967296 # 2**32-1;
    @offset = 1013904223
    unless @seed? && 0 <= seed < @modulo
      @seed = (new Date().valueOf() * new Date().getMilliseconds()) % @modulo

  # sets new seed value
  seed: (seed) ->
    @seed = seed

  # return a random integer 0 <= n < @modulo
  randn: ->
    # new_seed = (a * seed + c) % m
    @seed = (@multiplier*@seed + @offset) % @modulo

 # return a random float 0 <= f < 1.0
  randf: ->
    this.randn() / @modulo

  # return a random int 0 <= f < n
  rand: (n) ->
    Math.floor(this.randf() * n)

  # return a random int min <= f < max
  rand2: (min, max) ->
    min + this.rand(max-min)
{% endhighlight %}

## Discussion

JavaScript and CoffeeScript do not provide a seedable random number generator. Writing your own will be an exercise in trading off the amount of randomness with the simplicity of the generator. A full discussion of randomness is beyond the scope of this cookbook; for further reading consult Donald Knuth's _The Art of Computer Programming_, Volume II, Chapter 3, "Random Numbers", and _Numerical Recipes in C_, 2nd Edition, Chapter 7, "Random Numbers".

A brief explanation of this random number generator is in order, however. It is a Linear Congruential Pseudorandom Number Generator. LCPRNG's operate on the mathematical formula `I<sub>j+1</sub> = (aI<sub>j</sub>+c) % m`, where a is the multiplier, c is the addition offset, and m is the modulus.
 Each time a random number is requested, a very large multiplication and addition are performed -- "very large" relative to the key space -- and the resulting number is modulused back down into the keyspace.

This generator has a period of 2<sup>32</sup>. It is absolutely unacceptable for cryptographic purposes, but for most simple randomness requirements it is quite adequate. `randn()` will traverse the entire keyspace before repeating itself, and the next number is determined by the previous one.

If you want to tinker with this generator, you are _strongly_ encouraged to read Chapter 3 of Knuth's _The Art of Computer Programming_. Random number generation is VERY easy to screw up, and Knuth explains how to tell a good RNG from a bad one.

Avoid the temptation to modulus the output of this generator. If you need an integer range, use division. Linear Congruential generators are very nonrandom in their lower bits. This one in particular always generates an odd number from an even seed, and vice versa. So if you need a random 0 or 1, do NOT use

{% highlight coffeescript %}
# NOT random! Do not do this!
r.randn() % 2
{% endhighlight %}

because you will most definitely not get random digits. Use `r.rand(2)` instead.


================================================
FILE: chapters/math/generating-random-numbers.md
================================================
---
layout: recipe
title: Generating Random Numbers
chapter: Math
---
## Problem

You need to generate a random number in a certain range.

## Solution

Use JavaScript's Math.random() to get floating-point numbers from 0 <= x < 1.0. Use multiplication and Math.floor to get a number in a certain range.

{% highlight coffeescript %}
probability = Math.random()
0.0 <= probability < 1.0
# => true

# Note that percentile does NOT ever reach 100. A full range of 0 to 100 is actually a span of 101.
percentile = Math.floor(Math.random() * 100)
0 <= percentile < 100
# => true

dice = Math.floor(Math.random() * 6) + 1
1 <= dice <= 6
# => true

max = 42
min = -13
range = Math.random() * (max - min) + min
-13 <= range < 42
# => true
{% endhighlight %}

## Discussion

This is a straight lift from JavaScript.

Note that JavaScript's Math.random() does not allow you to seed the random number generator to force certain values. See [Generating Predictable Random Numbers]({{ site.baseurl }}/chapters/math/generating-predictable-random-numbers) for that.

To generate a number from 0 up to (but not including) n, multiply by n. To generate a number from 1 to n (inclusive), multiply by n and add 1.


================================================
FILE: chapters/math/index.html
================================================
---
layout: chapter
title: Math
chapter: Math
---

{% capture url %}/chapters/{{ page.chapter | replace: ' ', '_' | downcase }}{% endcapture %}
{% capture indexurl %}{{ url }}/index.html{% endcapture %}

<ul>
{% for page in site.pages %}
  {% if page.url contains url %}
    {% unless page.url == indexurl %}
  <li><a href="{{ site.baseurl }}{{ page.url | replace: '.html', '' }}">{{ page.title }}</a></li>
    {% endunless %}
  {% endif %}
{% endfor %}
</ul>


================================================
FILE: chapters/math/radians-degrees.md
================================================
---
layout: recipe
title: Converting Radians and Degrees
chapter: Math
---
## Problem

You need to convert between radians and degrees.

## Solution

Use Javascript's Math.PI and a simple formula to convert between the two.

{% highlight coffeescript %}
# To convert from radians to degrees
radiansToDegrees = (radians) ->
    degrees = radians * 180 / Math.PI

radiansToDegrees(1)
# => 57.29577951308232

# To convert from degrees to radians
degreesToRadians = (degrees) ->
    radians = degrees * Math.PI / 180

degreesToRadians(1)
# => 0.017453292519943295
{% endhighlight %}

## Discussion

Questions?


================================================
FILE: chapters/math/random-integer.md
================================================
---
layout: recipe
title: A Random Integer Function
chapter: Math
---
## Problem

You'd like to get a random integer between two integers, inclusive.

## Solution

Use the following function.

{% highlight coffeescript %}
randomInt = (lower, upper) ->
  [lower, upper] = [0, lower]     unless upper?           # Called with one argument
  [lower, upper] = [upper, lower] if lower > upper        # Lower must be less then upper
  Math.floor(Math.random() * (upper - lower + 1) + lower) # Last statement is a return value

(randomInt(1) for i in [0...10])
# => [0,1,1,0,0,0,1,1,1,0]

(randomInt(1, 10) for i in [0...10])
# => [7,3,9,1,8,5,4,10,10,8]
{% endhighlight %}

## Discussion

Questions?


================================================
FILE: chapters/math/working-with-exponents-and-logarithms.md
================================================
---
layout: recipe
title: Working with Exponents and Logarithms
chapter: Math
---
## Problem

You need to do some calculations that involve exponents and logarithms.

## Solution

Use Javascript's Math object to provide common mathematical functions.

{% highlight coffeescript %}
# Math.pow(x, y) returns x^y
Math.pow(2, 4)
# => 16

# Math.exp(x) returns E^x and is shorthand for Math.pow(Math.E, x)
Math.exp(2)
# => 7.38905609893065

# Math.log returns the natural (base E) log
Math.log(5)
# => 1.6094379124341003
Math.log(Math.exp(42))
# => 42

# To get a log with some other base n, divide by Math.log(n)
Math.log(100) / Math.log(10)
# => 2

{% endhighlight %}

## Discussion

For more information on the Math object see the documentation on the [Mozilla Developer Network](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math). Also refer to [Math Constants]({{ site.baseurl }}/chapters/math/constants) for discussion of the various constants in the Math object.


================================================
FILE: chapters/metaprogramming/detecting-and-replacing-functions.md
================================================
---
layout: recipe
title: Detecting and Creating Missing Functions
chapter: Metaprogramming
---
## Problem

You want to detect if a function exists and create it if it does not (such as an ECMAScript 5 function in Internet Explorer 8).

## Solution

Use the existential assignment operator (`?=`) to assign a function to the classes' prototype (using the `::` shorthand), and wrap it all in a IIFE (`do ->`) to contain the variables.

{% highlight coffeescript %}
do -> Array::filter ?= (callback) ->
  element for element in this when callback element

array = [1..10]

array.filter (x) -> x > 5
# => [6,7,8,9,10]
{% endhighlight %}

## Discussion

Objects in JavaScript (and thus, in CoffeeScript) have a prototype member that defines what member functions should be available on all objects based on that prototype.  
In Coffeescript, you access this prototype using the `::` shortcut. So, if you want to add a filter function to the array class, you do `Array::filter = ...`. This will add the filter function to all arrays.

However, we don't ever want to overwrite a prototype that we haven't created in the first place. For example, if `Array::filter` already exists in a fast native form in the browser, or a library maker has their own specific version of `Array::filter`, then you'll either replace the quick native version with a slow Javascript version, or you will break the library that depends on their own Array::shuffle.  
What you need to do is only add the function if it doesn't already exist. That's where the existential assignment operator (`?=`) comes in. If we do `Array::filter ?= ...` instead, it will see if `Array::filter` already exists. If it does, then it will use the current version. If it doesn't, it will add yours.

Finally, because the existential assignment operator--when compiled--creates a few variables, we clean up the code by wrapping it in an [Immediately-Invoked Function Expression (IIFE)](http://benalman.com/news/2010/11/immediately-invoked-function-expression/). This hides those internal-use-only variables from leaking outside. So, if the function we're writing already exists, it runs, does basically nothing, and exits, affecting absolutely none of your code. But, if the function we're writing *doesn't* exist, we send out only the function we're writing as a closure, so only the function you've made affects the code. The internal workings of `?=` are hidden either way.

### Example

Below, we've compiled and annotated the coffeescript written in the solution above

{% highlight javascript %}
// (function(){ ... })() is an IIFE, compiled in thanks to `do ->`
(function() {

  // This is from the `?=` operator, used to check if Array.prototype.filter (`Array::filter`) exists.
  // If it does, we set it to itself, and return. If it doesn't, then we set it to the function, and return the function.
  // The IIFE is only used to hide _base and _ref from the outside world.
  var _base, _ref;
  return (_ref = (_base = Array.prototype).filter) != null ? _ref : _base.filter = function(callback) {

    // `element for element in this when callback element`
    var element, _i, _len, _results;
    _results = [];
    for (_i = 0, _len = this.length; _i < _len; _i++) {
      element = this[_i];
      if (callback(element)) {
        _results.push(element);
      }
    }
    return _results;
    
  };
// The end of the IIFE from `do ->`
})();
{% endhighlight %}


================================================
FILE: chapters/metaprogramming/extending-built-in-objects.md
================================================
---
layout: recipe
title: Extending Built-in Objects
chapter: Metaprogramming
---
## Problem

You want to extend a class to add new functionality or replace old.

## Solution

Use `::` to assign your new function to the prototype of the object or class.

{% highlight coffeescript %}
String::capitalize = () ->
  (this.split(/\s+/).map (word) -> word[0].toUpperCase() + word[1..-1].toLowerCase()).join ' '

"foo bar     baz".capitalize()
# => 'Foo Bar Baz'
{% endhighlight %}

## Discussion

Objects in JavaScript (and thus, in CoffeeScript) have a prototype member that defines what member functions should be available on all objects based on that prototype. In CoffeeScript, you can access the prototype directly via the `::` operator.

**Note:** Although it's quite common in languages like Ruby, extending native objects is often considered bad practice in JavaScript (see: [Maintainable JavaScript: Don’t modify objects you don’t own](http://www.nczonline.net/blog/2010/03/02/maintainable-javascript-dont-modify-objects-you-down-own/); [Extending built-in native objects. Evil or not?](http://perfectionkills.com/extending-native-builtins/)).


================================================
FILE: chapters/metaprogramming/index.html
================================================
---
layout: chapter
title: Metaprogramming
chapter: Metaprogramming
---

{% capture url %}/chapters/{{ page.chapter | replace: ' ', '_' | downcase }}{% endcapture %}
{% capture indexurl %}{{ url }}/index.html{% endcapture %}

<ul>
{% for page in site.pages %}
  {% if page.url contains url %}
    {% unless page.url == indexurl %}
  <li><a href="{{ site.baseurl }}{{ page.url | replace: '.html', '' }}">{{ page.title }}</a></li>
    {% endunless %}
  {% endif %}
{% endfor %}
</ul>


================================================
FILE: chapters/networking/basic-client.md
================================================
---
layout: recipe
title: Basic Client
chapter: Networking
---
## Problem

You want to access a service provided over the network.

## Solution

Create a basic TCP client.

### In Node.js

{% highlight coffeescript %}
net = require 'net'

domain = 'localhost'
port = 9001

connection = net.createConnection port, domain

connection.on 'connect', () ->
	console.log "Opened connection to #{domain}:#{port}."

connection.on 'data', (data) ->
	console.log "Received: #{data}"
	connection.end()
{% endhighlight %}

### Example Usage

Accessing the [Basic Server]({{ site.baseurl }}/chapters/networking/basic-server):

{% highlight console %}
$ coffee basic-client.coffee
Opened connection to localhost:9001
Received: Hello, World!
{% endhighlight %}

## Discussion

The most important work takes place in the _connection.on 'data'_ handler, where the client receives its response from the server and would most likely arrange for responses to it.

See also the [Basic Server]({{ site.baseurl }}/chapters/networking/basic-server), [Bi-Directional Client]({{ site.baseurl }}/chapters/networking/bi-directional-client), and [Bi-Directional Server]({{ site.baseurl }}/chapters/networking/bi-directional-server) recipes.

### Exercises

* Add support for choosing the target domain and port based on command-line arguments or from a configuration file.


================================================
FILE: chapters/networking/basic-http-client.md
================================================
---
layout: recipe
title: Basic HTTP Client
chapter: Networking
---

## Problem

You want to create a HTTP client.

## Solution

In this recipe, we'll use [node.js](http://nodejs.org/)'s HTTP library. We'll go from a simple GET request example to a client which returns the external IP of a computer.

### GET something

{% highlight coffeescript %}
http = require 'http'

http.get { host: 'www.google.com' }, (res) ->
    console.log res.statusCode
{% endhighlight %}

The `get` function, from node.js's `http` module, issues a GET request to a HTTP server. The response comes in the form of a callback, which we can handle in a function. This example merely prints the response status code. Check it out:

{% highlight console %}
$ coffee http-client.coffee 
200

{% endhighlight %}

### What's my IP?

If you are inside a network which relies on [NAT](http://en.wikipedia.org/wiki/Network_address_translation) such as a LAN, you probably have faced the issue of finding out what's your external IP address. Let's write a small coffeescript for this.

{% highlight coffeescript %}
http = require 'http'

http.get { host: 'checkip.dyndns.org' }, (res) ->
    data = ''
    res.on 'data', (chunk) ->
        data += chunk.toString()
    res.on 'end', () ->
        console.log data.match(/([0-9]+\.){3}[0-9]+/)[0]
{% endhighlight %}

We can get the data from the result object by listening on its `'data'` event; and know that it has come to an end once the `'end'` event has been fired. When that happens, we can do a simple regular expression match to extract our IP address. Try it:

{% highlight console %}
$ coffee http-client.coffee 
123.123.123.123
{% endhighlight %}

## Discussion

Note that `http.get` is a shortcut of `http.request`. The latter allows you to issue HTTP requests with different methods, such as POST or PUT.

For API and overall information on this subject, check node.js's [http](http://nodejs.org/docs/latest/api/http.html) and [https](http://nodejs.org/docs/latest/api/https.html) documentation pages. Also, the [HTTP spec](http://www.ietf.org/rfc/rfc2616.txt) might come in handy.

### Exercises

* Create a client for the key-value store HTTP server, from the [Basic HTTP Server](basic-http-server) recipe.



================================================
FILE: chapters/networking/basic-http-server.md
================================================
---
layout: recipe
title: Basic HTTP Server
chapter: Networking
---

## Problem

You want to create a HTTP server over a network. Over the course of this recipe, we'll go step by step from the smallest server possible to a functional key-value store.

## Solution

We'll use [node.js](http://nodejs.org/)'s HTTP library to our own selfish purposes and create the simplest web server possible in Coffeescript.

### Say 'hi\n'

We can start by importing node.js's HTTP module. This contains `createServer` which, given a simple request handler, returns a HTTP server. We can use that server to listen on a TCP port.

{% highlight coffeescript %}
http = require 'http'
server = http.createServer (req, res) -> res.end 'hi\n'
server.listen 8000
{% endhighlight %}

To run this example, simply put in a file and run it. You can kill it with `Ctrl-C`. We can test it using the `curl` command, available on most \*nix platforms:

{% highlight console %}
$ curl -D - http://localhost:8000/
HTTP/1.1 200 OK
Connection: keep-alive
Transfer-Encoding: chunked

hi
{% endhighlight %}

### What's going on? 

Let's get a little bit more feedback on what's happening on our server. While we're at it, we could also be friendlier to our clients and provide them some HTTP headers.

{% highlight coffeescript %}
http = require 'http'

server = http.createServer (req, res) ->
    console.log req.method, req.url
    data = 'hi\n'
    res.writeHead 200,
        'Content-Type':     'text/plain'
        'Content-Length':   data.length
    res.end data

server.listen 8000
{% endhighlight %}

Try to access it once again, but this time use different URL paths, such as `http://localhost:8000/coffee`. You'll see something like this on the server console:

{% highlight console %}
$ coffee http-server.coffee 
GET /
GET /coffee
GET /user/1337
{% endhighlight %}

### GETting stuff

What if our webserver was able to hold some data? We'll try to come up with a simple key-value store in which elements are retrievable via GET requests. Provide a key on the request path and the server will return the corresponding value &mdash; or 404 if it doesn't exist.

{% highlight coffeescript %}
http = require 'http'

store = # we'll use a simple object as our store
    foo:    'bar'
    coffee: 'script'

server = http.createServer (req, res) ->
    console.log req.method, req.url
    
    value = store[req.url[1..]]

    if not value
        res.writeHead 404
    else
        res.writeHead 200,
            'Content-Type': 'text/plain'
            'Content-Length': value.length + 1
        res.write value + '\n'
    
    res.end()

server.listen 8000
{% endhighlight %}

We can try several URLs to see how it responds:

{% highlight console %}
$ curl -D - http://localhost:8000/coffee
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 7
Connection: keep-alive

script

$ curl -D - http://localhost:8000/oops
HTTP/1.1 404 Not Found
Connection: keep-alive
Transfer-Encoding: chunked

{% endhighlight %}

### Use your head(ers)

Let's face it, `text/plain` is kind of lame. How about if we use something hip like `application/json` or `text/xml`? Also, our store retrieval process could use a bit of refactoring &mdash; how about some exception throwing &amp; handling? Let's see what we can come up with:

{% highlight coffeescript %}
http = require 'http'

# known mime types
[any, json, xml] = ['*/*', 'application/json', 'text/xml']

# gets a value from the db in format [value, contentType]
get = (store, key, format) ->
    value = store[key]
    throw 'Unknown key' if not value
    switch format
        when any, json then [JSON.stringify({ key: key, value: value }), json]
        when xml then ["<key>#{ key }</key>\n<value>#{ value }</value>", xml]
        else throw 'Unknown format'

store =
    foo:    'bar'
    coffee: 'script'

server = http.createServer (req, res) ->
    console.log req.method, req.url
    
    try
        key = req.url[1..]
        [value, contentType] = get store, key, req.headers.accept
        code = 200
    catch error
        contentType = 'text/plain'
        value = error
        code = 404
 
    res.writeHead code,
        'Content-Type': contentType
        'Content-Length': value.length + 1
    res.write value + '\n'
    res.end()

server.listen 8000
{% endhighlight %}

This server will still return the value which matches a given key, or 404 if non-existent. But it will structure the response either in JSON or XML, according to the `Accept` header. See for yourself:

{% highlight console %}
$ curl http://localhost:8000/
Unknown key

$ curl http://localhost:8000/coffee
{"key":"coffee","value":"script"}

$ curl -H "Accept: text/xml" http://localhost:8000/coffee
<key>coffee</key>
<value>script</value>

$ curl -H "Accept: image/png" http://localhost:8000/coffee
Unknown format
{% endhighlight %}

### You gotta give to get back

The obvious last step in our adventure is to provide the client the ability to store data. We'll keep our RESTiness by listening to POST requests for this purpose.

{% highlight coffeescript %}
http = require 'http'

# known mime types
[any, json, xml] = ['*/*', 'application/json', 'text/xml']

# gets a value from the db in format [value, contentType]
get = (store, key, format) ->
    value = store[key]
    throw 'Unknown key' if not value
    switch format
        when any, json then [JSON.stringify({ key: key, value: value }), json]
        when xml then ["<key>#{ key }</key>\n<value>#{ value }</value>", xml]
        else throw 'Unknown format'

# puts a value in the db
put = (store, key, value) ->
    throw 'Invalid key' if not key or key is ''
    store[key] = value

store =
    foo:    'bar'
    coffee: 'script'

# helper function that responds to the client
respond = (res, code, contentType, data) ->
    res.writeHead code,
        'Content-Type': contentType
        'Content-Length': data.length
    res.write data
    res.end()

server = http.createServer (req, res) ->
    console.log req.method, req.url
    key = req.url[1..]
    contentType = 'text/plain'
    code = 404
    
    switch req.method
        when 'GET'
            try
                [value, contentType] = get store, key, req.headers.accept
                code = 200
            catch error
                value = error
            respond res, code, contentType, value + '\n'

        when 'POST'
            value = ''
            req.on 'data', (chunk) -> value += chunk
            req.on 'end', () ->
                try
                    put store, key, value
                    value = ''
                    code = 200
                catch error
                    value = error + '\n'
                respond res, code, contentType, value

server.listen 8000
{% endhighlight %}

Notice how the data is received in a POST request. By attaching some handlers on the `'data'` and `'end'` events of the request object, we're able to buffer and finally save the data from the client in the `store`.

{% highlight console %}
$ curl -D - http://localhost:8000/cookie
HTTP/1.1 404 Not Found # ...
Unknown key

$ curl -D - -d "monster" http://localhost:8000/cookie
HTTP/1.1 200 OK # ...

$ curl -D - http://localhost:8000/cookie
HTTP/1.1 200 OK # ...
{"key":"cookie","value":"monster"}
{% endhighlight %}

## Discussion

Give `http.createServer` a function in the shape of `(request, response) -> ...` and it will return a server object, which we can use to listen on a port. Interact with the `request` and `response` objects to give the server its behaviour. Listen on port 8000 using `server.listen 8000`.

For API and overall information on this subject, check node.js's [http](http://nodejs.org/docs/latest/api/http.html) and [https](http://nodejs.org/docs/latest/api/https.html) documentation pages. Also, the [HTTP spec](http://www.ietf.org/rfc/rfc2616.txt) might come in handy.

### Exercises

* Create a layer in between the server and the developer which would allow the developer to do something like:

{% highlight coffeescript %}
server = layer.createServer
    'GET /': (req, res) ->
        ...
    'GET /page': (req, res) ->
        ...
    'PUT /image': (req, res) ->
        ...
{% endhighlight %}



================================================
FILE: chapters/networking/basic-server.md
================================================
---
layout: recipe
title: Basic Server
chapter: Networking
---
## Problem

You want to provide a service over a network.

## Solution

Create a basic TCP server.

### In Node.js

{% highlight coffeescript %}
net = require 'net'

domain = 'localhost'
port = 9001

server = net.createServer (socket) ->
	console.log "Received connection from #{socket.remoteAddress}"
	socket.write "Hello, World!\n"
	socket.end()

console.log "Listening to #{domain}:#{port}"
server.listen port, domain
{% endhighlight %}

### Example Usage

Accessed by the [Basic Client]({{ site.baseurl }}/chapters/networking/basic-client):

{% highlight console %}
$ coffee basic-server.coffee
Listening to localhost:9001
Received connection from 127.0.0.1
Received connection from 127.0.0.1
[...]
{% endhighlight %}

## Discussion

The function passed to @net.createServer@ receives the new socket provided for each new connection to a client.  This basic server simply socializes with its visitors but a hard-working server would pass this socket along to a dedicated handler and then return to the task of waiting for the next client.

See also the [Basic Client]({{ site.baseurl }}/chapters/networking/basic-client), [Bi-Directional Server]({{ site.baseurl }}/chapters/networking/bi-directional-server), and [Bi-Directional Client]({{ site.baseurl }}/chapters/networking/bi-directional-client) recipes.

### Exercises

* Add support for choosing the target domain and port based on command-line arguments or from a configuration file.


================================================
FILE: chapters/networking/bi-directional-client.md
================================================
---
layout: recipe
title: Bi-Directional Client
chapter: Networking
---
## Problem

You want to a persistent service over a network, one which maintains an on-going connection with its clients.

## Solution

Create a bi-directional TCP client.

### In Node.js

{% highlight coffeescript %}
net = require 'net'

domain = 'localhost'
port = 9001

ping = (socket, delay) ->
	console.log "Pinging server"
	socket.write "Ping"
	nextPing = -> ping(socket, delay)
	setTimeout nextPing, delay

connection = net.createConnection port, domain

connection.on 'connect', () ->
	console.log "Opened connection to #{domain}:#{port}"
	ping connection, 2000

connection.on 'data', (data) ->
	console.log "Received: #{data}"

connection.on 'end', (data) ->
	console.log "Connection closed"
	process.exit()
{% endhighlight %}

### Example Usage

Accessing the [Bi-Directional Server]({{ site.baseurl }}/chapters/networking/bi-directional-server):

{% highlight console %}
$ coffee bi-directional-client.coffee
Opened connection to localhost:9001
Pinging server
Received: You have 0 peers on this server
Pinging server
Received: You have 0 peers on this server
Pinging server
Received: You have 1 peer on this server
[...]
Connection closed
{% endhighlight %}

## Discussion

This particular example initiates contact with the server and starts the conversation in the @connection.on 'connect'@ handler.  The bulk of the work in a real client, however, will lie in the @connection.on 'data'@ handler, which processes output from the server.  The @ping@  function only recurses in order to illustrate continuous communication with the server and can be removed from a real client.

See also the [Bi-Directional Server]({{ site.baseurl }}/chapters/networking/bi-directional-server), [Basic Client]({{ site.baseurl }}/chapters/networking/basic-client), and [Basic Server]({{ site.baseurl }}/chapters/networking/basic-server) recipes.

### Exercises

* Add support for choosing the target domain and port based on command-line arguments or from a configuration file.


================================================
FILE: chapters/networking/bi-directional-server.md
================================================
---
layout: recipe
title: Bi-Directional Server
chapter: Networking
---
## Problem

You want to provide a persistent service over a network, one which maintains an on-going connection with a client.

## Solution

Create a bi-directional TCP server.

### In Node.js

{% highlight coffeescript %}
net = require 'net'

domain = 'localhost'
port = 9001

server = net.createServer (socket) ->
	console.log "New connection from #{socket.remoteAddress}"

	socket.on 'data', (data) ->
		console.log "#{socket.remoteAddress} sent: #{data}"
		others = server.connections - 1
		socket.write "You have #{others} #{others == 1 and "peer" or "peers"} on this server"

console.log "Listening to #{domain}:#{port}"
server.listen port, domain
{% endhighlight %}

### Example Usage

Accessed by the [Bi-Directional Client]({{ site.baseurl }}/chapters/networking/bi-directional-client):

{% highlight console %}
$ coffee bi-directional-server.coffee
Listening to localhost:9001
New connection from 127.0.0.1
127.0.0.1 sent: Ping
127.0.0.1 sent: Ping
127.0.0.1 sent: Ping
[...]
{% endhighlight %}

## Discussion

The bulk of the work lies in the @socket.on 'data'@ handler, which processes all of the input from the client.  A real server would likely pass the data onto another function to process it and generate any responses so that the original handler.

See also the [Bi-Directional Client]({{ site.baseurl }}/chapters/networking/bi-directional-client), [Basic Client]({{ site.baseurl }}/chapters/networking/basic-client), and [Basic Server]({{ site.baseurl }}/chapters/networking/basic-server) recipes.

### Exercises

* Add support for choosing the target domain and port based on command-line arguments or on a configuration file.


================================================
FILE: chapters/networking/index.html
================================================
---
layout: chapter
title: Networking
chapter: Networking
---

{% capture url %}/chapters/{{ page.chapter | replace: ' ', '_' | downcase }}{% endcapture %}
{% capture indexurl %}{{ url }}/index.html{% endcapture %}

<ul>
{% for page in site.pages %}
  {% if page.url contains url %}
    {% unless page.url == indexurl %}
  <li><a href="{{ site.baseurl }}{{ page.url | replace: '.html', '' }}">{{ page.title }}</a></li>
    {% endunless %}
  {% endif %}
{% endfor %}
</ul>


================================================
FILE: chapters/regular_expressions/heregexes.md
================================================
---
layout: recipe
title: Using Heregexes
chapter: Regular Expressions
---
## Problem

You need to write a complex regular expression.

## Solution

Use Coffeescript's "heregexes" -- extended regular expressions that ignore internal whitespace and can contain comments.

{% highlight coffeescript %}
pattern = ///
  ^\(?(\d{3})\)? # Capture area code, ignore optional parens
  [-\s]?(\d{3})  # Capture prefix, ignore optional dash or space
  -?(\d{4})      # Capture line-number, ignore optional dash
///
[area_code, prefix, line] = "(555)123-4567".match(pattern)[1..3]
# => ['555', '123', '4567']
{% endhighlight %}

## Discussion

Breaking up your complex regular expressions and commenting key sections makes them a lot more decipherable and maintainable. For example, changing this regex to allow an optional space between the prefix and line number would now be fairly obvious.

### Whitespace characters in heregexes

Whitespace is ignored in heregexes -- so what do you do if you need to match a literal ASCII space?

One solution is to use the @\s@ character class, which will match spaces, tabs
and line breaks. If you only want to match a space, though, you'll need to use
`\x20` to denote a literal ASCII space.


================================================
FILE: chapters/regular_expressions/index.html
================================================
---
layout: chapter
title: Regular Expressions
chapter: Regular Expressions
---

{% capture url %}/chapters/{{ page.chapter | replace: ' ', '_' | downcase }}{% endcapture %}
{% capture indexurl %}{{ url }}/index.html{% endcapture %}

<ul>
{% for page in site.pages %}
  {% if page.url contains url %}
    {% unless page.url == indexurl %}
  <li><a href="{{ site.baseurl }}{{ page.url | replace: '.html', '' }}">{{ page.title }}</a></li>
    {% endunless %}
  {% endif %}
{% endfor %}
</ul>


================================================
FILE: chapters/regular_expressions/replacing-html-tags-with-html-named-entities.md
================================================
---
layout: recipe
title: Replacing HTML Tags with HTML Named Entities
chapter: Regular Expressions
---
## Problem

You need to replace HTML tags with named entities:

`<br/> => &lt;br/&gt;`

## Solution

{% highlight coffeescript %}
htmlEncode = (str) ->
  str.replace /[&<>"']/g, ($0) ->
    "&" + {"&":"amp", "<":"lt", ">":"gt", '"':"quot", "'":"#39"}[$0] + ";"

htmlEncode('<a href="http://bn.com">Barnes & Noble</a>')
# => '&lt;a href=&quot;http://bn.com&quot;&gt;Barnes &amp; Noble&lt;/a&gt;'
{% endhighlight %}

## Discussion

There are probably better ways to implement the above method.


================================================
FILE: chapters/regular_expressions/replacing-substrings.md
================================================
---
layout: recipe
title: Replacing Substrings
chapter: Regular Expressions
---
## Problem

You need to replace a portion of a string with another value.

## Solution

Use the JavaScript `replace` method. `replace` matches with the given string, and returns the edited string.

The first version takes 2 arguments: _pattern_ and _string replacement_

{% highlight coffeescript %}
"JavaScript is my favorite!".replace /Java/, "Coffee"
# => 'CoffeeScript is my favorite!'

"foo bar baz".replace /ba./, "foo"
# => 'foo foo baz'

"foo bar baz".replace /ba./g, "foo"
# => 'foo foo foo'
{% endhighlight %}

The second version takes 2 arguments: _pattern_ and _callback function_

{% highlight coffeescript %}
"CoffeeScript is my favorite!".replace /(\w+)/g, (match) ->
  match.toUpperCase()
# => 'COFFEESCRIPT IS MY FAVORITE!'
{% endhighlight %}

The callback function is invoked for each match, and the match value is passed as the argument to the callback.

## Discussion

Regular Expressions are a powerful way to match and replace strings.


================================================
FILE: chapters/regular_expressions/searching-for-substrings.md
================================================
---
layout: recipe
title: Searching for Substrings
chapter: Regular Expressions
---
## Problem

You need to search for a substring, and return either the starting position of the match or the matching value itself.

## Solution

There are several ways to accomplish this using regular expressions. Some methods are called on a `RegExp` pattern or object and some are called on `String` objects.

### `RegExp` objects

The first way is to call the `test` method on a `RegExp` pattern or object. The `test` method returns a boolean value:

{% highlight coffeescript %}
match = /sample/.test("Sample text")
# => false

match = /sample/i.test("Sample text")
# => true
{% endhighlight %}

The next way to is to call the `exec` method on a `RegExp` pattern or object. The `exec` method returns an array with the match information or `null`:

{% highlight coffeescript %}
match = /s(amp)le/i.exec "Sample text"
# => [ 'Sample', 'amp', index: 0, input: 'Sample text' ]

match = /s(amp)le/.exec "Sample text"
# => null
{% endhighlight %}

### `String` objects

The `match` method matches a given string with the `RegExp`. With 'g' flag returns an array containing the matches, without 'g' flag returns just the first match or if no match is found returns `null`.

{% highlight coffeescript %}
"Watch out for the rock!".match(/r?or?/g)
# => [ 'o', 'or', 'ro' ]

"Watch out for the rock!".match(/r?or?/)
# => [ 'o', index: 6, input: 'Watch out for the rock!' ]

"Watch out for the rock!".match(/ror/)
# => null
{% endhighlight %}

The `search` method matches `RegExp` with string and returns the index of the beginning of the match if found, -1 if not.

{% highlight coffeescript %}
"Watch out for the rock!".search /for/
# => 10

"Watch out for the rock!".search /rof/
# => -1
{% endhighlight %}

## Discussion

Regular Expressions are a powerful way to test and match substrings.


================================================
FILE: chapters/strings/capitalizing-words.md
================================================
---
layout: recipe
title: Capitalizing Words
chapter: Strings
---
## Problem

You want to capitalize the first letter of every word in a string.

## Solution

Use the split, map, join pattern: Split the string into words, then use a map to capitalize the first letter and lowercase all other letters of each word before gluing the string back together with join.

{% highlight coffeescript %}
("foo bar baz".split(' ').map (word) -> word[0].toUpperCase() + word[1..-1].toLowerCase()).join ' '
# => 'Foo Bar Baz'
{% endhighlight %}

Or do the same thing using a list comprehension:

{% highlight coffeescript %}
(word[0].toUpperCase() + word[1..-1].toLowerCase() for word in "foo   bar   baz".split /\s+/).join ' '
# => 'Foo Bar Baz'
{% endhighlight %}

## Discussion

Split, map, join is a common scripting pattern dating back to Perl. This function may benefit from being placed directly onto the String class by [Extending Classes]({{ site.baseurl }}/chapters/objects/extending-classes).

Be aware that two wrinkles can appear in the split, map, join pattern. The first is that the split text works best when it is constant. If the source string has multiple spaces in it, the split will need to take this into account to prevent getting extra, empty words. One way to do this is with a regular expression to split on runs of whitespace instead of a single space:

{% highlight coffeescript %}
("foo    bar    baz".split(/\s+/).map (word) -> word[0].toUpperCase() + word[1..-1].toLowerCase()).join ' '
# => 'Foo Bar Baz'
{% endhighlight %}

...but this leads us to the second wrinkle: notice that the runs of whitespace are now compressed down to a single character by the join.

Quite often one or both of these wrinkles is acceptable, however, so the split, map, join pattern can be a powerful tool.


================================================
FILE: chapters/strings/finding-substrings.md
================================================
---
layout: recipe
title: Finding Substrings
chapter: Strings
---
## Problem

You need to find the first or last occurrence of a search string within a message.

## Solution

Use Javascript's indexOf() and lastIndexOf() to find the first and last occurrences of a string, respectively.
Syntax: string.indexOf searchstring, start

{% highlight coffeescript %}
message = "This is a test string. This has a repeat or two. This might even have a third."
message.indexOf "This", 0
# => 0

# Modifying the start parameter
message.indexOf "This", 5
# => 23

message.lastIndexOf "This"
# => 49

# Count occurrences of a given string
message.split(" a ").length - 1
# => 3

{% endhighlight %}


================================================
FILE: chapters/strings/generating-a-unique-id.md
================================================
---
layout: recipe
title: Generating a Unique ID
chapter: Strings
---
## Problem

You want to generate a random unique identifier.

## Solution

You can create a Base 36 encoded string from a random number.

{% highlight coffeescript %}
uniqueId = (length=8) ->
  id = ""
  id += Math.random().toString(36).substr(2) while id.length < length
  id.substr 0, length

uniqueId()    # => n5yjla3b
uniqueId(2)   # => 0d
uniqueId(20)  # => ox9eo7rt3ej0pb9kqlke
uniqueId(40)  # => xu2vo4xjn4g0t3xr74zmndshrqlivn291d584alj
{% endhighlight %}

## Discussion

There are other possible techniques, but this is relatively performant and flexible.


================================================
FILE: chapters/strings/index.html
================================================
---
layout: chapter
title: Strings
chapter: Strings
---

{% capture url %}/chapters/{{ page.chapter | replace: ' ', '_' | downcase }}{% endcapture %}
{% capture indexurl %}{{ url }}/index.html{% endcapture %}

<ul>
{% for page in site.pages %}
  {% if page.url contains url %}
    {% unless page.url == indexurl %}
  <li><a href="{{ site.baseurl }}{{ page.url | replace: '.html', '' }}">{{ page.title }}</a></li>
    {% endunless %}
  {% endif %}
{% endfor %}
</ul>


================================================
FILE: chapters/strings/interpolation.md
================================================
---
layout:   recipe
title:    String Interpolation
chapter:  Strings
---
## Problem

You want to create a string that contains a text representation of a
CoffeeScript Variable.

## Solution

Use CoffeeScript's ruby-like string interpolation instead of
JavaScript's string addition. You must use Double-quoted strings to 
allow for interpolation. Single-quoted strings are treated as literals.

Interpolation:

{% highlight coffeescript %}
muppet = "Beeker"
favorite = "My favorite muppet is #{muppet}!"

# => "My favorite muppet is Beeker!"
{% endhighlight %}

{% highlight coffeescript %}
square = (x) -> x * x
message = "The square of 7 is #{square 7}."

# => "The square of 7 is 49."
{% endhighlight %}

## Discussion

CoffeeScript interpolates strings in similar fashion to ruby. Most
expressions are valid inside the `#{...}` interpolation syntax.

CoffeeScript permits multiple expressions inside the interpolation
which can have side effects, but this is discouraged. Only the last
value will be returned.

{% highlight coffeescript %}
# You can do this, but don't. YOU WILL GO MAD.
square = (x) -> x * x
muppet = "Beeker"
message = "The square of 10 is #{muppet='Animal'; square 10}. Oh, and your favorite muppet is now #{muppet}."

# => "The square of 10 is 100. Oh, and your favorite muppet is now Animal."
{% endhighlight %}


================================================
FILE: chapters/strings/lowercasing-a-string.md
================================================
---
layout: recipe
title: Lowercasing a String
chapter: Strings
---
## Problem

You want to lowercase a string.

## Solution

Use JavaScript's String toLowerCase() method:

{% highlight coffeescript %}
"ONE TWO THREE".toLowerCase()
# => 'one two three'
{% endhighlight %}

## Discussion

`toLowerCase()` is a standard JavaScript method. Don't forget the parentheses.

### Syntax Sugar

You can add some Ruby-like syntax sugar with the following shortcut:

{% highlight coffeescript %}
String::downcase = -> @toLowerCase()
"ONE TWO THREE".downcase()
# => 'one two three'
{% endhighlight %}

The snippet above demonstrates a few features of CoffeeScript:

* The double-colon `::` is shorthand for saying `.prototype.`
* The "at" sign `@` is shorthand for saying `this.`

The code above compiles in to the following JavaScript:

{% highlight javascript %}
String.prototype.downcase = function() {
  return this.toLowerCase();
};
"ONE TWO THREE".downcase();
{% endhighlight %}

**Note:** Although it's quite common in languages like Ruby, extending native objects is often considered bad practice in JavaScript (see: [Maintainable JavaScript: Don’t modify objects you don’t own](http://www.nczonline.net/blog/2010/03/02/maintainable-javascript-dont-modify-objects-you-down-own/); [Extending built-in native objects. Evil or not?](http://perfectionkills.com/extending-built-in-native-objects-evil-or-not/)).

================================================
FILE: chapters/strings/matching-strings.md
================================================
---
layout:   recipe
title:    Matching Strings
chapter:  Strings
---
## Problem

You want to match two or more strings.

## Solution

Calculate the edit distance, or number of operations required to transform one string into the other.

{% highlight coffeescript %}

  levenshtein = (str1, str2) ->
    
    l1 = str1.length
    l2 = str2.length
    prevDist = [0..l2]
    nextDist = [0..l2]

    for i in [1..l1] by 1
      nextDist[0] = i
      for j in [1..l2] by 1
        if (str1.charAt i-1) == (str2.charAt j-1)
          nextDist[j] = prevDist[j-1]
        else
          nextDist[j] = 1 + Math.min prevDist[j], nextDist[j-1], prevDist[j-1]
        [prevDist,nextDist]=[nextDist, prevDist]
    
    prevDist[l2]

{% endhighlight %}

## Discussion

You can use either Hirschberg or Wagner–Fischer's algorithm to calculate a Levenshtein distance. This example uses Wagner–Fischer's algorithm.

This version of Levenshtein algorithm is linear in memory, quadratic in time.

str.charAt i is preferred here to str[i] because the latter syntax is not supported by some browsers (e.g. IE7).

At first glance the use of "by 1" in the two loops might look useless. It is actually here to avoid a common danger 
of the coffeescript [i..j] syntax. If str1 or str2 is an empty string, then [1..l1] or [1..l2] will return [1,0].
The loops with the "by 1" statement also compiles to cleaner / slightly more performant javascript.

Finally the optimization of recycling of arrays at the end of the loops is mainly here to
demonstrate the syntax of coffeescript for swapping two variables.


==========
Download .txt
gitextract_ml6e9x2u/

├── .gitignore
├── .ruby-gemset
├── .ruby-version
├── Gemfile
├── LICENSE-CC-BY.textile
├── Procfile
├── README.md
├── _config.yml
├── _data/
│   └── chapters.yml
├── _layouts/
│   ├── chapter.html
│   ├── default.html
│   └── recipe.html
├── authors-guide.md
├── authors.md
├── chapters/
│   ├── ajax/
│   │   ├── ajax_request_without_jquery.md
│   │   └── index.html
│   ├── arrays/
│   │   ├── check-type-is-array.md
│   │   ├── concatenating-arrays.md
│   │   ├── creating-a-dictionary-object-from-an-array.md
│   │   ├── creating-a-string-from-an-array.md
│   │   ├── define-ranges.md
│   │   ├── filtering-arrays.md
│   │   ├── index.html
│   │   ├── list-comprehensions.md
│   │   ├── mapping-arrays.md
│   │   ├── max-array-value.md
│   │   ├── reducing-arrays.md
│   │   ├── removing-duplicate-elements-from-arrays.md
│   │   ├── reversing-arrays.md
│   │   ├── shuffling-array-elements.md
│   │   ├── testing-every-element.md
│   │   ├── using-arrays-to-swap-variables.md
│   │   ├── where-for-arrays-of-objects.md
│   │   └── zip-function.md
│   ├── classes_and_objects/
│   │   ├── chaining.md
│   │   ├── class-methods-and-instance-methods.md
│   │   ├── class-variables-and-instance-variables.md
│   │   ├── cloning.md
│   │   ├── index.html
│   │   ├── mixins.md
│   │   ├── object-literal.md
│   │   └── type-function.md
│   ├── databases/
│   │   ├── index.html
│   │   ├── mongodb.md
│   │   └── sqlite.md
│   ├── dates_and_times/
│   │   ├── date-of-easter.md
│   │   ├── date-of-thanksgiving.md
│   │   ├── days-between-two-dates.md
│   │   ├── finding-last-day-of-the-month.md
│   │   ├── finding-last-or-next-month.md
│   │   ├── index.html
│   │   └── moon-phase-for-date.md
│   ├── design_patterns/
│   │   ├── adapter.md
│   │   ├── bridge.md
│   │   ├── builder.md
│   │   ├── command.md
│   │   ├── decorator.md
│   │   ├── factory_method.md
│   │   ├── index.html
│   │   ├── interpreter.md
│   │   ├── memento.md
│   │   ├── observer.md
│   │   ├── singleton.md
│   │   ├── strategy.md
│   │   └── template_method.md
│   ├── functions/
│   │   ├── debounce.md
│   │   ├── index.html
│   │   ├── parentheses.md
│   │   ├── recursion.md
│   │   └── splat_arguments.md
│   ├── index.html
│   ├── jquery/
│   │   ├── ajax.md
│   │   ├── callback-bindings-jquery.md
│   │   ├── index.html
│   │   └── plugin.md
│   ├── math/
│   │   ├── constants.md
│   │   ├── fast-fibonacci.md
│   │   ├── fast-inv-square.md
│   │   ├── generating-predictable-random-numbers.md
│   │   ├── generating-random-numbers.md
│   │   ├── index.html
│   │   ├── radians-degrees.md
│   │   ├── random-integer.md
│   │   └── working-with-exponents-and-logarithms.md
│   ├── metaprogramming/
│   │   ├── detecting-and-replacing-functions.md
│   │   ├── extending-built-in-objects.md
│   │   └── index.html
│   ├── networking/
│   │   ├── basic-client.md
│   │   ├── basic-http-client.md
│   │   ├── basic-http-server.md
│   │   ├── basic-server.md
│   │   ├── bi-directional-client.md
│   │   ├── bi-directional-server.md
│   │   └── index.html
│   ├── regular_expressions/
│   │   ├── heregexes.md
│   │   ├── index.html
│   │   ├── replacing-html-tags-with-html-named-entities.md
│   │   ├── replacing-substrings.md
│   │   └── searching-for-substrings.md
│   ├── strings/
│   │   ├── capitalizing-words.md
│   │   ├── finding-substrings.md
│   │   ├── generating-a-unique-id.md
│   │   ├── index.html
│   │   ├── interpolation.md
│   │   ├── lowercasing-a-string.md
│   │   ├── matching-strings.md
│   │   ├── repeating.md
│   │   ├── replacing-sub-strings.md
│   │   ├── splitting-a-string.md
│   │   ├── trimming-whitespace-from-a-string.md
│   │   └── uppercasing-a-string.md
│   ├── syntax/
│   │   ├── code_reuse_on_client_and_server.md
│   │   ├── comparing_ranges.md
│   │   ├── embedding_javascript.md
│   │   ├── for_loops.md
│   │   └── index.html
│   └── testing/
│       ├── index.html
│       ├── testing_with_jasmine.md
│       └── testing_with_nodeunit.md
├── contributing.md
├── css/
│   ├── autumn.css
│   ├── borland.css
│   ├── bw.css
│   ├── colorful.css
│   ├── default.css
│   ├── emacs.css
│   ├── friendly.css
│   ├── fruity.css
│   ├── manni.css
│   ├── murphy.css
│   ├── native.css
│   ├── pastie.css
│   ├── perldoc.css
│   ├── solarized-light.css
│   ├── style.css
│   ├── tango.css
│   ├── trac.css
│   ├── vim.css
│   └── vs.css
├── designers-guide.md
├── developers-guide.md
├── index.html
├── js/
│   └── scripts.js
├── license.md
├── recipe-template.md
├── terms-of-use.md
└── wanted-recipes.md
Condensed preview — 147 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (363K chars).
[
  {
    "path": ".gitignore",
    "chars": 79,
    "preview": ".rvmrc\n_site\n\n*.swp\n*.swo\n\n.DS_Store\n\n# IntelliJ IDEA / WebStorm\n/.idea/\n/*.iml"
  },
  {
    "path": ".ruby-gemset",
    "chars": 22,
    "preview": "coffeescript-cookbook\n"
  },
  {
    "path": ".ruby-version",
    "chars": 6,
    "preview": "1.9.3\n"
  },
  {
    "path": "Gemfile",
    "chars": 129,
    "preview": "source 'https://rubygems.org'\n\ngroup :development do\n  gem \"github-pages\"\n  gem \"tzinfo-data\"\n\n  gem \"foreman\"\n  gem \"se"
  },
  {
    "path": "LICENSE-CC-BY.textile",
    "chars": 16882,
    "preview": "---\nlayout: default\ntitle: \"Creative Commons License: Attribution 3.0 Unported (CC BY 3.0)\"\n---\n\nLicense\n\nTHE WORK (AS D"
  },
  {
    "path": "Procfile",
    "chars": 89,
    "preview": "jekyll: bundle exec jekyll build --watch\nserve: bundle exec serve 4000 development _site\n"
  },
  {
    "path": "README.md",
    "chars": 1724,
    "preview": "CoffeeScript Cookbook\n=============\n\nCoffeeScript Cookbook is a community run website for the CoffeeScript language.\nWe "
  },
  {
    "path": "_config.yml",
    "chars": 174,
    "preview": "baseurl: ''\nsafe: true\nhighlighter: pygments\nlsi: false\nmarkdown: redcarpet\nexclude:\n  - README.md\n  - CNAME\n  - TODO.md"
  },
  {
    "path": "_data/chapters.yml",
    "chars": 200,
    "preview": "---\n- Syntax\n- Classes and Objects\n- Strings\n- Arrays\n- Dates and Times\n- Math\n- Functions\n- Metaprogramming\n- jQuery\n- "
  },
  {
    "path": "_layouts/chapter.html",
    "chars": 3469,
    "preview": "<!doctype html>\n<html>\n  <head>\n    <meta charset=\"utf-8\">\n    <meta name=\"viewport\" content=\"width=device-width\">\n    <"
  },
  {
    "path": "_layouts/default.html",
    "chars": 3442,
    "preview": "<!doctype html>\n<html>\n  <head>\n    <meta charset=\"utf-8\">\n    <meta name=\"viewport\" content=\"width=device-width\">\n    <"
  },
  {
    "path": "_layouts/recipe.html",
    "chars": 3392,
    "preview": "<!doctype html>\n<html>\n  <head>\n    <meta charset=\"utf-8\">\n    <meta name=\"viewport\" content=\"width=device-width\">\n    <"
  },
  {
    "path": "authors-guide.md",
    "chars": 10344,
    "preview": "---\nlayout: default\ntitle: Author's Guide\n---\n# Author's Guide\n\n## tl;dr: Look at Other Recipes, and Blend In\n\nLook at t"
  },
  {
    "path": "authors.md",
    "chars": 1734,
    "preview": "---\nlayout: default\ntitle: Authors\n---\n\n# Authors\n\nThe following people are totally rad and awesome because they have co"
  },
  {
    "path": "chapters/ajax/ajax_request_without_jquery.md",
    "chars": 3521,
    "preview": "---\nlayout: recipe\ntitle: Ajax Request Without jQuery\nchapter: Ajax\n---\n## Problem\n\nYou want to load data from your serv"
  },
  {
    "path": "chapters/ajax/index.html",
    "chars": 460,
    "preview": "---\nlayout: chapter\ntitle: Ajax\nchapter: Ajax\n---\n\n{% capture url %}/chapters/{{ page.chapter | replace: ' ', '_' | down"
  },
  {
    "path": "chapters/arrays/check-type-is-array.md",
    "chars": 1066,
    "preview": "---\nlayout: recipe\ntitle: Check if type of value is an Array\nchapter: Arrays\n---\n## Problem\n\nYou want to check if a valu"
  },
  {
    "path": "chapters/arrays/concatenating-arrays.md",
    "chars": 1878,
    "preview": "---\nlayout: recipe\ntitle: Concatenating Arrays\nchapter: Arrays\n---\n## Problem\n\nYou want to join two arrays together.\n\n##"
  },
  {
    "path": "chapters/arrays/creating-a-dictionary-object-from-an-array.md",
    "chars": 1406,
    "preview": "---\nlayout: recipe\ntitle: Creating a dictionary Object from an Array\nchapter: Arrays\n---\n## Problem\n\nYou have an Array o"
  },
  {
    "path": "chapters/arrays/creating-a-string-from-an-array.md",
    "chars": 386,
    "preview": "---\nlayout: recipe\ntitle: Creating a String from an Array\nchapter: Arrays\n---\n## Problem\n\nYou want to create a string fr"
  },
  {
    "path": "chapters/arrays/define-ranges.md",
    "chars": 897,
    "preview": "---\nlayout: recipe\ntitle: Define Ranges Array\nchapter: Arrays\n---\n## Problem\n\nYou want to define a range in an array.\n\n#"
  },
  {
    "path": "chapters/arrays/filtering-arrays.md",
    "chars": 1068,
    "preview": "---\nlayout: recipe\ntitle: Filtering Arrays\nchapter: Arrays\n---\n## Problem\n\nYou want to be able to filter arrays based on"
  },
  {
    "path": "chapters/arrays/index.html",
    "chars": 464,
    "preview": "---\nlayout: chapter\ntitle: Arrays\nchapter: Arrays\n---\n\n{% capture url %}/chapters/{{ page.chapter | replace: ' ', '_' | "
  },
  {
    "path": "chapters/arrays/list-comprehensions.md",
    "chars": 1249,
    "preview": "---\nlayout: recipe\ntitle: List Comprehensions\nchapter: Arrays\n---\n## Problem\n\nYou have an array of objects and want to m"
  },
  {
    "path": "chapters/arrays/mapping-arrays.md",
    "chars": 1322,
    "preview": "---\nlayout: recipe\ntitle: Mapping Arrays\nchapter: Arrays\n---\n## Problem\n\nYou have an array of objects and want to map th"
  },
  {
    "path": "chapters/arrays/max-array-value.md",
    "chars": 854,
    "preview": "---\nlayout: recipe\ntitle: Max Array Value\nchapter: Arrays\n---\n## Problem\n\nYou need to find the largest value contained i"
  },
  {
    "path": "chapters/arrays/reducing-arrays.md",
    "chars": 1265,
    "preview": "---\nlayout: recipe\ntitle: Reducing Arrays\nchapter: Arrays\n---\n## Problem\n\nYou have an array of objects and want to reduc"
  },
  {
    "path": "chapters/arrays/removing-duplicate-elements-from-arrays.md",
    "chars": 1127,
    "preview": "---\nlayout: recipe\ntitle: Removing Duplicate Elements from Arrays\nchapter: Arrays\n---\n## Problem\n\nYou want to remove dup"
  },
  {
    "path": "chapters/arrays/reversing-arrays.md",
    "chars": 363,
    "preview": "---\nlayout: recipe\ntitle: Reversing Arrays\nchapter: Arrays\n---\n## Problem\n\nYou want to reverse an array.\n\n## Solution\n\nU"
  },
  {
    "path": "chapters/arrays/shuffling-array-elements.md",
    "chars": 4316,
    "preview": "---\nlayout: recipe\ntitle: Shuffling Array Elements\nchapter: Arrays\n---\n## Problem\n\nYou want to shuffle the elements in a"
  },
  {
    "path": "chapters/arrays/testing-every-element.md",
    "chars": 1213,
    "preview": "---\nlayout: recipe\ntitle: Testing Every Element\nchapter: Arrays\n---\n## Problem\n\nYou want to be able to check that every "
  },
  {
    "path": "chapters/arrays/using-arrays-to-swap-variables.md",
    "chars": 867,
    "preview": "---\nlayout: recipe\ntitle: Using Arrays to Swap Variables\nchapter: Arrays\n---\n## Problem\n\nYou want to use an array to swa"
  },
  {
    "path": "chapters/arrays/where-for-arrays-of-objects.md",
    "chars": 2016,
    "preview": "---\nlayout: recipe\ntitle: where for arrays of objects\nchapter: Arrays\n---\n## Problem\n\nYou want to get an array of object"
  },
  {
    "path": "chapters/arrays/zip-function.md",
    "chars": 678,
    "preview": "---\nlayout: recipe\ntitle: Python-like Zip Function\nchapter: Arrays\n---\n## Problem\n\nYou want to zip together multiple arr"
  },
  {
    "path": "chapters/classes_and_objects/chaining.md",
    "chars": 1924,
    "preview": "---\nlayout: recipe\ntitle: Chaining Calls to an Object\nchapter: Classes and Objects\n---\n## Problem\n\nYou want to call mult"
  },
  {
    "path": "chapters/classes_and_objects/class-methods-and-instance-methods.md",
    "chars": 1434,
    "preview": "---\nlayout: recipe\ntitle: Class Methods and Instance Methods\nchapter: Classes and Objects\n---\n## Problem\n\nYou want to cr"
  },
  {
    "path": "chapters/classes_and_objects/class-variables-and-instance-variables.md",
    "chars": 2417,
    "preview": "---\nlayout: recipe\ntitle: Class Variables and Instance Variables\nchapter: Classes and Objects\n---\n## Problem\n\nYou want t"
  },
  {
    "path": "chapters/classes_and_objects/cloning.md",
    "chars": 1547,
    "preview": "---\nlayout: recipe\ntitle: Cloning an Object (Deep Copy)\nchapter: Classes and Objects\n---\n## Problem\n\nYou want to clone a"
  },
  {
    "path": "chapters/classes_and_objects/index.html",
    "chars": 490,
    "preview": "---\nlayout: chapter\ntitle: Classes and Objects\nchapter: Classes and Objects\n---\n\n{% capture url %}/chapters/{{ page.chap"
  },
  {
    "path": "chapters/classes_and_objects/mixins.md",
    "chars": 1079,
    "preview": "---\nlayout: recipe\ntitle: Mixins for classes\nchapter: Classes and Objects\n---\n## Problem\n\nYou have a few utility methods"
  },
  {
    "path": "chapters/classes_and_objects/object-literal.md",
    "chars": 1079,
    "preview": "---\nlayout: recipe\ntitle: Create an Object Literal if It Does Not Already Exist\nchapter: Classes and Objects\n---\n## Prob"
  },
  {
    "path": "chapters/classes_and_objects/type-function.md",
    "chars": 1351,
    "preview": "---\nlayout: recipe\ntitle: A CoffeeScript Type Function\nchapter: Classes and Objects\n---\n## Problem\n\nYou'd like to know t"
  },
  {
    "path": "chapters/databases/index.html",
    "chars": 470,
    "preview": "---\nlayout: chapter\ntitle: Databases\nchapter: Databases\n---\n\n{% capture url %}/chapters/{{ page.chapter | replace: ' ', "
  },
  {
    "path": "chapters/databases/mongodb.md",
    "chars": 1960,
    "preview": "---\nlayout: recipe\ntitle: MongoDB\nchapter: Databases\n---\n## Problem\n\nYou need to interface with a MongoDB database.\n\n## "
  },
  {
    "path": "chapters/databases/sqlite.md",
    "chars": 2678,
    "preview": "---\nlayout: recipe\ntitle: SQLite\nchapter: Databases\n---\n## Problem\n\nYou need to interface with a [SQLite](http://www.sql"
  },
  {
    "path": "chapters/dates_and_times/date-of-easter.md",
    "chars": 1346,
    "preview": "---\nlayout: recipe\ntitle: Calculate the Date of Easter Sunday\nchapter: Dates and Times\n---\n## Problem\n\nYou need to find "
  },
  {
    "path": "chapters/dates_and_times/date-of-thanksgiving.md",
    "chars": 1459,
    "preview": "---\nlayout: recipe\ntitle: Calculate the Date of Thanksgiving (USA and Canada)\nchapter: Dates and Times\n---\n## Problem\n\nY"
  },
  {
    "path": "chapters/dates_and_times/days-between-two-dates.md",
    "chars": 1282,
    "preview": "---\nlayout: recipe\ntitle: Get Days Between Two Dates\nchapter: Dates and Times\n---\n## Problem\n\nYou need to find how many "
  },
  {
    "path": "chapters/dates_and_times/finding-last-day-of-the-month.md",
    "chars": 965,
    "preview": "---\nlayout: recipe\ntitle: Finding the Last Day of the Month\nchapter: Dates and Times\n---\n## Problem\n\nYou need to find th"
  },
  {
    "path": "chapters/dates_and_times/finding-last-or-next-month.md",
    "chars": 1658,
    "preview": "---\nlayout: recipe\ntitle: Finding Last (or Next) Month\nchapter: Dates and Times\n---\n## Problem\n\nYou need to calculate a "
  },
  {
    "path": "chapters/dates_and_times/index.html",
    "chars": 482,
    "preview": "---\nlayout: chapter\ntitle: Dates and Times\nchapter: Dates and Times\n---\n\n{% capture url %}/chapters/{{ page.chapter | re"
  },
  {
    "path": "chapters/dates_and_times/moon-phase-for-date.md",
    "chars": 3569,
    "preview": "---\nlayout: recipe\ntitle: Calculate Phase of the Moon for a Date\nchapter: Dates and Times\n---\n## Problem\n\nYou want to fi"
  },
  {
    "path": "chapters/design_patterns/adapter.md",
    "chars": 2113,
    "preview": "---\nlayout: recipe\ntitle: Adapter pattern\nchapter: Design patterns\n---\n## Problem\n\nImagine you are traveling to a foreig"
  },
  {
    "path": "chapters/design_patterns/bridge.md",
    "chars": 1784,
    "preview": "---\nlayout: recipe\ntitle: Bridge Pattern\nchapter: Design Patterns\n---\n## Problem\n\nYou need to maintain a reliable interf"
  },
  {
    "path": "chapters/design_patterns/builder.md",
    "chars": 3601,
    "preview": "---\nlayout: recipe\ntitle: Builder Pattern\nchapter: Design Patterns\n---\n## Problem\n\nYou need to prepare a complicated, mu"
  },
  {
    "path": "chapters/design_patterns/command.md",
    "chars": 1497,
    "preview": "---\nlayout: recipe\ntitle: Command Pattern\nchapter: Design Patterns\n---\n## Problem\n\nYou need to let another object handle"
  },
  {
    "path": "chapters/design_patterns/decorator.md",
    "chars": 2584,
    "preview": "---\nlayout: recipe\ntitle: Decorator Pattern\nchapter: Design Patterns\n---\n## Problem\n\nYou have a set of data that you nee"
  },
  {
    "path": "chapters/design_patterns/factory_method.md",
    "chars": 1651,
    "preview": "---\nlayout: recipe\ntitle: Factory Method Pattern\nchapter: Design Patterns\n---\n## Problem\n\nYou don't know what kind of ob"
  },
  {
    "path": "chapters/design_patterns/index.html",
    "chars": 482,
    "preview": "---\nlayout: chapter\ntitle: Design Patterns\nchapter: Design Patterns\n---\n\n{% capture url %}/chapters/{{ page.chapter | re"
  },
  {
    "path": "chapters/design_patterns/interpreter.md",
    "chars": 4183,
    "preview": "---\nlayout: recipe\ntitle: Interpreter Pattern\nchapter: Design Patterns\n---\n## Problem\n\nSomeone else needs to run parts o"
  },
  {
    "path": "chapters/design_patterns/memento.md",
    "chars": 1395,
    "preview": "---\nlayout: recipe\ntitle: Memento Pattern\nchapter: Design Patterns\n---\n## Problem\n\nYou want to anticipate the reversion "
  },
  {
    "path": "chapters/design_patterns/observer.md",
    "chars": 1415,
    "preview": "---\nlayout: recipe\ntitle: Observer Pattern\nchapter: Design patterns\n---\n## Problem\n\nYou have to notify some objects abou"
  },
  {
    "path": "chapters/design_patterns/singleton.md",
    "chars": 3886,
    "preview": "---\nlayout: recipe\ntitle: Singleton Pattern\nchapter: Design Patterns\n---\n## Problem\n\nMany times you only want one, and o"
  },
  {
    "path": "chapters/design_patterns/strategy.md",
    "chars": 2245,
    "preview": "---\nlayout: recipe\ntitle: Strategy Pattern\nchapter: Design Patterns\n---\n## Problem\n\nYou have more than one way to solve "
  },
  {
    "path": "chapters/design_patterns/template_method.md",
    "chars": 1911,
    "preview": "---\nlayout: recipe\ntitle: Template Method Pattern\nchapter: Design Patterns\n---\n## Problem\n\nDefine the structure of an al"
  },
  {
    "path": "chapters/functions/debounce.md",
    "chars": 1101,
    "preview": "---\nlayout: recipe\ntitle: Debounce Functions\nchapter: Functions\n---\n## Problem\n\nYou want to execute a function only once"
  },
  {
    "path": "chapters/functions/index.html",
    "chars": 470,
    "preview": "---\nlayout: chapter\ntitle: Functions\nchapter: Functions\n---\n\n{% capture url %}/chapters/{{ page.chapter | replace: ' ', "
  },
  {
    "path": "chapters/functions/parentheses.md",
    "chars": 1347,
    "preview": "---\nlayout: recipe\ntitle: When Function Parentheses Are Not Optional\nchapter: Functions\n---\n## Problem\n\nYou want to call"
  },
  {
    "path": "chapters/functions/recursion.md",
    "chars": 726,
    "preview": "---\nlayout: recipe\ntitle: Recursive Functions\nchapter: Functions\n---\n## Problem\n\nYou want to call a function from within"
  },
  {
    "path": "chapters/functions/splat_arguments.md",
    "chars": 1486,
    "preview": "---\nlayout: recipe\ntitle: Splat Arguments\nchapter: Functions\n---\n## Problem\n\nYour function will be called with a varying"
  },
  {
    "path": "chapters/index.html",
    "chars": 956,
    "preview": "---\nlayout: default\ntitle: Cookbook\n---\n\n<article class=\"content-block\">\n\n  <h5 class=\"sidebar-title\">Chapters</h5>\n\n  <"
  },
  {
    "path": "chapters/jquery/ajax.md",
    "chars": 1207,
    "preview": "---\nlayout: recipe\ntitle: AJAX\nchapter: jQuery\n---\n## Problem\n\nYou want to make AJAX calls using jQuery.\n\n## Solution\n\n{"
  },
  {
    "path": "chapters/jquery/callback-bindings-jquery.md",
    "chars": 624,
    "preview": "---\nlayout: recipe\ntitle: Callback Bindings # using => instead of ->\nchapter: jQuery\n---\n## Problem\n\nYou want to bind a "
  },
  {
    "path": "chapters/jquery/index.html",
    "chars": 464,
    "preview": "---\nlayout: chapter\ntitle: jQuery\nchapter: jQuery\n---\n\n{% capture url %}/chapters/{{ page.chapter | replace: ' ', '_' | "
  },
  {
    "path": "chapters/jquery/plugin.md",
    "chars": 1074,
    "preview": "---\nlayout: recipe\ntitle: Create a jQuery Plugin\nchapter: jQuery\n---\n## Problem\n\nYou'd like to create jQuery plugin usin"
  },
  {
    "path": "chapters/math/constants.md",
    "chars": 883,
    "preview": "---\nlayout: recipe\ntitle: Math Constants\nchapter: Math\n---\n## Problem\n\nYou need to use common mathematical constants lik"
  },
  {
    "path": "chapters/math/fast-fibonacci.md",
    "chars": 2708,
    "preview": "---\nlayout: recipe\ntitle: Faster Fibonacci Algorithm\nchapter: Math\n---\n## Problem\n\nYou would like to calculate a number "
  },
  {
    "path": "chapters/math/fast-inv-square.md",
    "chars": 4731,
    "preview": "---\nlayout: recipe\ntitle: Fast Inverse Square Root\nchapter: Math\n---\n## Problem\n\nYou would like to calculate a the inver"
  },
  {
    "path": "chapters/math/generating-predictable-random-numbers.md",
    "chars": 3299,
    "preview": "---\nlayout: recipe\ntitle: Generating Predictable Random Numbers\nchapter: Math\n---\n## Problem\n\nYou need to generate a ran"
  },
  {
    "path": "chapters/math/generating-random-numbers.md",
    "chars": 1195,
    "preview": "---\nlayout: recipe\ntitle: Generating Random Numbers\nchapter: Math\n---\n## Problem\n\nYou need to generate a random number i"
  },
  {
    "path": "chapters/math/index.html",
    "chars": 460,
    "preview": "---\nlayout: chapter\ntitle: Math\nchapter: Math\n---\n\n{% capture url %}/chapters/{{ page.chapter | replace: ' ', '_' | down"
  },
  {
    "path": "chapters/math/radians-degrees.md",
    "chars": 606,
    "preview": "---\nlayout: recipe\ntitle: Converting Radians and Degrees\nchapter: Math\n---\n## Problem\n\nYou need to convert between radia"
  },
  {
    "path": "chapters/math/random-integer.md",
    "chars": 694,
    "preview": "---\nlayout: recipe\ntitle: A Random Integer Function\nchapter: Math\n---\n## Problem\n\nYou'd like to get a random integer bet"
  },
  {
    "path": "chapters/math/working-with-exponents-and-logarithms.md",
    "chars": 1001,
    "preview": "---\nlayout: recipe\ntitle: Working with Exponents and Logarithms\nchapter: Math\n---\n## Problem\n\nYou need to do some calcul"
  },
  {
    "path": "chapters/metaprogramming/detecting-and-replacing-functions.md",
    "chars": 3425,
    "preview": "---\nlayout: recipe\ntitle: Detecting and Creating Missing Functions\nchapter: Metaprogramming\n---\n## Problem\n\nYou want to "
  },
  {
    "path": "chapters/metaprogramming/extending-built-in-objects.md",
    "chars": 1149,
    "preview": "---\nlayout: recipe\ntitle: Extending Built-in Objects\nchapter: Metaprogramming\n---\n## Problem\n\nYou want to extend a class"
  },
  {
    "path": "chapters/metaprogramming/index.html",
    "chars": 482,
    "preview": "---\nlayout: chapter\ntitle: Metaprogramming\nchapter: Metaprogramming\n---\n\n{% capture url %}/chapters/{{ page.chapter | re"
  },
  {
    "path": "chapters/networking/basic-client.md",
    "chars": 1344,
    "preview": "---\nlayout: recipe\ntitle: Basic Client\nchapter: Networking\n---\n## Problem\n\nYou want to access a service provided over th"
  },
  {
    "path": "chapters/networking/basic-http-client.md",
    "chars": 2240,
    "preview": "---\nlayout: recipe\ntitle: Basic HTTP Client\nchapter: Networking\n---\n\n## Problem\n\nYou want to create a HTTP client.\n\n## S"
  },
  {
    "path": "chapters/networking/basic-http-server.md",
    "chars": 8191,
    "preview": "---\nlayout: recipe\ntitle: Basic HTTP Server\nchapter: Networking\n---\n\n## Problem\n\nYou want to create a HTTP server over a"
  },
  {
    "path": "chapters/networking/basic-server.md",
    "chars": 1507,
    "preview": "---\nlayout: recipe\ntitle: Basic Server\nchapter: Networking\n---\n## Problem\n\nYou want to provide a service over a network."
  },
  {
    "path": "chapters/networking/bi-directional-client.md",
    "chars": 2044,
    "preview": "---\nlayout: recipe\ntitle: Bi-Directional Client\nchapter: Networking\n---\n## Problem\n\nYou want to a persistent service ove"
  },
  {
    "path": "chapters/networking/bi-directional-server.md",
    "chars": 1720,
    "preview": "---\nlayout: recipe\ntitle: Bi-Directional Server\nchapter: Networking\n---\n## Problem\n\nYou want to provide a persistent ser"
  },
  {
    "path": "chapters/networking/index.html",
    "chars": 472,
    "preview": "---\nlayout: chapter\ntitle: Networking\nchapter: Networking\n---\n\n{% capture url %}/chapters/{{ page.chapter | replace: ' '"
  },
  {
    "path": "chapters/regular_expressions/heregexes.md",
    "chars": 1223,
    "preview": "---\nlayout: recipe\ntitle: Using Heregexes\nchapter: Regular Expressions\n---\n## Problem\n\nYou need to write a complex regul"
  },
  {
    "path": "chapters/regular_expressions/index.html",
    "chars": 490,
    "preview": "---\nlayout: chapter\ntitle: Regular Expressions\nchapter: Regular Expressions\n---\n\n{% capture url %}/chapters/{{ page.chap"
  },
  {
    "path": "chapters/regular_expressions/replacing-html-tags-with-html-named-entities.md",
    "chars": 596,
    "preview": "---\nlayout: recipe\ntitle: Replacing HTML Tags with HTML Named Entities\nchapter: Regular Expressions\n---\n## Problem\n\nYou "
  },
  {
    "path": "chapters/regular_expressions/replacing-substrings.md",
    "chars": 1038,
    "preview": "---\nlayout: recipe\ntitle: Replacing Substrings\nchapter: Regular Expressions\n---\n## Problem\n\nYou need to replace a portio"
  },
  {
    "path": "chapters/regular_expressions/searching-for-substrings.md",
    "chars": 1871,
    "preview": "---\nlayout: recipe\ntitle: Searching for Substrings\nchapter: Regular Expressions\n---\n## Problem\n\nYou need to search for a"
  },
  {
    "path": "chapters/strings/capitalizing-words.md",
    "chars": 1804,
    "preview": "---\nlayout: recipe\ntitle: Capitalizing Words\nchapter: Strings\n---\n## Problem\n\nYou want to capitalize the first letter of"
  },
  {
    "path": "chapters/strings/finding-substrings.md",
    "chars": 684,
    "preview": "---\nlayout: recipe\ntitle: Finding Substrings\nchapter: Strings\n---\n## Problem\n\nYou need to find the first or last occurre"
  },
  {
    "path": "chapters/strings/generating-a-unique-id.md",
    "chars": 635,
    "preview": "---\nlayout: recipe\ntitle: Generating a Unique ID\nchapter: Strings\n---\n## Problem\n\nYou want to generate a random unique i"
  },
  {
    "path": "chapters/strings/index.html",
    "chars": 466,
    "preview": "---\nlayout: chapter\ntitle: Strings\nchapter: Strings\n---\n\n{% capture url %}/chapters/{{ page.chapter | replace: ' ', '_' "
  },
  {
    "path": "chapters/strings/interpolation.md",
    "chars": 1337,
    "preview": "---\nlayout:   recipe\ntitle:    String Interpolation\nchapter:  Strings\n---\n## Problem\n\nYou want to create a string that c"
  },
  {
    "path": "chapters/strings/lowercasing-a-string.md",
    "chars": 1402,
    "preview": "---\nlayout: recipe\ntitle: Lowercasing a String\nchapter: Strings\n---\n## Problem\n\nYou want to lowercase a string.\n\n## Solu"
  },
  {
    "path": "chapters/strings/matching-strings.md",
    "chars": 1631,
    "preview": "---\r\nlayout:   recipe\r\ntitle:    Matching Strings\r\nchapter:  Strings\r\n---\r\n## Problem\r\n\r\nYou want to match two or more s"
  },
  {
    "path": "chapters/strings/repeating.md",
    "chars": 897,
    "preview": "---\nlayout: recipe\ntitle: Repeating a String\nchapter: Strings\n---\n## Problem\n\nYou want to repeat a string.\n\n## Solution\n"
  },
  {
    "path": "chapters/strings/replacing-sub-strings.md",
    "chars": 822,
    "preview": "---\nlayout: recipe\ntitle: Replacing Sub-Strings Within a String\nchapter: Strings\n---\n## Problem\n\nYou want to replace a s"
  },
  {
    "path": "chapters/strings/splitting-a-string.md",
    "chars": 852,
    "preview": "---\nlayout: recipe\ntitle: Splitting a String\nchapter: Strings\n---\n## Problem\n\nYou want to split a string.\n\n## Solution\n\n"
  },
  {
    "path": "chapters/strings/trimming-whitespace-from-a-string.md",
    "chars": 1773,
    "preview": "---\nlayout: recipe\ntitle: Trimming Whitespace from a String\nchapter: Strings\n---\n## Problem\n\nYou want to trim whitespace"
  },
  {
    "path": "chapters/strings/uppercasing-a-string.md",
    "chars": 1395,
    "preview": "---\nlayout: recipe\ntitle: Uppercasing a String\nchapter: Strings\n---\n## Problem\n\nYou want to uppercase a string.\n\n## Solu"
  },
  {
    "path": "chapters/syntax/code_reuse_on_client_and_server.md",
    "chars": 2006,
    "preview": "---\nlayout: recipe\ntitle: Code Reuse on Client and Server\nchapter: Syntax\n---\n## Problem\n\nYou have created some function"
  },
  {
    "path": "chapters/syntax/comparing_ranges.md",
    "chars": 711,
    "preview": "---\nlayout: recipe\ntitle: Comparing Ranges\nchapter: Syntax\n---\n## Problem\n\nYou want to know if a variable is inside a gi"
  },
  {
    "path": "chapters/syntax/embedding_javascript.md",
    "chars": 931,
    "preview": "---\nlayout: recipe\ntitle: Embedding JavaScript\nchapter: Syntax\n---\n## Problem\n\nYou want to include some found/pre-writte"
  },
  {
    "path": "chapters/syntax/for_loops.md",
    "chars": 628,
    "preview": "---\nlayout: recipe\ntitle: For Loops\nchapter: Syntax\n---\n## Problem\n\nYou need to iterate over an array, object or range w"
  },
  {
    "path": "chapters/syntax/index.html",
    "chars": 464,
    "preview": "---\nlayout: chapter\ntitle: Syntax\nchapter: Syntax\n---\n\n{% capture url %}/chapters/{{ page.chapter | replace: ' ', '_' | "
  },
  {
    "path": "chapters/testing/index.html",
    "chars": 466,
    "preview": "---\nlayout: chapter\ntitle: Testing\nchapter: Testing\n---\n\n{% capture url %}/chapters/{{ page.chapter | replace: ' ', '_' "
  },
  {
    "path": "chapters/testing/testing_with_jasmine.md",
    "chars": 6181,
    "preview": "---\nlayout: recipe\ntitle: Testing with Jasmine\nchapter: Testing\n---\n## Problem\n\nYou are writing a simple calculator usin"
  },
  {
    "path": "chapters/testing/testing_with_nodeunit.md",
    "chars": 6211,
    "preview": "---\nlayout: recipe\ntitle: Testing with Nodeunit\nchapter: Testing\n---\n## Problem\n\nYou are writing a simple calculator usi"
  },
  {
    "path": "contributing.md",
    "chars": 1261,
    "preview": "---\nlayout: default\ntitle: Contributing\n---\n# Contributing\n\nThe Cookbook needs your help!\n\nHere's the Contribution Recip"
  },
  {
    "path": "css/autumn.css",
    "chars": 3539,
    "preview": ".highlight .hll { background-color: #ffffcc }\n.highlight .c { color: #aaaaaa; font-style: italic } /* Comment */\n.highli"
  },
  {
    "path": "css/borland.css",
    "chars": 2943,
    "preview": ".highlight .hll { background-color: #ffffcc }\n.highlight .c { color: #008800; font-style: italic } /* Comment */\n.highli"
  },
  {
    "path": "css/bw.css",
    "chars": 2078,
    "preview": ".highlight .hll { background-color: #ffffcc }\n.highlight .c { font-style: italic } /* Comment */\n.highlight .err { borde"
  },
  {
    "path": "css/colorful.css",
    "chars": 4160,
    "preview": ".highlight .hll { background-color: #ffffcc }\n.highlight .c { color: #808080 } /* Comment */\n.highlight .err { color: #F"
  },
  {
    "path": "css/default.css",
    "chars": 5605,
    "preview": "/* Minimal reset */\n\n* {\n  vertical-align: baseline;\n  font-family: inherit;\n  font-style: inherit;\n  font-size: 100%;\n "
  },
  {
    "path": "css/emacs.css",
    "chars": 3868,
    "preview": ".highlight .hll { background-color: #ffffcc }\n.highlight .c { color: #008800; font-style: italic } /* Comment */\n.highli"
  },
  {
    "path": "css/friendly.css",
    "chars": 3896,
    "preview": ".highlight .hll { background-color: #ffffcc }\n.highlight .c { color: #60a0b0; font-style: italic } /* Comment */\n.highli"
  },
  {
    "path": "css/fruity.css",
    "chars": 4443,
    "preview": ".highlight .hll { background-color: #333333 }\n.highlight .c { color: #008800; font-style: italic; background-color: #0f1"
  },
  {
    "path": "css/manni.css",
    "chars": 3980,
    "preview": ".highlight .hll { background-color: #ffffcc }\n.highlight .c { color: #0099FF; font-style: italic } /* Comment */\n.highli"
  },
  {
    "path": "css/murphy.css",
    "chars": 4202,
    "preview": ".highlight .hll { background-color: #ffffcc }\n.highlight .c { color: #606060; font-style: italic } /* Comment */\n.highli"
  },
  {
    "path": "css/native.css",
    "chars": 4285,
    "preview": ".highlight .hll { background-color: #404040 }\n.highlight .c { color: #999999; font-style: italic } /* Comment */\n.highli"
  },
  {
    "path": "css/pastie.css",
    "chars": 4259,
    "preview": ".highlight .hll { background-color: #ffffcc }\n.highlight .c { color: #888888 } /* Comment */\n.highlight .err { color: #a"
  },
  {
    "path": "css/perldoc.css",
    "chars": 3625,
    "preview": ".highlight .hll { background-color: #ffffcc }\n.highlight .c { color: #228B22 } /* Comment */\n.highlight .err { color: #a"
  },
  {
    "path": "css/solarized-light.css",
    "chars": 4951,
    "preview": "/*\nbase03:    #002b36;\nbase02:    #073642;\nbase01:    #586e75;\nbase00:    #657b83;\nbase0:     #839496;\nbase1:     #93a1a"
  },
  {
    "path": "css/style.css",
    "chars": 57045,
    "preview": "/*\n  Author:         Amsul - http://github.com/amsul\n  Description:    CoffeeScript Cookbook stylings\n  Version:        "
  },
  {
    "path": "css/tango.css",
    "chars": 4491,
    "preview": ".highlight .hll { background-color: #ffffcc }\n.highlight .c { color: #8f5902; font-style: italic } /* Comment */\n.highli"
  },
  {
    "path": "css/trac.css",
    "chars": 3647,
    "preview": ".highlight .hll { background-color: #ffffcc }\n.highlight .c { color: #999988; font-style: italic } /* Comment */\n.highli"
  },
  {
    "path": "css/vim.css",
    "chars": 4000,
    "preview": ".highlight .hll { background-color: #222222 }\n.highlight .c { color: #000080 } /* Comment */\n.highlight .err { color: #c"
  },
  {
    "path": "css/vs.css",
    "chars": 1896,
    "preview": ".highlight .hll { background-color: #ffffcc }\n.highlight .c { color: #008000 } /* Comment */\n.highlight .err { border: 1"
  },
  {
    "path": "designers-guide.md",
    "chars": 499,
    "preview": "---\nlayout: default\ntitle: Designer's Guide\n---\n\n# Designer's Guide\n\nStart with the [Developer's Guide]({{ site.baseurl "
  },
  {
    "path": "developers-guide.md",
    "chars": 1739,
    "preview": "---\nlayout: default\ntitle: Developer's Guide\n---\n\n# Developer's Guide\n\n_Please help out by updating this page_\n\n### Oper"
  },
  {
    "path": "index.html",
    "chars": 277,
    "preview": "---\nlayout: default\ntitle: Home\n---\n\n\n<h2>Welcome to the CoffeeScript Cookbook!</h2>\n<p>CoffeeScript recipes for the com"
  },
  {
    "path": "js/scripts.js",
    "chars": 947,
    "preview": "\n/*jshint browser: true, devel: true, debug: true */\n\n\n(function( window, document, undefined ) {\n\n    var activePage, p"
  },
  {
    "path": "license.md",
    "chars": 426,
    "preview": "---\nlayout: default\ntitle: License\n---\n\ncoffeescript-cookbook.github.io is licensed under the [Creative Commons Attribut"
  },
  {
    "path": "recipe-template.md",
    "chars": 343,
    "preview": "---\nlayout: default\ntitle: Recipe Template\n---\n\n## Sample recipe template\n\nCreate a new `my-recipe.md` file and use this"
  },
  {
    "path": "terms-of-use.md",
    "chars": 45,
    "preview": "---\nlayout: default\ntitle: Terms of Use\n---\n\n"
  },
  {
    "path": "wanted-recipes.md",
    "chars": 2306,
    "preview": "---\nlayout: default\ntitle: Wanted Recipes\n---\n# Wanted Recipes\n\nHere's a list of recipes we think we need. Pick one, imp"
  }
]

About this extraction

This page contains the full source code of the coffeescript-cookbook/coffeescript-cookbook.github.io GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 147 files (334.9 KB), approximately 106.4k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!