On Wed, Jul 10, 2002 at 01:48:34PM +0900, Park Heesob wrote:
> You can redirect standard error to file like this:

Ok, someone please shed some light on this.  The following works
(forget for a moment that files are closed in the procedure):

def redir(redout, rederr)
	raise unless block_given?
	oldout, olddef, olderr = $stdout.dup, $defout.dup, $stderr.dup
	begin
		$stdout = redout.dup
		$defout = redout.dup
		$stderr = rederr.dup
		yield
	ensure
		redout.close
		rederr.close
		$stdout = oldout
		$defout = olddef
		$stderr = olderr
	end
end

out = File.open("/tmp/stdout", "w+")
err = File.open("/tmp/stderr", "w+")

redir(out, err) do
  puts "hello, world!"
  `ls notexist`
end


The following does work for stdout *only*.  It does not work for
stderr.  redir is as above.


class TempIO
	def initialize
		@buffer = ''
	end
	
	def write(str)
		@buffer << str
		str.length
	end

	def close 
	end
end

out, err = TempIO.new, TempIO.new

redir(out, err) do
  puts "hello, world!"
  `ls notexist`
end



Has a IO class to provide something else for this kind of things apart
from a write method?  And even if so, where does ruby silently decide
that the given IO has no right to become stderr and grabs old stderr
back?  I'm puzzled.


Massimiliano