Bug #9067

IO.reopen broken in 1.9/2.0, worked in 1.8

Added by Johan Walles 6 months ago. Updated 6 months ago.

[ruby-core:58084]
Status:Rejected
Priority:Normal
Assignee:-
Category:-
Target version:-
ruby -v:ruby 2.0.0p247 (2013-06-27 revision 41674) [universal.x86_64-darwin13] Backport:1.9.3: UNKNOWN, 2.0.0: UNKNOWN

Description

Try piping some input into the attached code:

echo foo | reopen-fail.rb

Works as expected with ruby 1.8.7 (2012-02-08 patchlevel 358) [i686-linux]:
* "foo" is printed at the middle of the screen
* you can press RETURN to exit

Results with ruby 1.9.3p194 (2012-04-20 revision 35410) [i686-linux] and ruby 2.0.0p247 (2013-06-27 revision 41674) [universal.x86_64-darwin13]:

./reopen-fail.rb:8:in reopen': <STDIN> can't change access mode from "r" to "w" (ArgumentError)
from ./reopen-fail.rb:8:in
'

AFAICT this makes it impossible to write Curses programs in Ruby that can accept input through pipes with newer versions of Ruby.

In my particular case this blocks my Ruby-implemented less replacement: https://github.com/walles/moar

reopen-fail.rb Magnifier - Repro (306 Bytes) Johan Walles, 10/31/2013 05:04 AM

History

#1 Updated by Akira Tanaka 6 months ago

2013/10/31 walles (Johan Walles) johan.walles@gmail.com:

Bug #9067: IO.reopen broken in 1.9/2.0, worked in 1.8
https://bugs.ruby-lang.org/issues/9067

./reopen-fail.rb:8:in reopen': <STDIN> can't change access mode from "r" to "w" (ArgumentError)
from ./reopen-fail.rb:8:in
'

AFAICT this makes it impossible to write Curses programs in Ruby that can accept input through pipes with newer versions of Ruby.

I recommend
$stdin.reopen(IO.new(1, "r+"))
or
$stdin.reopen("/dev/tty")
instead of
$stdin.reopen($stdout)
--
Tanaka Akira

#2 Updated by Nobuyoshi Nakada 6 months ago

  • Status changed from Open to Rejected

#3 Updated by Johan Walles 6 months ago

Thanks for the quick turnaround!

$stdin.reopen(IO.new(1, "r+")) does what I want.

Also available in: Atom PDF