ちょっと必要に駆られて、
Wormhole
というライブラリを書きました。

350px-Worm3.jpg

インストールはGitHubから行えます。

pre>>
sudo gem sources -a http://gems.github.com
sudo gem install genki-wormhole
<<--

メソッドの内部を実行中に、呼び出し元に一旦処理を戻し、
中断した場所から処理を継続する機能を提供します。

例えば、以下のようなプログラムに対して、

ruby>>
require 'rubygems'
require 'wormhole'

def foo
puts "foo"
Wormhole.throw :foo => 'hello' do |data|
puts data[:foo]
end
puts "bar"
end

Wormhole.catch do
foo
end.return do |data|
puts data[:foo]
data[:foo] = 'world!'
end
<<--

結果として、以下のような出力を得ます。

pre>>
foo
hello
world!
bar
<<--

処理を中断したいところで Wormhole.throw を呼び出して、
外側から Wormhole.catch で受け止めます。
catchが完了したら、Wormholeオブジェクトが返るので、
returnで中断箇所に戻ります。
Wormhole.throw はHashを受け渡すことができます(省略可能)。
また、catchブロックとreturnは上記の例のように続けて記述します。
catchの戻り値を適当な変数に代入して、後でreturn
を呼び出すことも可能ですが、その場合、catchを抜けた直後から
returnを呼ぶまでの区間が二度実行されてしまいます
(この辺が最初に例外を使って実装してた理由ですね)

中断箇所から処理を再開するために callcc を使っています。
callccは面白いですね。

更新履歴

  • 2008/7/4 例外処理をやめてthrow/catchを使うようにしました。それにあわせて本文を修正しました。
posted by genki genki on Thu 3 Jul 2008 at 21:08 with 5 comments