io scope #1

今回は jsxについて ではなく、iolanguage の block と scope まわりについて少し

javascript の closure ってとても可読性が高くて、よくあるサンプルならこんな感じ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var createCounter = function (){
  var count = 0;
  return function (){
    return count++;
  };
};

var a = createCounter();
console.log(a()); // => 0
console.log(a()); // => 1

var b = createCounter();
console.log(b()); // => 0
console.log(b()); // => 1

んで、これを io でやろうとする場合、そのままやるならこんな実装になる

1
2
3
4
5
6
7
8
createCounter := method (
  count := 0;
  block ( count = count + 1 )
)

a := createCounter
a call println => 1
a call println => 2

と、method や block が入り組んだ、とても気持ち悪いコードになってしまう。
ただ、これはなんてことはない、javascriptのブロックがfunctionになっているから、綺麗なコードに見えるだけだ!(とかいう)
ちなみに、このコードを下記のように method だけにすると、スコープの参照が出来なくなってしまう

1
2
3
4
5
6
7
createCounter := method (
  count := 0;
  method ( count = count + 1 )
)

b := createCounter
b println => Exception: Object does not respond to 'count'

つまり、method は内包的なブロックを参照できないけど block は参照できる。と
んで、これを使うと interpolate がひと味違ってくる

1
2
3
4
a := block(a, b, c,
  "hello #{a} #{b + c}" interpolate
)
a call("hello world", 1, 2) // => hello hello world 3

interpolate は通常こんな使い方になってしまうんだけど、block はスコープを参照してるのがいいね

1
2
3
4
5
obj := Object clone
obj a := "hello world"
obj b := 1
obj c := 2
"hello #{a} #{b + c}" interpolate(obj) // hello hello world 3

さて、何を書こうと思ってたか忘れてしまった。。。
block とかその辺りは次回へ続く。。。