2012年9月11日火曜日

coffeescriptを好きな8つの理由と4つのトピック

このエントリーをはてなブックマークに追加

はじめに

エンジニアの@ryooo321です。
賛否両論ありますが、私はcoffeescriptには良い印象を持っており、積極的に使っています。
今回は私がcoffeescriptを好きな理由と、Source map、livescriptなどの周辺のトピックについても紹介できればと思います。

目次

・coffeescriptを好きな8つの理由
・4つのトピック
 -> Source mapでcoffeescriptのコードのままデバッグ
 -> 実行速度は早くはならない
 -> haskell風に書けるcoffeescript派生LiveScript
 -> ブラウザ実行


どんな方にcoffeescriptを薦めるのか

coffeescriptを採用するかはメンバーのスキルやプロジェクトの風土などによりケースバイケースだと思っています。
javascriptで満足しているなら、やらなくてよいと思います。
javascriptの下記の点に不満があるなら、coffeescriptを採用するメリットがあると思います。
・javascriptの文法や特性に精通していないメンバーがいる。
・javascriptのコーディング方法がメンバー間で揃わない。
・大規模なプログラム群をjavascriptで書いている。
・javascriptを書いていて楽しくない。


coffeescriptを好きな8つの理由

その1. 学習コストが少ない

javascriptとpythonかrubyを書ける方であれば、かなり簡単に習得できます。
(恐らく1時間もかからずざっと書けるようになるかと。)

その2. javascriptの罠を勝手に回避

coffeescriptで書くだけで、下記のようにjavascriptの罠を回避できます。
・varのつけ忘れによるグローバル変数定義は、意図しなければ起きない
・定義箇所によっては意図しない挙動を引き起こす、関数・変数定義のホイスティングを回避
・挙動が曖昧な弱い等価比較(==)は、厳密な等価比較に変換(===)
・ブラウザ間で挙動が変わるjavascript予約語を、自動でエスケープ
・文末セミコロンの省略やオブジェクト末尾カンマによるエラーを回避

その3. 出力するjsがとにかく綺麗

コンパイルで出力されるjavascriptはかなり綺麗で、そのままjavascriptで運用してもよいくらいです。
関数や変数の名前はそのまま出力されます。
単行のコメントはコンパイル時に削除され、ブロックコメントは残ります。
綺麗なので、coffeescriptがもしもオワコンとなっても、javascriptファイルだけで十分運用できるレベルです。

その4. 定型句が楽に書ける

class、継承、for文、デフォルト引数、可変長引数、変数バリデーションなど
javascriptでよく使われる定型句が、coffeescriptのシンタックス表現で楽に使えます。
coffeescript自体がjavascriptのスニペット群であるかのように、綺麗で素直なjavascriptに変換してくれます。
※ ステップ数はjavascriptの1/3などとも言われますが、実用上ではそんなに減ったことはありません。
私の場合ではせいぜい30%減ってところです。

その5. 楽しく書ける

インデントによる表現など無駄を省いたコーディングスタイルで、とにかくタイピングが楽です。
後置のif文
list.push(item) if item.price is 0
   ↓↓↓変換後↓↓↓
if (item.price === 0) list.push(item);


?による存在演算子
price = list["price"] ? 100
   ↓↓↓変換後↓↓↓
price = (_ref = list["price"]) != null ? _ref : 100;

関数のdefinedも確認できます。
# listが定義済みかつpush()が実装済みならitemをpushする
list?.push? item
   ↓↓↓変換後↓↓↓
if (typeof list !== "undefined" && list !== null) {
  if (typeof list.push === "function") list.push(item);
}


ファットアロー(=>)による実行コンテキストの固定化
javascriptでは関数のthisは実行コンテキストを指し示すので、「var self = this;」などと書いて関数の中ではselfを用いるのですが、coffeescriptでは簡単に回避します。
# 実行コンテキストに関わらずfunc内でのthisが常に自分自身のオブジェクトを指すように定義
class Hoge
  func: (name)=>
    this.name = name
   ↓↓↓変換後↓↓↓
var Hoge,
  __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };

Hoge = (function() {

  Hoge.name = 'Hoge';

  function Hoge() {
    this.func = __bind(this.func, this);

  }

  Hoge.prototype.func = function(name) {
    return this.name = name;
  };

  return Hoge;

})();

その6. コンパイラをほとんど意識しないでよい

コンパイラの動きが直感的で、コーディング中ほとんど意識せず作業できます。
ファイルの変更を監視して自動でコンパイルするコマンドがあるので、編集後すぐにブラウザで確認できます。
coffee -wc hoge.coffee
また、Javascript Lintでの構文チェック(-l)や複数ファイルのjoin(-j)も自動でできます。
ブラウザではjavascriptでデバッグすることになりますが、数千行程度のコードでも特に迷ったことはありません。

その7. レビューしやすい

javascriptの気をつけるべきポイントの多くをケアしてくれるので、レビュアーのチェックポイントはロジックを中心に集中できる。
ロジック以外のお作法的なコードが少ないので、理解しやすい。

その8. javascriptライブラリの選択肢が広がる

node.js界隈を中心に多くのライブラリがcoffeescriptで書かれています。
coffeescriptを学ぶことで間口が広がるかと思います。


4つのトピック

その1. Source mapsでcoffeescriptのコードのままデバッグ

概要(CoffeeScriptRedux)(いまいち)
私は特にjavascriptでしかデバッグできない現状に不満はないのですが、Source mapという仕組みでcoffeescriptのコードでデバッグが可能です。
Source mapはChromeのデベロッパーツールの右下の設定から「Enable source maps」をonにすることで利用できます。

こちらを使うとステップ実行やブレークポイントもcoffeescriptのまま実行できます。

※ 公式のcoffeescriptでは現在未対応ですが、CoffeeScriptReduxというコンパイラで対応済みですので今回はこちらのコンパイラを使います。
※ 現時点でCoffeeScriptReduxは複雑なCoffeeScriptファイルをコンパイルできませんでした。(条件未調査ですが平易なコードならコンパイルできましたというレベルです。)

CoffeeScript Source Maps
https://github.com/michaelficarra/CoffeeScriptRedux

仕組み
coffeescriptファイル(.coffee)とjsファイル(.js)と、さらにマッピングファイル(.js.map)を用意することでcoffeescriptソースでデバッグできます。
ブラウザで読み込むファイルはこれまで同様jsです。
jsの最下部に「//@ sourceMappingURL=app.js.map」とmapファイルへのjsからの相対パスを記載します。
mapファイルは、CoffeeScriptReduxのcoffeeコマンドに--source-mapオプションをつけることで出力できます。
git clone git://github.com/michaelficarra/CoffeeScriptRedux.git
cd CoffeeScriptRedux
make deps
make test

npm install source-map
# jsの階層でコマンドを実行しなければ正しいファイルが生成されません。
cd jsの階層へ
./../CoffeeScriptRedux/bin/coffee --js -i app.coffee > app.js
./../CoffeeScriptRedux/bin/coffee --source-map -i app.coffee > app.js.map
(echo; echo '//@ sourceMappingURL=app.js.map') >> app.js


その2. 実行速度は早くはならない

coffeescriptはjavascriptに1対1で変換される設計になっています。
そのため、javascript以上に早くはなれません。
超えることはできませんが、無駄のない高速なコードに変換してくれます。
比してjsxでは人の手では難しいレベルまで関数のインライン展開などの最適化を行ってくれるため、高速化されるとのことです。

jsxについてはこちら
http://jsx.github.com/


その3. haskell風に書けるcoffeescript派生LiveScript

coffeescriptからforkされたCocoからさらに派生したLiveScriptはhaskell風に書けるようです。
本家
http://gkz.github.com/LiveScript/
こちらのブログで紹介されています
http://d.hatena.ne.jp/mizchi/20120706/1341568588

その4. ブラウザ実行

基本的にはサーバーサイドでコンパイルして、jsをブラウザで読み込むのですが、「coffee-script.js」を読み込むことで、ブラウザ側でコンパイルできます。




関連情報

・CoffeeScript
http://coffeescript.org/
ブラウザ上で実行できる環境と小さなチュートリアル集があります。
ここを一読すれば一通り理解できるかと思います。

・jsx
http://jsx.github.com/

・LiveScript
http://gkz.github.com/LiveScript/
http://d.hatena.ne.jp/mizchi/20120706/1341568588



一緒に働きたい方、絶賛 募集中

京都で開発してみたいというエンジニアの皆さん、ご応募お待ちしています!
技術力を伸ばしたい学生さん、アルバイトも可能なのでご応募お待ちしています!
大阪、滋賀、神戸から通勤実績あり

1 件のコメント:

  1. đồng tâm
    game mu
    cho thuê nhà trọ
    cho thuê phòng trọ
    nhac san cuc manh
    số điện thoại tư vấn pháp luật miễn phí
    văn phòng luật
    tổng đài tư vấn pháp luật
    dịch vụ thành lập công ty trọn gói
    lý thuyết trò chơi
    đức phật và nàng
    hồ sơ mật dinh độc lập
    đừng hoang tưởng về biển lớn
    chiến thắng trò chơi cuộc sống
    lượng tử
    ngồi khóc trên cây
    truy tìm ký ức
    mặt dày tâm đen
    thế giới như tôi thấy

    “Trương Các Lão ta hỏi ngươi, ngươi biết bao nhiêu về Lưu Phong, quan viên Giang Nam phản ứng như thế nào về hắn, hắn căn bản là một dạng háo sắc, hoa hoa công tử, mặc dù có chút tài nhỏ, nhưng cũng chưa đủ trọng trách ở Hộ Bộ……”. Đôi lông mày của Hình Văn Danh rung động, miệng có chút run run. Vốn dĩ hắn phản đối việc Lưu Phong tiến kinh, kết quả đến bây giờ người ta chẳng những được vào kinh mà còn lại được địa vị cao trong Hộ Bộ.
    “Hai vị khanh gia, không nên tranh cãi nữa, để trẫm suy nghĩ chút.” Hoa Ha đại đế hơi nhức đầu. Không nghĩ tới việc điều động một Lưu Phong bé nhỏ lại gây kích động đến vậy. Phản ứng trên triều đường hắn cũng có lường trước. Bất quá từ đây hắn cũng thấy được mâu thuẫn sâu sắc giữa Lưu Phong cùng Hoàng Thái Tôn và Yến Vương. Càng như vậy thì Hoa Hạ đại đế càng kì vọng vào việc Lưu Phong mau tiến kinh nhậm chức. Kỳ thật việc Lưu Phong tiến kinh trước khi Trương Thiên Sư bị ngộ hại, hai người có thương nghị qua. Ai ngờ chuyện đang dang dở thì Trương Thiên Sư bị trúng độc thủ. Hoa Hạ đại đế mong chờ việc Lưu Phong tiến kinh nhằm giải quyết 2 vấn đề, thứ nhất chính là việc Trương Thiên Sư bị hại. Thứ hai chính là vấn đề của Hộ Bộ. Viễn chinh Phù Tang và Cao Lệ thì cần phải có kinh phí lớn, nhưng bây giờ ngay cả một nửa lực lượng vũ trang cũng truy không ra. Nếu không điều chỉnh thì thiệt hại thật to lớn. Hoa Hạ đại đế thật sự không dám tưởng tượng ra hậu quả.
    “Bệ hạ, thần có việc khải tấu”. Trương Tử Ngưu hiểu rằng lúc này cần phối hợp với bệ hạ để giải quyết triệt để vấn đề của Lưu Phong. Kinh nghiệm nhiều năm làm quan mách bảo hắn, bệ hạ đối với Lưu Phong rất trọng thị.
    Thấy vậy, sắc mặt bệ hạ nhanh chóng phẳng lặng như nước, đứng dậy:
    “Các Lão cứ nói đi!”. Hoa Hạ đại đế âm thầm tán thưởng Trương Tử Ngưu

    返信削除