土岐です。 Date: Sun, 1 Aug 1999 08:36:48 +0900 Subject: [ruby-list:15809] Re: ERb について Masatoshi SEKI <m_seki / mva.biglobe.ne.jp> wrote... SEKI> このパッチで ERb もうまく動きました。 SEKI> 松尾さん、土岐さんの環境ではどうでしょうか? わたしの環境でもうまく動きました。 Date: Sun, 1 Aug 1999 12:32:59 +0900 Subject: [ruby-list:15811] Re: ERb について matsuo hisanori <matsuo_hisanori / pop21.odn.ne.jp> wrote... matsuo> スレッドセーフにする為なんだろうけど、あそこでスレッドを使 matsuo> うには、どういう意味があるのかな…。 ERb の生成するスクリプトをスレッドで評価しているのは、もともとは $SAFE を変更するためだったようです。 Date: Sun, 1 Aug 1999 14:44:57 +0900 Subject: [ruby-list:15814] Re: ERb について Masatoshi SEKI <m_seki / mva.biglobe.ne.jp> wrote... SEKI> $SAFE を使わない時は、スレッドにしなくても良い気がしてきました。 SEKI> 実際、スレッドやめても動いているみたい。 わたしもそんな気がしてきました。ERb が呼ばれたスレッドは ERb の評価が 終了するまで動くことはないので、標準出力が ERb と衝突することはないか ら、StringIO のからくりはうまく働きそうに思えます。でもそうすると今の ままではスレッドが生きているあいだは DefOut に ERb の出力結果が残っちゃ いますね。 あと 1.3 系だと StringIO#write に print の引数のオブジェクトがそのまま 渡されるみたいで、StringIO#write の中でオブジェクトを文字列に変換して やらないといけないみたいです。IO の実装が変わったのかな。 SEKI> # あれ?? $SAFE=4 がうごかない…。1.3系だから!? "Insecure: can't access instance variable" ですか。 これだとスクリプトではどうしようもないような気が... それで、以上の点をふまえて strio.rb を修正してみました。 参考になれば幸いです。 *** strio.rb.orig Sun Aug 1 17:09:29 1999 --- strio.rb Sun Aug 1 18:43:06 1999 *************** *** 16,21 **** --- 16,27 ---- end end + def clear + @m.synchronize do + @writers.delete(Thread.current) + end + end + def cleanup @m.synchronize do @writers.delete_if do |k, v| *************** *** 23,29 **** end end end ! module_function :write, :set, :cleanup @m = Mutex.new @writers = Hash.new --- 29,35 ---- end end end ! module_function :write, :set, :clear, :cleanup @m = Mutex.new @writers = Hash.new *************** *** 51,69 **** attr :str def write(str) ! @str.concat(str) end ! def as_stdout(safe=nil) ! t = Thread.new { ! out = StringIO.new ! DefOut.set(out) ! $SAFE = safe if safe yield ! out.str ! } ! DefOut.cleanup ! t.value end module_function :as_stdout end --- 57,95 ---- attr :str def write(str) ! @str.concat(str.to_s) end ! def _as_stdout ! out = StringIO.new ! DefOut.set(out) ! begin yield ! ensure ! DefOut.clear ! end ! out.str ! end ! module_function :_as_stdout ! ! def as_stdout(safe=$SAFE) ! if safe > $SAFE ! _as_stdout do ! t = Thread.new { ! $SAFE = safe ! yield ! } ! begin ! t.join # for ruby-1.3 ! rescue NameError ! Thread.join t # for ruby-1.2 ! end ! end ! else ! _as_stdout do ! yield ! end ! end end module_function :as_stdout end ---------------------------------------------------------------------- 土岐 仁謙 神戸大学物理高エネ研 M2 URL: http://www3.phys.sci.kobe-u.ac.jp/~toki/index.html PGP fingerprint = D0 A8 90 AB 73 F8 34 FE CE CA DB BF 01 30 C0 35