原です。

In message "[ruby-list:15010] Thread safe eRuby"
    on 99/06/16, Masatoshi SEKI <m_seki / mva.biglobe.ne.jp> writes:

|咳です。

|やや スレッドセーフ になった erb.rb 

今ごろになって erb.rb がスレッドセーフとはどういう意味か理解しま
した。(^^;;;

erb.rb は同時に複数のスクリプトを評価して結果の標準出力を別々に得
る必要があるんですね。

|このバージョンでは、eRuby スクリプトがマルチスレッドなとき、
|ERb#result は正しく動作しません。
|eRubyスクリプトが単一のスレッドであれば、マルチスレッドから
|ERb を使っても期待通りに動いてくれると思います。

この仕様で十分な気がします。CGI みたいなスクリプトがマルチスレッ
ドで動いてそれぞれが出力を出すって事あります?基本的に HTTP って
1セッション内で対話しないから、いいんじゃないかなあ。


でも一応考えてみました。Thread.start の定義をいじるという大げさ
なものなんですけど、一応動いている様な気がします。

-----^ as_output.rb
class IO; alias write_orig write; end
class Thread; OUTPUTS = {}; end

class << Thread
  alias start_orig start
  
  def as_output(x)
    if Thread::OUTPUTS.empty?
      Thread.critical = true
      def $stdout.write(s)
	if io = Thread::OUTPUTS[Thread.current]
	  io.write(s)
	else
	  write_orig(s)
	end
      end
      
      def Thread.start(x = nil)
	c = Thread.current
	Thread.start_orig {
	  d = Thread.current
	  Thread::OUTPUTS[d] = x || Thread::OUTPUTS[c]
	  yield
	  Thread::OUTPUTS.delete d
	  
	  if Thread::OUTPUTS.empty?
	    def $stdout.write(s); $stdout.write_orig(s); end
	    def Thread.start; Thread.start_orig {yield}; end
	  end
	}
      end
      Thread.critical = false
    end
    
    Thread.start(x) {
      yield
    }.value
  end
end
-----$ as_output.rb

テストプログラムです。

-----^ test.rb
#!/usr/local/bin/ruby
require "as_output"

Thread.abort_on_exception = true

def display(n=0)
  (0..5).each { |i| puts i+n; Thread.pass}
end
class String
  def write(x); concat(x); end
end

s1 = ""
s2 = ""
s3 = ""

thrs = []

thrs << Thread.start {
  Thread.as_output(s1) {
    thrs << Thread.start {
      thrs << Thread.start {
	display(1000)
      }
      display(1100)
    }
  }
}

puts "HELLO!"

Thread.as_output(s2) {
  Thread.as_output(s3) {
    thrs << Thread.start {
      display(3100)
    }
    display(3000)
  }
  thrs << Thread.start {
    display(2000)
  }
  Thread.as_output(s2) {
    display(2100)
  }
}

thrs.each do |x|
  #Thread.join(x)
  x.join
end

puts "----- s1 ------"
puts s1
puts "----- s2 ------"
puts s2
puts "----- s3 ------"
puts s3
-----$ test.rb