On Sat, 3 May 2003, Brian Candler wrote:

> On Sat, May 03, 2003 at 12:26:10AM +0900, ahoward wrote:
> > On Fri, 2 May 2003, Brian Candler wrote:
> >
> > > I profess to not fully understanding the different between $defout, $stdout
> > > and STDOUT; but I believe that $defout is where puts and friends send their
> > > output by default, so you can change this to a different Ruby stream without
> > > touching the stdout which is connected to the process.
> >
> > http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&selm=Pine.LNX.4.53.0303242333140.13691%40eli.fsl.noaa.gov
> >
> > and view the complete thread.
>
> Oh yes, I remember that now. But I don't think it explains $stdout versus
> STDOUT

i am more confused than usual ;-)

~ > cat foo.rb
#!/usr/bin/env ruby

def dump s, binding=nil
  case s
  when Symbol
    STDERR.puts %Q(\t#{s} => #{eval(s.to_s, binding).inspect})
  when String
    STDERR.puts "\t#{s}"
  end
end

File.open("output","w") { |f|

  dump '(ORIGINAL)'
  [:f,:$defout,:$stdout,:STDOUT].map{|sym| dump sym, binding}

  puts("To the screen")

  $defout.reopen f
  dump '(REDIRECTED TO FILE)'
  [:f,:$defout,:$stdout,:STDOUT].map{|sym| dump sym, binding}

  puts("To the file")

  $defout.reopen STDOUT
  dump '(RESTORED)'
  [:f,:$defout,:$stdout,:STDOUT].map{|sym| dump sym, binding}


  puts("To the screen again")
}


> ruby foo.rb
        (ORIGINAL)
        f => #<File:0x40182b2c>
        $defout => #<IO:0x401880a4>
        $stdout => #<IO:0x401880a4>
        STDOUT => #<IO:0x401880a4>
To the screen
        (REDIRECTED TO FILE)
        f => #<File:0x40182b2c>
        $defout => #<File:0x401880a4>
        $stdout => #<File:0x401880a4>
        STDOUT => #<File:0x401880a4>
        (RESTORED)
        f => #<File:0x40182b2c>
        $defout => #<File:0x401880a4>
        $stdout => #<File:0x401880a4>
        STDOUT => #<File:0x401880a4>


so it appears that reopening even $defout results in STDOUT and $stdout also
being reopened to point to a file.  in otherwords, you will never be able to
restore unless a copy is made prior to this.  this works like it reads:


> cat redirect.rb && ruby redirect.rb && echo 'output:' && cat output
#!/usr/bin/env ruby

class IO
  def redirect io
    (@__self ||= []) << (clone = self.clone)
    reopen io
    clone
  end
  def restore
    raise 'NOT REDIRECTED' unless
      defined? @__self and not @__self.empty?
    reopen @__self.pop
  end
end

File.open("output","w") { |f|
  puts("To the screen")

  STDOUT.redirect f
  puts("To the file")

  STDOUT.restore
  puts("To the screen again")
}

To the screen
To the screen again
output:
To the file


-a


--
  ====================================
  | Ara Howard
  | NOAA Forecast Systems Laboratory
  | Information and Technology Services
  | Data Systems Group
  | R/FST 325 Broadway
  | Boulder, CO 80305-3328
  | Email: ara.t.howard / fsl.noaa.gov
  | Phone:  303-497-7238
  | Fax:    303-497-7259
  ====================================