Darek Nędza
Darek Nędza

Reputation: 1420

enter & IOError: byte oriented read for character buffered IO

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:

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

Answers (1)

Denis de Bernardy
Denis de Bernardy

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

Related Questions