=begin
きしもとです
|throwのかわりに、なにか別のメソッド(rewindという名前はどうでしょう?)を実行すると、catchのブロックが再実行される、というのはどうでしょうか?
基本的なアイディアを否定するわけではありませんが、
- catchブロックの再実行が必要なユースケースが示されていない
- rewindという名前はいろいろなところで使われているので望ま
しくない
ので、現時点では賛成しません。
ユースケースですが、The Art of Multiprocessor Programming の、
ロックフリースキップリストの find メソッド(Fig. 14.13)を Ruby で書いた
ものを示します。(begin と rescue と retry で同等のものを実装しています。
元の Java コードではラベル付きの continue でした)
def find key, before_list, after_list
retry_tag = Class.new Exception
begin
pp = nil
p = @head
@level_max.downto(0){|level|
pp = p.links[level].get_link
loop {
ppp, mark = pp.links[level].get
while mark do
snip = p.links[level].compare_and_set pp, ppp, false, false
unless snip then
raise retry_tag
end
pp = ppp
ppp, mark = pp.links[level].get
end
if pp.key.__send__(@cmp_op, key) == -1 then
p = pp
pp = ppp
else
break
end
}
before_list[level] = p
after_list[level] = pp
}
if pp.key.__send__(@cmp_op, key) == 0 then
pp
else
nil
end
rescue retry_tag
retry
end
end
private :find
また、しばらく考えてみたのですが、C言語で do { continue; } while (0); が
ループにならないことを考えると、デフォルトでは1回きりの実行が期待されている
catch との組み合わせはあまり良くないように思えてきました。
loop のブロックが引数を取るようにして、
loop {|tag|
...
continue tag
...
}
というかたちではどうでしょうか?
あと、名前ですが、continue の他に loop と対になるので pool ...というのは
ダメですね多分。
=end