I’ve been using for Ruby for a bit now, but I’ve never felt happy that I’ve
understood the difference purposes of $stdout and STDOUT (and -in & -err).
In particular, I’m interested in doing things similar to what I did in Perl
with select and tie-ing STD filehandles to classes temporarily then
returning to program default values. I’ve seen an interesting example of a
string-based class implementing IO-like behaviour in ‘The Ruby Way’
(223-225), but I’m not sure how to manipulate Ruby’s STDOUT and $stdout to
do useful things with these sort of classes (using .reopen()?), so I’d
appreciate pointers to threads or example code.
There’s been some discussion
(http://www.rubygarden.org/article.php?sid=179) about changing IO to
make this task (and other tasks) easier. At the moment, reopen() can
only be using with real IO objects (and won’t work with a StringIO
object).
The following will work, but the solution is not ideal. I’d like to
make it buffered (for better performance), and I’m not sure what should
happen if stop() is called when there is still data to be read. And if
you want to be able to make this work during a system call, then you’ll
need to use a separate process instead of a thread.
Hope this helps,
Paul
A very basic StringIO implementation
class StringIO
attr_reader :str
def initialize @str = ‘’
end
def write(str) @str << str
end
end
A class to redirect $stdout (or other IO object) to a StringIO object
(or other object with a write() method)
class Redirector
def initialize(from, to)
tmp = from.dup
r, w = IO.pipe
from.reopen(w) @t = Thread.new do
begin
loop do
s = r.read(1) # TODO: can I make this buffered?
to.write(s)
end
ensure
from.reopen(tmp)
end
end
end
def stop @t.kill
end
def self.redirect(from, to)
s = self.new(from, to)
begin
yield
ensure
s.stop
end
end
end
if FILE == $0 then
Thread.abort_on_exception = true
s = StringIO.new
r = Redirector.redirect($stdout, s) do
$stdout.puts “this is a test”
$stdout.puts “of the StringIO redirection system”
end
puts “Done redirecting.”
puts “Result:\n#{s.str}”
end
···
On Wed, Aug 07, 2002 at 08:22:48AM +0900, alex f wrote:
In particular, I’m interested in doing things similar to what I did in Perl
with select and tie-ing STD filehandles to classes temporarily then
returning to program default values. I’ve seen an interesting example of a
string-based class implementing IO-like behaviour in ‘The Ruby Way’
(223-225), but I’m not sure how to manipulate Ruby’s STDOUT and $stdout to
do useful things with these sort of classes (using .reopen()?), so I’d
appreciate pointers to threads or example code.