Reputation: 1420
In the one answer I have found this stanza that waits for your input and prints it until you press enter:
require 'io/console'
require 'io/wait'
loop do
chars = STDIN.getch
chars << STDIN.getch while STDIN.ready? # Process multi-char paste
break if chars == ?\n
STDOUT.print chars
end
However, in order to exit loop
, I must press "Enter"(key for new line - \n
) twice, or press something else after it.
When I try to execute the same loop again (copy-paste it into the same pry session) I am getting:
IOError: byte oriented read for character buffered IO
chars << STDIN.getch while STDIN.ready?
cause raising, mentioned above, error. Without this line, ruby just doesn't show any error.
In both cases (with and without above line), in the loop:
when I press the enter and then some letter (for example 'z') I'm getting this error.
In the next loop, above letter will show (without my input).
when I press the enter twice - no error, it will exit.
In the next loop when I press some letter, error will show.
In the next loop above letter will show
I remember that in C or C++ there was flush
so you can empty the buffer. I have found s few methods, and tried like this:
loop do
STDIN.ioflush
STDOUT.ioflush
STDOUT.iflush
STDIN.iflush
STDOUT.oflush
STDIN.oflush
chars = STDIN.getch
chars << STDIN.getch while STDIN.ready?
break if chars == ?\n
STDOUT.print chars
end
but it didn't work.
How to solve this behavior with enter and 2nd letter & IOError
. I think both are correlated in some way.
Upvotes: 2
Views: 238
Reputation: 78561
The code from that answer is a simplified version of a highline-like library I wrote for personal use. I never encountered that specific error myself, but it might be due to the fact I'm actually using something slightly different. My actual code goes something more like this:
require 'io/console'
require 'io/wait'
catch(:done) do
loop do
chars = STDIN.getch
chars << STDIN.getch while STDIN.ready? # Process multi-char paste
throw :done if ["\r", "\n", "\r\n"].include?(chars)
STDOUT.print chars
end
end
STDOUT.print "\n"
I also have kill-signal handler, in case Ctrl+C (kill process) or Ctrl+D (end of input) get pressed; the first interrupts the program, and the second is wired to react as if enter was pressed.
The precise behavior might depend on the OS (I use it on OSX and FreeBSD), since the enter key could return any of "\r"
, "\n"
or "\r\n"
depending on the OS:
\r\n , \r , \n what is the difference between them?
Upvotes: 2