From: "KISHIMOTO, Makoto" Date: 2010-07-31T19:06:51+09:00 Subject: [ruby-dev:41906] Re: [Feature #3627] catchのブロックを再実行するメソッド きしもとです > |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 ...というのは ダメですね多分。