STDERR vs $stderr - delegation bug

all of the previous solutions seem to make the following assumptions -

$stderr and $stdout are global objects which all of ruby send messages
bound to ‘stderr’ and ‘stdout’ to, and that the constants STDERR and
STDOUT also point to these same objects. that being the case (?), can
someone tell me why the following DOES NOT WORK?

···

======================================================================
#!/usr/bin/env ruby

require ‘delegate’

simplest possible example

of a redirectable IO class

class DupableIO < SimpleDelegator
def initialize io
@io = io
super(@io)
end
def duplicate io
setobj io
end
def unduplicate
setobj @io
end
end

output goes to stderr

ls non_existent_file

global stdout delegates all his calls to constant object STDOUT

$stdout = DupableIO.new STDOUT

global stderr delegates all his calls to constant object STDERR

$stderr = DupableIO.new STDERR

a normal io (File) object

$log = open ‘logfile’, ‘w’

output STILL goes to stderr (correct)

ls non_existent_file

now tell stderr and stdout to delegate

their calls to the log object

$stderr.duplicate $log
$stdout.duplicate $log

output goes to logfile (correct)

$stderr.puts ‘foo’

======================================================================

in particular it would seem that, somewhere, some test is made of
$stderr and $stdout BEFORE actually using them - something along the
lines of

if $stderr.type == IO
… use it
else
… open up 2 and use it
end

how else to explain the above behavior. it’s really unfortunate
because i think this type of solution is in the ‘ruby spirit’ : what
we require is an IO object which can, temporarily, make calls on
another IO object. this IS the delegate pattern to a ‘T’ - it would
be nice to be able to use it.

  • ara howard

ahoward@fsl.noaa.gov