On 2008.02.06 03:00, Sam Ruby wrote:
> require 'tmpdir'
> 
> save = STDOUT.dup
> STDOUT.reopen File.open(File.join(Dir.tmpdir, "should_output_#{$$}"), "w+")
> puts 'hi'
> out = STDOUT.dup
> STDOUT.reopen save
> 
> out.rewind
> p out.read
> 
> reopen.rb:7:in `reopen': /tmp/should_output_8694 can't change access 
> mode from "w+" to "w" (ArgumentError)
>         from reopen.rb:7:in `<main>'
> 
> Is this a bug in Ruby 1.9?  

The error message is ambiguous at least. It means that for some reason,
the backend is trying to apply the existing mode 'w+' to the stream to
be opened and since STDOUT is 'w', failing to do so because that would
"widen" the stream. It is a bug, probably caused by 'incorrect' use of
freopen().

Logically, there is no reason why reopen should care about the previous
mode of the old stream since it is just closed/discarded. freopen() does
take a new mode which is not allowed to widen the existing mode on the
stream but that only affects the new stream (or pointer), not the previous
one.

>                            If not, any suggestions on a workaround for 
> test/spec?

The workaround is to just open the tempfile 'w' and open it again
for reading later. Hopefully it will be fixed soon though.

I have actually meant to try to write up a list of things in the IO
hierarchy that could be simplified/improved. The #reopen/#dup logic
is one of those, the weird relationship between IO and File is another
main one. Perhaps I will actually get around to it at some point.

--
Eero