From: Stephen Veit Date: 2006-08-26T06:31:54+09:00 Subject: Re: Can you temporarily turn off STDERR ?? On 8/25/06, Berger, Daniel wrote: > > This comes up often enough that I wonder if allowing IO#reopen to take a > block would be a good idea: > > $stderr.reopen('/dev/null') do > # Code here redirects to /dev/null > end > > # Code outside the block behaves normally > > I thought this idea had been brought up before, and that there was some > downside to this, but I can't find any references to it now. > > Thoughts? > > - Dan How about this? #!/usr/bin/env ruby # reopen_with_block.rb class IO alias_method :_orig_reopen, :reopen def reopen(*args) if block_given? is_path = args.length == 2 path_or_io, mode_str = args old_io = clone path_or_io = File.open(path_or_io, mode_str || "w") if is_path _orig_reopen(path_or_io) begin yield ensure _orig_reopen(old_io) path_or_io.close if is_path end else _orig_reopen(*args) end end end if $0 == __FILE__ $stderr.reopen('error_log', 'w') do $stderr.puts "Stuff on error" puts "normal stuff" end File.open('error_log_2', "w") do |file| $stderr.reopen(file) do $stderr.puts "Stuff on error 2" puts "normal stuff 2" end end $stderr.reopen('/dev/null') do $stderr.puts "Stuff on error 3" puts "normal stuff 3" end # Make sure old way works old_stderr = $stderr.clone File.open('error_log_4', 'w') do |log_file| $stderr.reopen(log_file) begin $stderr.puts "Stuff on error 4" puts "normal stuff 4" ensure $stderr.reopen(old_stderr) end end begin $stderr.reopen('error_log_5', 'w') do $stderr.puts "Stuff on error 5" puts "normal stuff 5" raise "This message courtesy of raise" end rescue => e puts e end end