Opalでクロージャは使えるのか

DxOpalの実験も一段落したので、本格的に開発に取りかかるその前に少しコードを綺麗に整理しておきたい。
まず気になるのはインスタンス変数(メンバ変数)の多さである。

これだけ多いと結構汚く見える。しかしまだ巨大なクラスって言うほど肥大化している訳ではないはず。原因は更新メソッドが毎フレーム毎に呼ばれる仕組みになっているからである。次のフレームまで変数が消えないようにしなければならないのだ。
こういう場合fiber(コルーチン)を使うとスマートな処理を実現できるのだが、困ったことにOpalにfiberは実装されてないようなのだ。
しかたないので代替としてクロージャを使ってなんとかならないか試してみる。「クロージャとは?」あえて誤解を招く表現をすると「関数を抜けてもローカル変数の値を維持できる仕組み」なのだ!どーん。
まずは従来のインスタンス変数版の例

class Player
  def initialize
    @n = 0
  end

  def update
    @n += 1
  end
end

a = Player.new
a.update # => 1
a.update # => 2

これのupdateメソッドのみクロージャに書き換えると

class Player
  def update
    (@f ||= run).()
  end

  def run
    n = 0
    -> {
      n += 1
    }
  end
end

a = Player.new
a.update # => 1
a.update # => 2

こうなる。updateが呼ばれてもnの値が維持されているのがわかる。
javascriptに変換されたコードも上手くクロージャ化されているようである。
これで処理の流れがよりシーケンシャルになり見通しか良くなることを期待してみる。

0