From: Brian Candler Date: 2009-02-09T20:16:44+09:00 Subject: Re: assignment to $stdout deprecated? 7stud -- wrote: > In pickaxe2, on p. 335, it says that assigning to $stdout is deprecated > and to use $stdout.reopen() instead: It depends what you're trying to do. I'll describe this from a Unix point of view. Your Ruby program runs as a process which starts with three open file descriptors: stdin (fd 0), stdout (fd 1), stderr (fd 2). These are wrapped in Ruby objects STDIN, STDOUT, STDERR, and the global variables $stdin, $stdout, $stderr point to these objects too. If you do STDOUT.reopen(...) then you are closing fd 1 and replacing it with a different file in the Unix file descriptor table. When your Ruby program writes to STDOUT it will write to this file; but also any child process spawned by your Ruby program will inherit this too (e.g. using system() or backticks) If you reassign $stdout to point to a completely different Ruby object, then any code you write which does $stdout.puts will write to this object - but FD 1 still remains connected to the original stdout. Therefore, STDOUT.puts will still write to the original destination, as will any child process. $stdout = File.open("/tmp/stdout.txt","w") puts "Hello" # uses $stdout, goes to the file STDOUT.puts "World" # goes to the terminal (FD 1) system("echo Wheee") # goes to the terminal (FD 1) If you need to redirect to a StringIO object, then you have little choice but to use $stdout, because a StringIO is not a Unix file, i.e. it doesn't have an entry in the file descriptor table. (If you wanted to get very fancy, you could perhaps set up a pipe, connect stdout to the writer end, and have a Ruby thread reading from the reader end and appending to a StringIO object. But you'd only jump through those hoops if you wanted the stdout from spawned child processes to write to the StringIO too, and in that case you'd be better off using IO.popen anyway) -- Posted via http://www.ruby-forum.com/.