74
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

updated at

Organization

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

Cookbookがあった。
CoffeeScript Cookbook

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

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

スルーしてるやつ

  • 公式ドキュメントに載ってる基本的なものはだいたいスルー
  • あと変態ぽいやつ(例えば「Repeating a String」)もスルー。(直感的でない)
  • 単純なjsのtipsもスルー (Recursive Functions)

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

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

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

ディープコピー

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

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

とあるが、ES5。IE8を含めるならunderscore.jsなどで吸収しないといけない。(EcmaScriptの各ブラウザ対応状況)

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

↓Mapの代用。

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

Splat Arguments

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

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 (複数行で書ける正規表現)

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

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


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はどうでもよくて、クロージャの書き方がいい感じ。

# 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 (プライベート変数とプライベートクラス)

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

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

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


なにしてるのかわかんないやつらは置いといて、いい感じの書き方を覚えたら、スタバでCoffeeでも飲んでレッツ!ドヤリング!

ドヤリング

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
74
Help us understand the problem. What are the problem?