From: Tanaka Akira Date: 2003-01-02T14:08:15+09:00 Subject: [ruby-dev:19286] Re: ruby-1.8.0 / yield(nil)とyield()の In article , Masatoshi SEKI writes: > 不安定というのは仕様がですか? > それとも挙動が不安定なのでしょうか? たぶん、仕様が。誰も使ってないところは不安定なものです。 > ふむむ。実現できたらいいなあ。 > いまのRubyが持ってるしかけでやるにはどうしたらいいんだろう。 > ちょっと考えてみます。 > ブロックの内でbreakやretryが行われたことを知るにはどうしたら > いいんだろう。またそれをサーバに伝えるには… ケチをつけるばかりなのもなんなのでちょっと書いてみました。 よーするに break/retry で適切な所に飛ぶのは Ruby にまかせれば break と retry を区別しなくてもすむというだけの話ですが。 require 'thread' def f(arg) yield arg + 1 end def server_stub s2c = Queue.new c2s = Queue.new Thread.new { com = [:shrink] catch(:shrink) { begin methodname, args = c2s.deq ret = send(methodname, *args) {|a| s2c.enq [:yield, a] case (d = c2s.deq).first when :next next d.last when :shrink throw :shrink end } com = [:return, ret] ensure s2c.enq com end } } return s2c, c2s end def client_stub(*args) s2c, c2s = server_stub c2s.enq [:f, args] while true d = s2c.deq case d.first when :yield com = [:shrink] begin val = yield d.last com = [:next, val] ensure c2s.enq com s2c.deq if com.first == :shrink end when :return break d.last end end end p client_stub(10) {|a| p :x; break } client_stub(10) {|a| p :y; retry } # infinite loop それはそれとして、これを書いて気がついたんですが、retry の挙動が変な気 がします。 % ruby -e ' def f p 0 loop { p 1 yield } end f { p 2; retry }' 0 1 2 1 2 1 2 1 2 1 ... というように、retry で f でなくて loop が再起動される(0 が最初の一回し か出て来ない)のは意図されていないんじゃないかと思います。 (まぁ、だれも使ってないだろうけど。) -- [田中 哲][たなか あきら][Tanaka Akira]