I would like to capture stderr into a variable in memory, without using a file on the filesystem. (This is because if the process is kill -9
'ed, the file, even if it is a Tempfile, will not be deleted.)
There is a solution for this at How do I temporarily redirect stderr in Ruby?, but its strategy is to assign a StringIO to $stderr
. This will not work if the value of $stderr was copied prior to the reassignment, nor will it work if STDERR
is used. As evidence:
#!/usr/bin/env ruby
stderr_sav = $stderr
$stderr = File.open(File::NULL, 'w')
$stderr.puts 'Using $stderr'
stderr_sav.puts 'Using stderr_sav'
STDERR.puts 'Using STDERR'
# Outputs:
# Using stderr_sav
# Using STDERR
In contrast, using reopen
works:
#!/usr/bin/env ruby
stderr_sav = $stderr
$stderr.reopen(File.new(File::NULL, 'w'))
$stderr.puts 'Using $stderr'
stderr_sav.puts 'Using stderr_sav'
STDERR.puts 'Using STDERR'
# Outputs:
# [nothing]
Unfortunately, passing a StringIO
to reopen
does not work:
`reopen': no implicit conversion of StringIO into String (TypeError)
Is there any way to accomplish the capturing of $stderr
without using a file?