読者です 読者をやめる 読者になる 読者になる

レガシーコード生産ガイド

私に教えられることなら

Pharoでクロージャ

Pharo3.0のメソッド、ブロックで普通にクロージャが利用できるみたいなので使ってみる。

Sketchオブジェクトを作って、クラスサイドにメソッドを追加

counter
    | i |
    i := 0.
    ^ [ i := i + 1. i ] .
c := Sketch counter.
c value. "print it の度に数字が増えていく"

d := Sketch counter.
d value. "cとは独立"

素直に使えるみたいだ。

メソッド変数ではなくブロック内の変数でもできる。

counterFromBlock
    ^ [ | i | i := 0 . [ i := i + 1. i ] ] value.
c := Sketch counterFromBlock .
c value.

同じ様に使える。

しかし引数としての?ブロック変数にするとうまくいかなかった。

counterFromBlock: n
    ^ [ :i | [ i := i + 1. i ] ] value: n.
c := Sketch counterFromBlock: 10 .
c value. "エラー"

c.をprint itすると普通に[ i := i + 1. i ]のブロックが出てくるので、どうも:iが保持されてないみたいだ。i := i + 1.のところで+のレシーバがnullだと言われる。

その後調べてみると、次の書き方で行けることがわかった。

counterFromBlock: n
    ^ [ :x |
        | i |
        i := x. 
        [ i := i + 1. i ].
    ] value: n.

引数とローカル変数別名にしないといけないのがちょっと面倒かな。 ただ、せっかくSmalltalkなんだからブロックとクロージャバンバン使うんじゃなくて、オブジェクトでやるべきなんだろう。

広告を非表示にする