CoffeeScript 1.7.1が出てた

変更点を適当にまとめてみた


pull#3279

.jsから.coffeeをrequireする時は、require('coffee-script')じゃなくて、require('coffee-script/register')を利用するようになった

a.js

require('coffee-script/register');
require('./cs-sample');

cs-sample.coffee

console.log 'require success!'

pull#3031 pull#2968

ソースマップとスタックトレースで表示されるエラーメッセージが改善された。 ソースマップは最新の記法(//#方式)にアップデートされた。

a.js

require('coffee-script'); // require('coffee-script/register');
require('./b');

b.coffee

(-> b())()

Error @1.6.3

/path/to/b.coffee:3
    return b();
           ^
ReferenceError: b is not defined
    at /path/to/b.coffee:3:12
    at Object.<anonymous> (/path/to/b.coffee:4:5)
    at Object.<anonymous> (/path/to/b.coffee:6:4)
    at Module._compile (module.js:456:26)
    at Object.loadFile (/path/to/node_modules/coffee-script/lib/coffee-script/coffee-script.js:182:19)
    at Module.load (/path/to/node_modules/coffee-script/lib/coffee-script/coffee-script.js:211:36)
    at Function.Module._load (module.js:312:12)
    at Module.require (module.js:364:17)
    at require (module.js:380:17)
    at Object.<anonymous> (/path/to/a.js:2:1)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)
    at node.js:902:3

Error @1.7.1

/path/to/b.coffee:3
    return b();
           ^
ReferenceError: b is not defined
  at /path/to/b.coffee:1:5
  at Object.<anonymous> (/path/to/b.coffee:1:1)
  at Object.<anonymous> (/path/to/b.coffee:1:1)
  at Module._compile (module.js:456:26)
  at Object.loadFile (/path/to/node_modules/coffee-script/lib/coffee-script/register.js:16:19)
  at Module.load (/path/to/node_modules/coffee-script/lib/coffee-script/register.js:45:36)
  at Function.Module._load (module.js:312:12)
  at Module.require (module.js:364:17)
  at require (module.js:380:17)
  at Object.<anonymous> (/path/to/a.js:2:1)
  at Module._compile (module.js:456:26)
  at Object.Module._extensions..js (module.js:474:10)
  at Module.load (module.js:356:32)
  at Function.Module._load (module.js:312:12)
  at Function.Module.runMain (module.js:497:10)
  at startup (node.js:119:16)
  at node.js:902:3

pull#3263

.で始まる行は現在解釈中のファンクションコールを閉じる。 これまで記法の制約上避けられやすかったメソッドチェインが書き易くなる。

sample.coffee

$ 'body'
.click (e) ->
  $ '.box'
  .fadeIn 'fast'
  .addClass '.active'
.css 'background', 'white'

これまでは上記記法だと、.click()'body'というStringにかかると解釈されてきた。 これが正しく解釈されるようになった。

sample.js @1.6.3

$('body'.click(function(e) {
  return $('.box'.fadeIn('fast'.addClass('.active')));
}).css('background', 'white'));

sample.js @1.7.1

$('body').click(function(e) {
  return $('.box').fadeIn('fast').addClass('.active');
}).css('background', 'white');

pull#2026

演算子が追加された

  • a ** b => Math.pow a, b
  • a // b => Math.floor a / b
  • a %% b => (a % b + b) % b

issue#3229 pull#3246

ヒアドキュメント(''', """)でない途中に改行のある文字列は、インデントを無視し、単独のホワイトスペース区切りで結合するようになった。ホワイトスペースを入れたくない際は行末にバックスラッシュを入れる必要がある

sample.coffee

console.log "Hello world.
             This is a long line of text
             that I'd like split in my code."

console.log "http://github.com/jashkenas/coffee-script/blob/master/src/
lexer.coffee#L126"

console.log "http://github.com/jashkenas/coffee-script/blob/master/src/\
lexer.coffee#L126"

sample.js @1.6.3

console.log("Hello world.             This is a long line of text             that I'd like split in my code.");

console.log("http://github.com/jashkenas/coffee-script/blob/master/src/lexer.coffee#L126");   

console.log("http://github.com/jashkenas/coffee-script/blob/master/src/\lexer.coffee#L126");   

sample.js @1.7.1

console.log("Hello world. This is a long line of text that I'd like split in my code.");

console.log("http://github.com/jashkenas/coffee-script/blob/master/src/ lexer.coffee#L126");   

console.log("http://github.com/jashkenas/coffee-script/blob/master/src/lexer.coffee#L126");

issue#3264

ヒアドキュメントにおけるinterpolation(#{variable})は正しく処理されるようになった

sample.coffee

console.log """

a
"""

console.log """

#{a}
"""

sample.js @1.6.3

console.log("\na");

console.log("" + a);

sample.js @1.7.1

console.log("\na");

console.log("\n" + a);

pull#3320

閉じ括弧(},],))についてのインデント処理が入った、スコープをインデントベースで正しく処理するようになった

sample.coffee

($ document)
  .on 'click', (e) ->
    ($ '.xyz').click( ->
      false
     )
    false

sample.js @1.6.3

($(document)).on('click', function(e) {
  return ($('.xyz')).click(function() {
    return false;
  });
});

false;

sample.js @1.7.1

($(document)).on('click', function(e) {
  ($('.xyz')).click(function() {
    return false;
  });
  return false;
});

pull#2954

コール不可能なリテラルを引数にとるオペレータコールにはコンパイラエラーを吐くようになった

sample.coffee

do 'hoge'

sample.js @1.6.3

'hoge'();

Error @1.7.1

sample.coffee:1:4: error: literal is not a function
do 'hoge'
   ^^^^^^

pull#3211

連続した条件文を解釈する際、一時的に確保された変数は使用され続ける。冪等でないコールでも同一条件下で動作するようになった。

sample.coffee

x = foo().bar ?= baz

sample.js @1.6.3

x = (_base = foo()).bar != null ? (_base = foo()).bar : _base.bar = baz;

sample.js @1.7.1

x = (_base = foo()).bar != null ? _base.bar : _base.bar = baz;

issue#3056 pull#3284

連続した条件文は正しく解釈されるようになった。

sample.coffee

console.log "hello" unless true if false

sample.js @1.6.3

if (!(false ? true : void 0)) {
  console.log("hello");
}

sample.js @1.7.1

if (false) {
  if (!true) {
    console.log("hello");
  }
}

pull#3132

ブロックコメントを正しくフォーマットするようになった

sample.coffee

###
# block comment
###

###
block comment
###

sample.js @1.6.3

/*
# block comment
*/

/*
block comment
*/

sample.js @1.7.1

/*
 * block comment
 */

/*
block comment
 */

issue#3089

CoffeeScriptのコンパイラへ渡されたオプションは、変化しないようになった

shでプログレスバーを出す

echo '\c'を使う

PROGRESS() {                                                                                
  PRG=`echo "$1 * 100 / $2" | bc` 
  CUR=`echo "$MAX * $PRG / 100" | bc -l | cut -d'.' -f1` 
  STR='[' 
  for i in `seq 1 $MAX`; do 
    if [[ $i -le $CUR ]]; then STR="$STR="; else STR="$STR "; fi 
  done 
  echo "$STR] $PRG%\r\c" >&2 
}

release reference in reference

久しぶりにjsの闇を思い知らされた

オブジェクトを作る

coffee> a = t: [1, 2, 3], r: 'foo'

参照を解除する、ここではutil._extendを使った

coffee> b = util._extend {}, a

書き換えてみる

coffee> a.r
'foo'
coffee> b.r = 'bar'
coffee> a
{ t: [ 1, 2, 3 ],
  r: 'foo' }
coffee> b
{ t: [ 1, 2, 3 ],
  r: 'bar' }

オブジェクトの参照は解除されている、ここまではいい

tキーの配列の値を直接書き換えてみる

coffee> a.t[0] = 4
coffee> a
{ t: [ 4, 2, 3 ],
  r: 'foo' }
coffee> b
{ t: [ 4, 2, 3 ],
  r: 'bar' }

٩(ˊᗜˋ*)و つらい

参照型の中であれ、参照型は参照型であり参照されている

これに気づかず30分くらいロストした、ともすれば忘れてしまいがちなので次から気をつける