4

I am quite new with Ruby, and I am trying to open a File object that points to stdout.

I know from this question that redirecting stdout to point to a File is quite simple, but what about redirecting a File to point to stdout?

I am writing a program, and I am thinking of providing the users with the option to write part of the output to a file. If they do not choose that option, then all of the output should be written to stdout.

See this pseudocode:

if output redirect option is selected
    o = File.open('given filename','w')
else
    o = File.open($stdout, 'w')
end

Here is pseudocode for a possible usecase:

puts 'Generating report for XYZ'
report = ReportGenerator::generateReport('XYZ')
o.puts report

As you can see, I desire only o to put the report to stdout if the output redirection option was not specified. The 'Generating report' message, however, I need to still be printed to stdout, so redirecting stdout will be cumbersome, especially since I have many more messages and many more places in which I am (possibly) alternating between output streams.

o = File.open($stdout, 'w') is the part I am uncertain of.

Community
  • 1
  • 1
scottysseus
  • 1,922
  • 3
  • 25
  • 50

1 Answers1

7

Ruby's $stdout is an IO instance that responds to puts, so you can just write:

if output_redirect_option_is_selected
  o = File.open('given filename','w')
else
  o = $stdout.dup
end

dup-ing $stdout allows you to close o without affecting $stdout:

o = $stdout.dup
o.close
puts 'bye' # works as expected

whereas:

o = $stdout
o.close
puts 'bye' # raises IOError
Stefan
  • 109,145
  • 14
  • 143
  • 218
  • leaving the `dup` method call when assigning `o = $stdout` actually did not raise IOError. Do you think that is because I never closed `o`? – scottysseus Aug 18 '15 at 14:29
  • @ScottScooterWeidenkopf yes, it only happens if you close `o` (i.e. `$stdout`) and write to it afterwards. You should nonetheless close open file handles. – Stefan Aug 18 '15 at 14:42