変数のread hook

今は、プログラムを作っている場合じゃないくらい忙しい(でもblogを書くくらいのゆとりが今日はあるので)のですが、思いついたのでメモ。

何か?

変数のread hook。対象はRuby 1.9.x

詳細はこんな感じ

  • 変数を参照するとき、登録したブロックが呼ばれる
  • 変数はローカル変数、ブロック変数、クラス変数、インスタンス変数、グローバル変数なんでも対象
  • メソッドはその変数の値を引数にとって、実際に参照したい値を返す。
  • メソッドの返値に変数が設定され、あたかもメソッドの返値が変数の値だったかのように振舞う
  • 登録したメソッド内では変数のHookは効かない

例えば、こんな感じで使います。

  VariableHook::set_hook do |val|
       val * 2
   end

   a = 1
   p a      # 2が表示される、aは2が設定されている。
  b = nil
   p b      # 多分、フックブロック内でエラーが起こる

こんなもん何に使うのか?

将来、RubyでTimeWarpアルゴリズムなどの楽観的ロックを使った分散システムをRubyで作りたいなと思っています。そのとき、変数の衝突の検出と、ロールバックをこんな感じのフックを使って、ユーザからは詳細を見せずに実現できるんじゃないかなと思っています。

実現方法

 Ruby 1.9.0では変数を参照するにはget***というバイトコード(getlocal, getglobalなど)を使っています。これにフックをかけて、登録したメソッドを呼び出して、その値を変数に設定するようにバイトコードのパッチを当てれば実現できるんじゃないかなと思います。

追記
ちょっと考えたら、ロールバックするためには変数の値だけじゃなくてプログラムカウンタも戻す必要がありました。これをバイトコードで実現するのは難しそうです。毎回、継続を生成すれば可能ですが・・・