Remapping global $ stdout for console - ruby

I am trying to set $ stdout to write to a file temporarily and then back to the file.

test.rb :
   old_stdout = $stdout    
    $stdout.reopen("mytestfile.out",'w+')
       puts "this goes in mytestfile"
    $stdout= old_stdout
puts "this should be on the console"
    $stdout.reopen("mytestfile1.out",'w+')
       puts "this goes in mytestfile1:"
    $stdout = old_stdout
 puts "this should be back on the console"

Here is the result.

ruby test.rb => no output on the console
cat mytestfile.out 
  this goes in mytestfile
  this should be on the console
cat  mytestfile1.out
  this goes in mytestfile1:
  this should be back on the console

I'm not sure why $ stdout is not getting reset for the console?

+5
source share
2 answers

This problem can be solved by calling dup on $stdoutbefore changing it:

old_stdout = $stdout.dup  
$stdout.reopen("mytestfile.out",'w+')
puts "this goes in mytestfile"
$stdout = old_stdout.dup
puts "this should be on the console"
$stdout.reopen("mytestfile1.out",'w+')
puts "this goes in mytestfile1:"
$stdout = old_stdout
puts "this should be back on the console"

Conclusion:

ruby test.rb
# => this should be on the console
# => this should be back on the console
cat mytestfile.out
# => this goes in mytestfile
cat mytestfile1.out
# => this goes in mytestfile1

This is how I usually set this function to a function:

# Runs a block of code while blocking stdout.
# Note that /dev/null should be changed to NUL on Windows.
def silence_stdout(log = '/dev/null')
  old = $stdout.dup
  $stdout.reopen(File.new(log, 'w'))
  yield
  $stdout = old
end

Using:

silence_stdout 'mytestfile.out' do
  puts "this goes in mytestfile"
end

puts "this should be on the console"

silence_stdout 'mytestfile1.out' do
  puts "this goes in mytestfile1"
end

puts "this should be back on the console"

Edit: as another poster mentioned, using reopening is only necessary when working with pure Ruby code. The function above works both with pure Ruby code, and when using, for example, C-extensions that are written to STDOUT.

+7
source

reopen, Ruby. puts Ruby $stdout, .

old_stdout = $stdout    
$stdout = File.new("mytestfile.out",'w+')
puts "this goes in mytestfile"
$stdout = old_stdout
puts "this should be on the console"
$stdout = File.new("mytestfile1.out",'w+')
puts "this goes in mytestfile1:"
$stdout = old_stdout
puts "this should be back on the console"

reopen, - (, fork) , , , Ruby $stdout global.

, reopen, $stdout, old_stdout, -, old_stdout stdout.

+3
source

All Articles