From b16a9071dd6833cf2689e6380b7fc417c99a4f0b Mon Sep 17 00:00:00 2001 From: guillaumebiton Date: Thu, 30 May 2013 12:13:47 +0200 Subject: [PATCH 01/77] new template for arrays of objects (collections?) --- .../arrays/where-for-arrays-of-objects.md | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 chapters/arrays/where-for-arrays-of-objects.md diff --git a/chapters/arrays/where-for-arrays-of-objects.md b/chapters/arrays/where-for-arrays-of-objects.md new file mode 100644 index 0000000..1c6d4d7 --- /dev/null +++ b/chapters/arrays/where-for-arrays-of-objects.md @@ -0,0 +1,76 @@ +--- +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", (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 libraires like underscore or lodash name it "where". From 0b3e4cdbdbfa0a10cdc04516aa405a6a1730b9b2 Mon Sep 17 00:00:00 2001 From: guillaumebiton Date: Thu, 30 May 2013 12:20:05 +0200 Subject: [PATCH 02/77] update discussion example --- chapters/arrays/where-for-arrays-of-objects.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/chapters/arrays/where-for-arrays-of-objects.md b/chapters/arrays/where-for-arrays-of-objects.md index 1c6d4d7..51eba6d 100644 --- a/chapters/arrays/where-for-arrays-of-objects.md +++ b/chapters/arrays/where-for-arrays-of-objects.md @@ -68,6 +68,10 @@ Array::where = (query, matcher = (a,b) -> a is b) -> 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 From 57747556034440204359f767646b458ca4bb0ed9 Mon Sep 17 00:00:00 2001 From: Tatiana Shemiakina Date: Tue, 30 Jul 2013 22:23:19 +0300 Subject: [PATCH 03/77] Create adapter --- chapters/design_patterns/adapter | 60 ++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 chapters/design_patterns/adapter diff --git a/chapters/design_patterns/adapter b/chapters/design_patterns/adapter new file mode 100644 index 0000000..95db31a --- /dev/null +++ b/chapters/design_patterns/adapter @@ -0,0 +1,60 @@ +--- +layout: default +title: Adapter pattern +--- + +## Sample recipe template + +Create a new `my-recipe.md` file and use this text as a start. + +{% highlight text %} +--- +layout: recipe +title: Adapter patter +chapter: Design patterns +--- +## Problem + +Suppose we have 3-rd party grid component. We want to apply there our own custom sorting but a small problem. Our custom sorter does not implement required interface by grid component. +To understand the problem completely best example would be an socket from our usual life. Everybody knows this device. In some countries it has 3 pins and in other contries it has only 2 pins. +This is exactly right situation to use adapter. + +## Solution + +#grid component +class AwesomeGrid + constructor: (@datasource)-> + @sort_order = 'ASC' + @sorter = new NullSorter # in this place we use NullObject pattern (another usefull 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 + +## Discussion + +Adapter is usefull when you have to organize an interaction between two objects with different interfaces. It can happen when you use 3-rd party libraries or you work with legacy code. +In any case be carefull with adapter: it can be helpfull but it can instigate design errors. + +{% endhighlight %} From 8a510977fd926dcf3e0ada13545b6990b514a1a5 Mon Sep 17 00:00:00 2001 From: Tatiana Shemiakina Date: Tue, 30 Jul 2013 22:26:02 +0300 Subject: [PATCH 04/77] Update and rename adapter to adapter.md --- chapters/design_patterns/{adapter => adapter.md} | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) rename chapters/design_patterns/{adapter => adapter.md} (95%) diff --git a/chapters/design_patterns/adapter b/chapters/design_patterns/adapter.md similarity index 95% rename from chapters/design_patterns/adapter rename to chapters/design_patterns/adapter.md index 95db31a..e6a3d67 100644 --- a/chapters/design_patterns/adapter +++ b/chapters/design_patterns/adapter.md @@ -20,8 +20,8 @@ To understand the problem completely best example would be an socket from our us This is exactly right situation to use adapter. ## Solution - -#grid component +{% highlight coffeescript %} +# a fragment of 3-rd party grid component class AwesomeGrid constructor: (@datasource)-> @sort_order = 'ASC' @@ -52,6 +52,8 @@ 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 usefull when you have to organize an interaction between two objects with different interfaces. It can happen when you use 3-rd party libraries or you work with legacy code. From 5fc588889f546f4f958f782c6c4b268712dacd6f Mon Sep 17 00:00:00 2001 From: Tatiana Shemiakina Date: Tue, 30 Jul 2013 22:33:03 +0300 Subject: [PATCH 05/77] Update markup; add link to wiki adapter page --- chapters/design_patterns/adapter.md | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/chapters/design_patterns/adapter.md b/chapters/design_patterns/adapter.md index e6a3d67..8be4ece 100644 --- a/chapters/design_patterns/adapter.md +++ b/chapters/design_patterns/adapter.md @@ -1,14 +1,4 @@ --- -layout: default -title: Adapter pattern ---- - -## Sample recipe template - -Create a new `my-recipe.md` file and use this text as a start. - -{% highlight text %} ---- layout: recipe title: Adapter patter chapter: Design patterns @@ -17,9 +7,10 @@ chapter: Design patterns Suppose we have 3-rd party grid component. We want to apply there our own custom sorting but a small problem. Our custom sorter does not implement required interface by grid component. To understand the problem completely best example would be an socket from our usual life. Everybody knows this device. In some countries it has 3 pins and in other contries it has only 2 pins. -This is exactly right situation to use adapter. +This is exactly right situation to use [adapter pattern](https://en.wikipedia.org/wiki/Adapter_pattern). ## Solution + {% highlight coffeescript %} # a fragment of 3-rd party grid component class AwesomeGrid @@ -58,5 +49,3 @@ agrid.sort() # sort data with custom sorter through adapter Adapter is usefull when you have to organize an interaction between two objects with different interfaces. It can happen when you use 3-rd party libraries or you work with legacy code. In any case be carefull with adapter: it can be helpfull but it can instigate design errors. - -{% endhighlight %} From a97b9d157f8bb95c14bb45fca2ed151b27334916 Mon Sep 17 00:00:00 2001 From: erik Date: Tue, 6 Aug 2013 11:51:51 -0500 Subject: [PATCH 06/77] Simplified and sped up the "type-function" example. --- chapters/classes_and_objects/type-function.md | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/chapters/classes_and_objects/type-function.md b/chapters/classes_and_objects/type-function.md index 42952ac..96e8cea 100644 --- a/chapters/classes_and_objects/type-function.md +++ b/chapters/classes_and_objects/type-function.md @@ -12,16 +12,20 @@ You'd like to know the type of a object without using typeof. (See http://javasc Use the following function: {% highlight coffeescript %} -type = (obj) -> - if obj == undefined or obj == null - return String obj - classToType = new Object - for name in "Boolean Number String Function Array Date RegExp".split(" ") - classToType["[object " + name + "]"] = name.toLowerCase() - myClass = Object.prototype.toString.call obj - if myClass of classToType - return classToType[myClass] - return "object" + 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 From 8bd340fb0c863c116e4cf248c7c0d733d6e662fb Mon Sep 17 00:00:00 2001 From: Frankie Bagnardi Date: Sat, 10 Aug 2013 03:01:08 -0700 Subject: [PATCH 07/77] Math.max.apply note is confusing --- chapters/arrays/max-array-value.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/chapters/arrays/max-array-value.md b/chapters/arrays/max-array-value.md index 906eaac..ce3adc1 100644 --- a/chapters/arrays/max-array-value.md +++ b/chapters/arrays/max-array-value.md @@ -16,18 +16,14 @@ 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 Math.max.apply: +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 - -# Pre-ES5 -Math.max.apply(null, [12,32,11,67,1,3]) -# => 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 ammount of arguments, such as `console.log`. \ No newline at end of file +`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 ammount of arguments, such as `console.log`. From 3d3acde05f6d749adcdf87e85617dd689e96d29c Mon Sep 17 00:00:00 2001 From: Frankie Bagnardi Date: Sat, 10 Aug 2013 03:19:18 -0700 Subject: [PATCH 08/77] r.randi is undefined, should be r.rand --- chapters/math/generating-predictable-random-numbers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chapters/math/generating-predictable-random-numbers.md b/chapters/math/generating-predictable-random-numbers.md index a7cc561..128bc61 100644 --- a/chapters/math/generating-predictable-random-numbers.md +++ b/chapters/math/generating-predictable-random-numbers.md @@ -62,4 +62,4 @@ Avoid the temptation to modulus the output of this generator. If you need an int r.randn() % 2 {% endhighlight %} -because you will most definitely not get random digits. Use `r.randi(2)` instead. +because you will most definitely not get random digits. Use `r.rand(2)` instead. From c2ff4ae0fa8123dfdefe3f2653fea3c92cc82e5a Mon Sep 17 00:00:00 2001 From: Peter Hellberg Date: Sun, 18 Aug 2013 14:19:13 +0200 Subject: [PATCH 09/77] Updated development dependencies --- Gemfile | 12 +++---- Gemfile.lock | 98 ++++++++++++++++++++++++++++++++++------------------ 2 files changed, 70 insertions(+), 40 deletions(-) diff --git a/Gemfile b/Gemfile index ebe0f96..b4d66ba 100644 --- a/Gemfile +++ b/Gemfile @@ -1,9 +1,9 @@ -source 'http://rubygems.org/' +source 'https://rubygems.org/' group :development do - gem "RedCloth", "~> 4.2" - gem "foreman", "~> 0.13" - gem "serve", "~> 1.0" - gem "jekyll", "~> 0.10" - gem "thin", "~> 1.2" + gem "github-pages" + gem "tzinfo-data" + + gem "foreman", "~> 0.63" + gem "serve", "~> 1.5" end diff --git a/Gemfile.lock b/Gemfile.lock index 0b46357..d8185b6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,47 +1,77 @@ GEM - remote: http://rubygems.org/ + remote: https://rubygems.org/ specs: RedCloth (4.2.9) - activesupport (3.0.7) + activesupport (3.2.14) + i18n (~> 0.6, >= 0.6.4) + multi_json (~> 1.0) classifier (1.3.3) fast-stemmer (>= 1.0.0) - daemons (1.1.3) - directory_watcher (1.4.0) - eventmachine (0.12.10) - fast-stemmer (1.0.0) - foreman (0.13.0) - term-ansicolor (~> 1.0.5) + colorator (0.1) + commander (4.1.5) + highline (~> 1.6.11) + directory_watcher (1.4.1) + dotenv (0.8.0) + fast-stemmer (1.0.2) + foreman (0.63.0) + dotenv (>= 0.7) thor (>= 0.13.6) - i18n (0.4.2) - jekyll (0.10.0) - classifier (>= 1.3.1) - directory_watcher (>= 1.1.1) - liquid (>= 1.9.0) - maruku (>= 0.5.9) - liquid (2.2.2) - maruku (0.6.0) + github-pages (1) + RedCloth (= 4.2.9) + jekyll (= 1.1.2) + kramdown (= 1.0.2) + liquid (= 2.5.1) + maruku (= 0.6.1) + rdiscount (= 1.6.8) + redcarpet (= 2.2.2) + highline (1.6.19) + i18n (0.6.5) + jekyll (1.1.2) + classifier (~> 1.3) + colorator (~> 0.1) + commander (~> 4.1.3) + directory_watcher (~> 1.4.1) + kramdown (~> 1.0.2) + liquid (~> 2.5.1) + maruku (~> 0.5) + pygments.rb (~> 0.5.0) + redcarpet (~> 2.2.2) + safe_yaml (~> 0.7.0) + kramdown (1.0.2) + liquid (2.5.1) + maruku (0.6.1) syntax (>= 1.0.0) - rack (1.2.2) - serve (1.0.0) - activesupport (~> 3.0.1) - i18n (~> 0.4.1) - rack (~> 1.2.1) - tzinfo (~> 0.3.23) + multi_json (1.7.9) + posix-spawn (0.3.6) + pygments.rb (0.5.2) + posix-spawn (~> 0.3.6) + yajl-ruby (~> 1.1.0) + rack (1.5.2) + rack-test (0.6.2) + rack (>= 1.0) + rdiscount (1.6.8) + redcarpet (2.2.2) + safe_yaml (0.7.1) + serve (1.5.2) + activesupport (~> 3.2.12) + i18n + rack (~> 1.5.2) + rack-test (~> 0.6.2) + tilt (~> 1.3.3) + tzinfo syntax (1.0.0) - term-ansicolor (1.0.5) - thin (1.2.11) - daemons (>= 1.0.9) - eventmachine (>= 0.12.6) - rack (>= 1.0.0) - thor (0.14.6) - tzinfo (0.3.27) + thor (0.18.1) + tilt (1.3.7) + tzinfo (1.0.1) + tzinfo-data (1.2013.4) + tzinfo (>= 1.0.0) + yajl-ruby (1.1.0) PLATFORMS ruby DEPENDENCIES - RedCloth (~> 4.2) - foreman (~> 0.13) - jekyll (~> 0.10) - serve (~> 1.0) - thin (~> 1.2) + foreman (~> 0.63) + github-pages + serve (~> 1.5) + tzinfo-data From fffd98eed9629cb74817e6c9bc2d1a7d906b6b20 Mon Sep 17 00:00:00 2001 From: Peter Hellberg Date: Sun, 18 Aug 2013 14:21:24 +0200 Subject: [PATCH 10/77] Now using the github-pages gem in order to better mirror the production environment. --- .ruby-gemset | 1 + .ruby-version | 1 + Procfile | 2 +- _config.yml | 2 ++ 4 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 .ruby-gemset create mode 100644 .ruby-version diff --git a/.ruby-gemset b/.ruby-gemset new file mode 100644 index 0000000..119b7fd --- /dev/null +++ b/.ruby-gemset @@ -0,0 +1 @@ +coffeescript-cookbook diff --git a/.ruby-version b/.ruby-version new file mode 100644 index 0000000..77fee73 --- /dev/null +++ b/.ruby-version @@ -0,0 +1 @@ +1.9.3 diff --git a/Procfile b/Procfile index c41ebb6..26a670a 100644 --- a/Procfile +++ b/Procfile @@ -1,2 +1,2 @@ -jekyll: bundle exec jekyll --auto +jekyll: bundle exec jekyll build --watch serve: bundle exec serve 4000 development _site diff --git a/_config.yml b/_config.yml index f61488e..fef8911 100644 --- a/_config.yml +++ b/_config.yml @@ -1,5 +1,7 @@ +safe: true pygments: true lsi: false +markdown: redcarpet exclude: - README.md - CNAME From 7ebd0275b2c5569b7a5f30723551028d8d8ea6b5 Mon Sep 17 00:00:00 2001 From: Peter Hellberg Date: Sun, 18 Aug 2013 15:13:54 +0200 Subject: [PATCH 11/77] Updated the Developer's Guide to better reflect the current workflow. --- developers-guide.md | 54 ++++++++++++++++++++------------------------- 1 file changed, 24 insertions(+), 30 deletions(-) diff --git a/developers-guide.md b/developers-guide.md index 8d8c210..909847e 100644 --- a/developers-guide.md +++ b/developers-guide.md @@ -9,7 +9,8 @@ _Please help out by updating this page_ ### Operating System -It works on Mac OSX. Probably works without any changes or issues on linux. A masochist could probably get it working on Windows. +It works on Mac OSX. Probably works without any changes or issues on Linux. +A masochist could probably get it working on Windows. ## Installation @@ -19,54 +20,47 @@ It works on Mac OSX. Probably works without any changes or issues on linux. A ma git clone git://github.com/coffeescript-cookbook/coffeescript-cookbook.github.com.git {% endhighlight %} -### Create a Ruby Gemset +### Ruby environment -Optional, but highly recommended. +You probably want to have [RVM](http://rvm.io/) installed. -{% highlight bash %} -$ rvm gemset create jekyll -$ echo 'rvm gemset use jekyll' >> .rvmrc -{% endhighlight %} - -### Install Required Gems +The project includes a `.ruby-version` file locked to +*1.9.3* since that is what Github Pages are currently using. -{% highlight bash %} -gem install jekyll # needed for testing building the site -gem install RedCloth # needed for .md rendering -gem install serve # needed for resolving .html files w/o extension -gem install thin # optional; more efficient webserver than Webrick but not strictly necessary -{% endhighlight %} +There is also a `.ruby-gemset` that is set to *coffeescript-cookbook* -### Install pygments +### Required dependencies -You'll need python installed for this. Macs and most linuces come with it preinstalled. +We are using [Bundler](http://bundler.io/) to install the required Ruby dependencies. {% highlight bash %} -easy_install pygments # for syntax highlighting +bundle install {% endhighlight %} -## Building and Viewing the Website - -### Run jekyll +#### Install pygments -Open a terminal window, cd into the project folder and run jekyll from the project root. +You'll need python installed for this. +Macs and most Linuces come with it preinstalled. {% highlight bash %} -jekyll --auto +easy_install pygments # for syntax highlighting {% endhighlight %} -Leave this window running while you work. Any time you change a file, jekyll will rerender it into the `_site` folder. - -### Run serve +## Building and Viewing the Website -Open another terminal window, cd into the project folder, then cd into the `_site` subfolder, and run +Open a terminal window, cd into the project folder and run `foreman start` from the project root. {% highlight bash %} -serve +foreman start {% endhighlight %} -This will start a webserver in the `_site` folder. Open a browser and visit `http://localhost:4000/` and you should see the site. +Leave this window running while you work. +Any time you change a file, jekyll will rerender it into the `_site` folder. + +Open a browser and visit and you should see the site. ## Minutiae and Other Trivialities -jekyll can take a second or two to catch up when you save a file. If you edit a file and don't see the changes in your browser, give it a second or two and try again. You may also see Maruku warnings, but as long as it prints `Successfully generated site` you should be alright. +Jekyll can take a second or two to catch up when you save a file. +If you edit a file and don't see the changes in your browser, give it a second or two and try again. +As long as it prints `Successfully generated site` you should be alright. From 31a0d63425aa933afd11fa3a731fba5d1b06ef77 Mon Sep 17 00:00:00 2001 From: Julien Date: Thu, 5 Sep 2013 18:24:15 +0800 Subject: [PATCH 12/77] Fix 5 typos on the Adapter design pattern page. --- chapters/design_patterns/adapter.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/chapters/design_patterns/adapter.md b/chapters/design_patterns/adapter.md index 8be4ece..2d6fc56 100644 --- a/chapters/design_patterns/adapter.md +++ b/chapters/design_patterns/adapter.md @@ -1,12 +1,12 @@ --- layout: recipe -title: Adapter patter +title: Adapter pattern chapter: Design patterns --- ## Problem Suppose we have 3-rd party grid component. We want to apply there our own custom sorting but a small problem. Our custom sorter does not implement required interface by grid component. -To understand the problem completely best example would be an socket from our usual life. Everybody knows this device. In some countries it has 3 pins and in other contries it has only 2 pins. +To understand the problem completely best example would be an socket from our usual life. Everybody knows this device. In some countries it has 3 pins and in other countries it has only 2 pins. This is exactly right situation to use [adapter pattern](https://en.wikipedia.org/wiki/Adapter_pattern). ## Solution @@ -47,5 +47,5 @@ agrid.sort() # sort data with custom sorter through adapter ## Discussion -Adapter is usefull when you have to organize an interaction between two objects with different interfaces. It can happen when you use 3-rd party libraries or you work with legacy code. -In any case be carefull with adapter: it can be helpfull but it can instigate design errors. +Adapter is useful when you have to organize an interaction between two objects with different interfaces. It can happen when you use 3-rd 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. From 68aaa998b96077340a707b5ad286e07b405fb061 Mon Sep 17 00:00:00 2001 From: Julien Date: Thu, 5 Sep 2013 18:26:21 +0800 Subject: [PATCH 13/77] Anglicize the problem statement. --- chapters/design_patterns/adapter.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/chapters/design_patterns/adapter.md b/chapters/design_patterns/adapter.md index 2d6fc56..19aaca9 100644 --- a/chapters/design_patterns/adapter.md +++ b/chapters/design_patterns/adapter.md @@ -5,9 +5,12 @@ chapter: Design patterns --- ## Problem -Suppose we have 3-rd party grid component. We want to apply there our own custom sorting but a small problem. Our custom sorter does not implement required interface by grid component. -To understand the problem completely best example would be an socket from our usual life. Everybody knows this device. In some countries it has 3 pins and in other countries it has only 2 pins. -This is exactly right situation to use [adapter pattern](https://en.wikipedia.org/wiki/Adapter_pattern). +Imagine you are traveling to a foreign country and once at your hotel room you realize your power cord is not compatible with the wall electric socket. +Luckily you remember you brought with you a socket adapter. +It will connect to the wall socket on one side and to your power cord 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](//en.wikipedia.org/wiki/Adapter_pattern) comes in handy. It will do the translation, from one side to the other. ## Solution @@ -47,5 +50,5 @@ agrid.sort() # sort data with custom sorter through adapter ## Discussion -Adapter is useful when you have to organize an interaction between two objects with different interfaces. It can happen when you use 3-rd party libraries or you work with legacy code. +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. From 2324b0344fb569798d30db10de69287554826d0a Mon Sep 17 00:00:00 2001 From: Julien Date: Thu, 5 Sep 2013 19:06:11 +0800 Subject: [PATCH 14/77] Bring CoffeeScript idiom to conditional statement. An advantage of CoffeeScript compared to JavaScript is its ability to check for array membership with the `in` keyword. A feature it borrowed from Python. --- chapters/ajax/ajax_request_without_jquery.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chapters/ajax/ajax_request_without_jquery.md b/chapters/ajax/ajax_request_without_jquery.md index 5956548..7f69c93 100644 --- a/chapters/ajax/ajax_request_without_jquery.md +++ b/chapters/ajax/ajax_request_without_jquery.md @@ -47,7 +47,7 @@ loadDataFromServer = -> req.addEventListener 'readystatechange', -> if req.readyState is 4 # ReadyState Compelte - if req.status is 200 or req.status is 304 # Success result codes + if req.status in [200, 304] # Success result codes data = eval '(' + req.responseText + ')' console.log 'data message: ', data.message else From cf2867beba00fe2cc0dbe9bf315086b4b7cd615f Mon Sep 17 00:00:00 2001 From: Julien Date: Thu, 5 Sep 2013 19:29:49 +0800 Subject: [PATCH 15/77] Amount takes only 1 'm'. --- chapters/arrays/max-array-value.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chapters/arrays/max-array-value.md b/chapters/arrays/max-array-value.md index ce3adc1..25f1472 100644 --- a/chapters/arrays/max-array-value.md +++ b/chapters/arrays/max-array-value.md @@ -26,4 +26,4 @@ Alternatively, it's possible to use ES5 `reduce` method. For backward compatibil ## 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 ammount of arguments, such as `console.log`. +`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`. From 227978f0c15f08ff7b4970cd531f8354e44496c3 Mon Sep 17 00:00:00 2001 From: Julien Date: Thu, 5 Sep 2013 21:29:53 +0800 Subject: [PATCH 16/77] Improve readability. --- chapters/ajax/ajax_request_without_jquery.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/chapters/ajax/ajax_request_without_jquery.md b/chapters/ajax/ajax_request_without_jquery.md index 7f69c93..d95713c 100644 --- a/chapters/ajax/ajax_request_without_jquery.md +++ b/chapters/ajax/ajax_request_without_jquery.md @@ -47,7 +47,8 @@ loadDataFromServer = -> req.addEventListener 'readystatechange', -> if req.readyState is 4 # ReadyState Compelte - if req.status in [200, 304] # Success result codes + successResultCodes = [200, 304] + if req.status in successResultCodes data = eval '(' + req.responseText + ')' console.log 'data message: ', data.message else From 026fd00545b36330624e6de3189ee0864ef60539 Mon Sep 17 00:00:00 2001 From: Julien Date: Sat, 7 Sep 2013 13:21:39 +0800 Subject: [PATCH 17/77] Better rephrase the problem statement. --- chapters/design_patterns/adapter.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/chapters/design_patterns/adapter.md b/chapters/design_patterns/adapter.md index 19aaca9..7e2af73 100644 --- a/chapters/design_patterns/adapter.md +++ b/chapters/design_patterns/adapter.md @@ -5,9 +5,9 @@ chapter: Design patterns --- ## Problem -Imagine you are traveling to a foreign country and once at your hotel room you realize your power cord is not compatible with the wall electric socket. -Luckily you remember you brought with you a socket adapter. -It will connect to the wall socket on one side and to your power cord on the other side, allowing for communication between them. +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](//en.wikipedia.org/wiki/Adapter_pattern) comes in handy. It will do the translation, from one side to the other. From 5f35db8957f5938c27bc9bdf3721a25af075e898 Mon Sep 17 00:00:00 2001 From: Jakob Krigovsky Date: Fri, 13 Sep 2013 19:40:39 +0200 Subject: [PATCH 18/77] =?UTF-8?q?Automatically=20update=20=E2=80=9Clast=20?= =?UTF-8?q?updated=E2=80=9D=20date?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _layouts/chapter.html | 2 +- _layouts/default.html | 2 +- _layouts/recipe.html | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/_layouts/chapter.html b/_layouts/chapter.html index b075d2c..2bfe664 100644 --- a/_layouts/chapter.html +++ b/_layouts/chapter.html @@ -55,7 +55,7 @@

{{ page.title }}

diff --git a/_layouts/default.html b/_layouts/default.html index 1f00656..b45615d 100644 --- a/_layouts/default.html +++ b/_layouts/default.html @@ -52,7 +52,7 @@

ó diff --git a/_layouts/recipe.html b/_layouts/recipe.html index d71dfba..fd6e969 100644 --- a/_layouts/recipe.html +++ b/_layouts/recipe.html @@ -54,7 +54,7 @@

{{ page.title }}

From 0776427f49975b494a218e3144be078a7ce714bf Mon Sep 17 00:00:00 2001 From: Calum Robertson Date: Thu, 19 Sep 2013 19:08:22 +0100 Subject: [PATCH 19/77] Added the Template Method Pattern. --- authors.md | 1 + chapters/design_patterns/template_method.md | 45 +++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 chapters/design_patterns/template_method.md diff --git a/authors.md b/authors.md index be4922c..7876aa2 100644 --- a/authors.md +++ b/authors.md @@ -21,6 +21,7 @@ The following people are totally rad and awesome because they have contributed r * Frederic Hemberger * Mike Hatfield *oakraven13@gmail.com* * [Anton Rissanen](http://github.com/antris) *hello@anton.fi* +* Calum Robertson *http://github.com/randusr836* * ...You! What are you waiting for? Check out the [contributing](/contributing) section and get cracking! # Developers diff --git a/chapters/design_patterns/template_method.md b/chapters/design_patterns/template_method.md new file mode 100644 index 0000000..607be35 --- /dev/null +++ b/chapters/design_patterns/template_method.md @@ -0,0 +1,45 @@ +--- +layout: recipe +title: Template Method Pattern +chapter: Design Patterns +--- +## Problem + +You need to execute a series of steps according to some algorithm or recipe and wish to provide the implementation for any of the steps. + +## Solution + +Use the Template Method to describe each step in a superclass, delegating the implementation of each step to a subclass. + +For example, imagine you wish to model 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" + +doc1 = new DocWithHeader +doc1.produceDocument() + +doc2 = new DocWithoutHeader +doc2.produceDocument() +{% endhighlight %} + +## Discussion + +In this example, there are two steps, one for producing a document header and the second for producing the document body; these two steps are given empty implementations in the superclass. The DocWithHeader implements both the body and header steps, whereas the DocWithoutHeader only impements the body step. From 198eed36fca85a819aac55ee534432d4dfcb0b9c Mon Sep 17 00:00:00 2001 From: Calum Robertson Date: Fri, 20 Sep 2013 21:39:13 +0100 Subject: [PATCH 20/77] Changes after feedback. Wrote a little about polymorphism being used in the pattern. Described in greater detail the concepts of the algorithm structure and the specification of algorithm step behaviour. --- chapters/design_patterns/template_method.md | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/chapters/design_patterns/template_method.md b/chapters/design_patterns/template_method.md index 607be35..31fe475 100644 --- a/chapters/design_patterns/template_method.md +++ b/chapters/design_patterns/template_method.md @@ -5,13 +5,13 @@ chapter: Design Patterns --- ## Problem -You need to execute a series of steps according to some algorithm or recipe and wish to provide the implementation for any of the steps. +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 each step in a superclass, delegating the implementation of each step to a subclass. +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 various types of document and each one may contain a header and a body. +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 @@ -33,13 +33,12 @@ class DocWithoutHeader extends Document produceBody: -> console.log "Producing body for DocWithoutHeader" -doc1 = new DocWithHeader -doc1.produceDocument() - -doc2 = new DocWithoutHeader -doc2.produceDocument() +docs = [new DocWithHeader, new DocWithoutHeader] +doc.produceDocument() for doc in docs {% endhighlight %} ## Discussion -In this example, there are two steps, one for producing a document header and the second for producing the document body; these two steps are given empty implementations in the superclass. The DocWithHeader implements both the body and header steps, whereas the DocWithoutHeader only impements the body step. +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. \ No newline at end of file From 2228b639d6e1b06cdb9d15b4a18aa1e971e9b0cf Mon Sep 17 00:00:00 2001 From: Devin Weaver Date: Tue, 8 Oct 2013 00:48:21 -0400 Subject: [PATCH 21/77] Changed to best practice of the `this` keyword I've seen several people on IRC talk about readability. It seems there is some opinions that when chaining like this the `this` keyword is more readable then a dangling `@` symbol. I think it is a good idea to offer code readability in this project. Feel free to revert this commit if this is disputed. (Unable to open a PR from in the Github UI). --- chapters/classes_and_objects/chaining.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/chapters/classes_and_objects/chaining.md b/chapters/classes_and_objects/chaining.md index 65f450f..be19212 100644 --- a/chapters/classes_and_objects/chaining.md +++ b/chapters/classes_and_objects/chaining.md @@ -20,13 +20,13 @@ class CoffeeCup sugar: false strength: (newStrength) -> @properties.strength = newStrength - @ + this cream: (newCream) -> @properties.cream = newCream - @ + this sugar: (newSugar) -> @properties.sugar = newSugar - @ + this morningCup = new CoffeeCup() From 5358690140a8d0a8efffe43cf3bac8ccb2857e06 Mon Sep 17 00:00:00 2001 From: Stephen Daves Date: Tue, 22 Oct 2013 23:20:23 -0600 Subject: [PATCH 22/77] Remove unneeded word --- chapters/design_patterns/singleton.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chapters/design_patterns/singleton.md b/chapters/design_patterns/singleton.md index 18bbf27..6aff70c 100644 --- a/chapters/design_patterns/singleton.md +++ b/chapters/design_patterns/singleton.md @@ -12,7 +12,7 @@ Many times you only want one, and only one, instance of a class. For example, yo 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 is 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). +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/ From 2cc50bce27bbd9f70341678c6acf3c565ed255b9 Mon Sep 17 00:00:00 2001 From: Orban Botond Date: Sun, 3 Nov 2013 15:48:40 +0200 Subject: [PATCH 23/77] FIX #95 --- chapters/arrays/testing-every-element.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chapters/arrays/testing-every-element.md b/chapters/arrays/testing-every-element.md index 5978500..4f82c2a 100644 --- a/chapters/arrays/testing-every-element.md +++ b/chapters/arrays/testing-every-element.md @@ -12,7 +12,7 @@ You want to be able to check that every element in an array meets a particular c Use Array.every (ECMAScript 5): {% highlight coffeescript %} -evens = (x for x in [1..10] by 2) +evens = (x for x in [0..10] by 2) evens.every (x)-> x % 2 == 0 # => true From 2d16a576acd38b3666737d4861aca87652ee3502 Mon Sep 17 00:00:00 2001 From: jlburkhead Date: Sun, 15 Dec 2013 04:49:15 -0500 Subject: [PATCH 24/77] add an example of generating random numbers in an arbitrary range --- chapters/math/generating-random-numbers.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/chapters/math/generating-random-numbers.md b/chapters/math/generating-random-numbers.md index f181940..afb1c5c 100644 --- a/chapters/math/generating-random-numbers.md +++ b/chapters/math/generating-random-numbers.md @@ -24,6 +24,12 @@ percentile = Math.floor(Math.random() * 100) 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 From dd4f0b9ea9a60ba4b3d31abe34f92f643074a129 Mon Sep 17 00:00:00 2001 From: jlburkhead Date: Sun, 15 Dec 2013 05:06:33 -0500 Subject: [PATCH 25/77] add recipe on exponents and logarithms --- .../working-with-exponents-and-logarithms.md | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 chapters/math/working-with-exponents-and-logarithms.md diff --git a/chapters/math/working-with-exponents-and-logarithms.md b/chapters/math/working-with-exponents-and-logarithms.md new file mode 100644 index 0000000..6891530 --- /dev/null +++ b/chapters/math/working-with-exponents-and-logarithms.md @@ -0,0 +1,37 @@ +--- +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 Netword](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math). Also refer to [Converting Radians and Degrees](/chapters/math/radians-degrees) for discussion of the various constants in the Math object. From 658abba3357ff67286019b5a376a0642be341ca3 Mon Sep 17 00:00:00 2001 From: jlburkhead Date: Sun, 15 Dec 2013 15:10:48 -0500 Subject: [PATCH 26/77] fix another typo and link to correct reference --- authors.md | 1 + chapters/math/working-with-exponents-and-logarithms.md | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/authors.md b/authors.md index 7876aa2..70bea43 100644 --- a/authors.md +++ b/authors.md @@ -22,6 +22,7 @@ The following people are totally rad and awesome because they have contributed r * 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* * ...You! What are you waiting for? Check out the [contributing](/contributing) section and get cracking! # Developers diff --git a/chapters/math/working-with-exponents-and-logarithms.md b/chapters/math/working-with-exponents-and-logarithms.md index 6891530..c8e7c49 100644 --- a/chapters/math/working-with-exponents-and-logarithms.md +++ b/chapters/math/working-with-exponents-and-logarithms.md @@ -34,4 +34,4 @@ Math.log(100) / Math.log(10) ## Discussion -For more information on the Math object see the documentation on the [Mozilla Developer Netword](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math). Also refer to [Converting Radians and Degrees](/chapters/math/radians-degrees) for discussion of the various constants in the Math object. +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](/chapters/math/constants) for discussion of the various constants in the Math object. From 3ff4351575f1dd89e9689a8b78ab7710a0e44961 Mon Sep 17 00:00:00 2001 From: Ayush Gupta Date: Tue, 18 Mar 2014 17:20:15 +0530 Subject: [PATCH 27/77] updated string interpolation to mention that it works only with double quoted strings --- chapters/strings/interpolation.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/chapters/strings/interpolation.md b/chapters/strings/interpolation.md index b1e1e9e..a437be4 100644 --- a/chapters/strings/interpolation.md +++ b/chapters/strings/interpolation.md @@ -11,7 +11,8 @@ CoffeeScript Variable. ## Solution Use CoffeeScript's ruby-like string interpolation instead of -JavaScript's string addition. +JavaScript's string addition. You must use Double-quoted strings to +allow for interpolation. Single-quoted strings are treated as literals. Interpolation: From dc70747b1a4e8679f975b424311ed9ea08943412 Mon Sep 17 00:00:00 2001 From: Marc Bodmer Date: Sat, 29 Mar 2014 16:43:43 -0400 Subject: [PATCH 28/77] Remove completed recipes for wanted recipes documentation --- wanted-recipes.md | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/wanted-recipes.md b/wanted-recipes.md index 64eec51..5adc15d 100644 --- a/wanted-recipes.md +++ b/wanted-recipes.md @@ -8,16 +8,10 @@ Here's a list of recipes we think we need. Pick one, implement it, and remove it In the notes below, "JS" means the recipe is just a simple passthrough to an existing JavaScript method. -## Introduction - -We need a better introduction. Right now the first recipe is [Embedding JavaScript](/chapters/syntax/embedding_javascript), which doesn't set the right first impression. How about three or four recipes that hold new users' hands a bit more as the first section? - ## Syntax * Ensuring variables are closed over # with "do" -## Objects - ## Strings * HTML methods # JS .sup(), .sub(), .blink(), .link(url), etc. May not exist in your JS impl! @@ -45,10 +39,6 @@ evens.every even [1..10].some (x) -> x % 2 == 0 # => true {% endhighlight %} -## Dates and Times - -* Empty - ## Math * square root # JS Math.sqrt @@ -89,24 +79,11 @@ foo 1, 2, 3 # => 6 {% endhighlight %} -## jQuery - -## Regular Expressions - -## Networking - -* Streaming HTTP server -* Streaming HTTP client - -## AJAX - -* Getting data from a remote server # using raw XHTTPRequest instead of jQuery's `$.ajax` - ## Design patterns * Creational Patterns * Abstract Factory - * Prototype + * Prototype * Structural Patterns * Adapter From 6fe6cce0b1776795f516415fced927fab29e2c8a Mon Sep 17 00:00:00 2001 From: Simon Taranto Date: Wed, 2 Apr 2014 10:42:38 -0700 Subject: [PATCH 29/77] Remove duplicate words --- chapters/regular_expressions/searching-for-substrings.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chapters/regular_expressions/searching-for-substrings.md b/chapters/regular_expressions/searching-for-substrings.md index 1928591..888c774 100644 --- a/chapters/regular_expressions/searching-for-substrings.md +++ b/chapters/regular_expressions/searching-for-substrings.md @@ -23,7 +23,7 @@ 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 an array with the match information or `null`: +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" From 552577922c2209b10ae250926ceb71eb5a4eeb4d Mon Sep 17 00:00:00 2001 From: rdubigny Date: Sat, 5 Apr 2014 17:17:15 +0200 Subject: [PATCH 30/77] Change folder name "tests" -> "test" I just lost one hour because of that. --- chapters/testing/testing_with_nodeunit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chapters/testing/testing_with_nodeunit.md b/chapters/testing/testing_with_nodeunit.md index 30af5b8..ec610d2 100644 --- a/chapters/testing/testing_with_nodeunit.md +++ b/chapters/testing/testing_with_nodeunit.md @@ -17,7 +17,7 @@ For example, we expect our calculator will be able to add and subtract and will {% highlight coffeescript %} -# tests/calculator.test.coffee +# test/calculator.test.coffee Calculator = require '../calculator' From 91e7d3eb8a49a124896fc3101cd4bd0195928e61 Mon Sep 17 00:00:00 2001 From: Joseph Chiocchi Date: Mon, 7 Apr 2014 17:08:07 -0500 Subject: [PATCH 31/77] fix typo on testing-every-element.md --- chapters/arrays/testing-every-element.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chapters/arrays/testing-every-element.md b/chapters/arrays/testing-every-element.md index 4f82c2a..12b78a1 100644 --- a/chapters/arrays/testing-every-element.md +++ b/chapters/arrays/testing-every-element.md @@ -20,7 +20,7 @@ evens.every (x)-> x % 2 == 0 Array.every was addded 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, prentend you have a multiple select list that looks like: +For a real world example, pretend you have a multiple select list that looks like: {% highlight html %}