Stephen Veit
8/25/2006 9:32:00 PM
On 8/25/06, Berger, Daniel <Daniel.Berger@qwest.com> 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