我怀疑主要区别在于reopen
,新流不仅适用于该$std...
变量的后续使用,还适用于先前分配给该变量值的 $std...
变量。这可能是好是坏,取决于您的情况。
此 irb 会话表明,reopen
在流更改之前分配的变量将获取新更改的流。请注意,任何一个变量的fileno
都不会改变,并且两个变量都不会产生输出:
> $stderr.fileno
=> 2
> stderr_copy = $stderr
=> #<IO:<STDERR>>
> stderr_copy.fileno
=> 2
> $stderr.reopen(File.open('/dev/null', 'w'))
=> #<File:/dev/null>
> stderr_copy.fileno
=> 2
> $stderr.fileno
=> 2
> $stderr.puts 'foo'
=> nil
> stderr_copy.puts 'foo'
=> nil
相反,当reopen
新打开的/dev/null
File 对象不使用 ,而是分配给 时 $stderr
,stderr_copy
将保留其原始输出流。只$stderr
得到新的fileno
,stderr_copy
仍然产生输出:
> $stderr.fileno
=> 2
> stderr_copy = $stderr
=> #<IO:<STDERR>>
> stderr_copy.fileno
=> 2
> $stderr = File.open('/dev/null', 'w')
=> #<File:/dev/null>
> $stderr.fileno
=> 10
> stderr_copy.fileno
=> 2
> $stderr.puts 'foo'
=> nil
> stderr_copy.puts 'foo'
foo
=> nil
如果你想使用reopen
,但想保存原始输出流的副本,你可以使用dup
:
> stderr_dup = $stderr.dup
=> #<IO:<STDERR>>
> stderr_dup.fileno
=> 10
> $stderr.reopen(File.open('/dev/null', 'w'))
=> #<File:/dev/null>
> $stderr.fileno
=> 2
> stderr_dup.puts 'foo'
foo
=> nil
> $stderr.puts 'foo'
=> nil