CoffeeScript Cookbookのおいしいところだけ抜き出して、おいしい思いをしよう！！


Cookbookがあった。
[CoffeeScript Cookbook](http://coffeescriptcookbook.com/)


Cookbookとは「諸々の問題を華麗に解決しよう！」というレシピ本みたいなの。CoffeeScriptの特徴というより、単なるプログラムの書き方の寄せ集めみたいなノリでもある。

なので、CoffeeScriptの特徴を捉えてるやつをピックアップして見てみよう！


## スルーしてるやつ
* 公式ドキュメントに載ってる基本的なものはだいたいスルー
* あと変態ぽいやつ(例えば「[Repeating a String](http://coffeescriptcookbook.com/chapters/strings/repeating)」)もスルー。(直感的でない)
* 単純なjsのtipsもスルー  ([Recursive Functions](http://coffeescriptcookbook.com/chapters/functions/recursion))


## スタティックなメソッドを使おう

http://coffeescriptcookbook.com/chapters/classes_and_objects/class-methods-and-instance-methods

なぜか公式に書いてない、staticなやりかた。
classのメソッド、プロパティに@をつけるとOK。

``` 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) ->
    Songs._titles++
```


## ディープコピー
http://coffeescriptcookbook.com/chapters/classes_and_objects/cloning

ガチでディープコピーするとき。

``` 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
```

ちなみにJSONのクローンは

	JSON.parse(JSON.stringify(object))

で強引にクローンできる。



## ES5を使った配列のmap, every, select
* [Testing Every Element](http://coffeescriptcookbook.com/chapters/arrays/testing-every-element)
* [Mapping Arrays](http://coffeescriptcookbook.com/chapters/arrays/mapping-arrays)

とあるが、ES5。IE8を含めるならunderscore.jsなどで吸収しないといけない。([EcmaScriptの各ブラウザ対応状況](http://kangax.github.io/es5-compat-table/))

ちなみにCoffeeScriptだと、配列処理はわりと楽に書ける。ので、ES5使わなくていいかもね。

↓Mapの代用。

``` coffeescript
list = [1, 2, 3]
double = (value *= 2 for value in list) #[2,4,6]

```


## Splat Arguments

http://coffeescriptcookbook.com/chapters/functions/splat_arguments

引数の間にargs...的なやつを仕込める

``` 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 }
```

## jQueryのコンフリクトしないrequire

	$ ?= require 'jquery' # For Node.js compatibility
	
## Using Heregexes (複数行で書ける正規表現)
http://coffeescriptcookbook.com/chapters/regular_expressions/heregexes

CoffeeScriptにはいい感じのがあるとか。コメントやwhitespaceを含めながら複雑な正規表現を書ける。

heredocumentっぽいからheregexesという名前なのかな。

```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']
```



## closureの書き方 (Command Patternにて)
Command Patternのページに書いてあるけど、Command Patternはどうでもよくて、クロージャの書き方がいい感じ。

```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

```

## Singleton (プライベート変数とプライベートクラス)

http://coffeescriptcookbook.com/chapters/design_patterns/singleton

Private Classが使える。もちろん、外からは見えず、アクセスしようとしても`undefined`になる。

classのなかで `@classVar: 'hoge`や `instanceVar: hoge` などといった書き方ではなく、`privateVar = 'hoge'`と書くことで、**外に見えないプライベート変数**を作っている。


``` 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

```






-----
# なにしてるのかわかんないやつ
CoffeeScript Cookbook » Check if type of value is an Array
http://coffeescriptcookbook.com/chapters/arrays/check-type-is-array



* なんか高度なやつ
	* [Debounce Functions](http://coffeescriptcookbook.com/chapters/functions/debounce)
* 頭がおかしくなりそうな文
	* [Detecting and Creating Missing Functions](http://coffeescriptcookbook.com/chapters/metaprogramming/detecting-and-replacing-functions)
	



----
##なにしてるのかわかんないやつらは置いといて、いい感じの書き方を覚えたら、スタバでCoffeeでも飲んでレッツ！ドヤリング！
![ドヤリング](http://i.imgur.com/APJWF.jpg)