Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How is STDERR.puts different from puts in Ruby?

Tags:

ruby

stderr

I'm learning the language from Programming Ruby 1.9, and they toss STDERR.puts into a block of code early in the book without explaining why they're using it or how it's different from puts.

I've googled and wikied the term, but all I can gather from my research is that it's involved in diagnostics. Nowhere in the code provided by Programming Ruby does there seem to be a link to error exception handling.

Here's the code.

require_relative 'csv_reader' reader = CsvReader.new ARGV.each do |csv_file_name|   STDERR.puts "Processing #{csv_file_name}"   reader.read_in_csv_data(csv_file_name) end 

I did manage to read somewhere that STDERR.puts is used for error handling out of convention, but I guess I'm asking if it acts any differently than puts.

like image 816
rubynewbie Avatar asked Mar 10 '14 19:03

rubynewbie


People also ask

What is the point of stderr?

Stderr is the standard error message that is used to print the output on the screen or windows terminal. Stderr is used to print the error on the output screen or window terminal. Stderr is also one of the command output as stdout, which is logged anywhere by default.

What is stdout in Ruby?

The $stdout is a global variable which holds the standard output stream. printing2.rb. #!/usr/bin/ruby $stdout.print "Ruby language\n" $stdout.puts "Python language" We print two lines using the $stdout variable. Ruby has another three methods for printing output.


2 Answers

By default, puts writes to STDOUT. By specifying STDERR.puts, you're sending your output to the STDERR handle. Although the implementation behavior is the same, using STDERR instead of STDOUT will definitely impact consumers of your program, since they will be attempting to capture output from your program from STDOUT, by convention. Best practice is to log debugging information, errors, warnings, status, etc to STDERR and actual program output to STDOUT.

like image 123
Palpatim Avatar answered Oct 10 '22 19:10

Palpatim


Within a *nix based system when a new process is started it will by default have three open filehandles these are as follows

 0 - STDIN 1 - STDOUT 2 - STDERR 

These numbers, lets call them file descriptors are important to the unix shell that you are using to start your program. STDIN is where your program expects to get its input from (Usually the keyboard unless you've changed that). STDOUT is where your program will write its output (Usually the screen unless you've changed it) and STDERR is where it will write its errors (Again usually the screen unless you've changed it).

The common statement from above is "Unless you've changed it". If you run a command like this

command > file.out 

Then the output (everything written to STDOUT) will not show up on screen it will appear in file.out. If you run your command like this

command 2> file.err 

Then your output will appear on screen again but any errors written to STDERR will appear in file.err. In fact command > file.out is really shorthand for command 1>file.out. Whatever applies to the > symbol (Redirection) also applies to the | symbol for piping. This means that if you run your program as a filter, receiving data on STDIN and writing to STDOUT then other programs can receive their data from your program but they won't receive the data written to STDERR. (Unless you've asked it to)

You can use both of these commands together like this.

command 1> file.out 2> file.err  # Generally you would leave out the 1 

In this instance, not surprisingly the output and error will be in 2 separate files. Bash also has the notion of duplicating file descriptors. This is done with >& operator. The following command will put both STDOUT and STDERR in the same file.

command > file.out 2>&1 

What this command is saying is run the command setting up STDOUT to be redirected to file.out then duplicate ( >& ) file descriptor 2 (STDERR) to go to wherever file descriptor 1 is going to (file.out)

You need to be a little careful here with the order that you use these arguments in. Compare the above with this command.

command 2>&1 > file.out 

This has an entirely different result. This command says run the command and duplicate STDERR on to STDOUT (At this point in time the terminal) then redirect STDOUT to file.out. Your error text will remain on the screen.

like image 37
Steve Weet Avatar answered Oct 10 '22 19:10

Steve Weet