IO#getc behavior

I'm writing a console application with an input loop like the following:

   while running
        keyhit = select( [$stdin], nil, nil, 0.1 )
        if keyhit
          c = $stdin.getc
          session.message(c.chr)
        end
   end

In the cygwin version of Ruby all is fine. The user hits a key select() indicates it and the character is gotten with $stdin.getc.

However I ran this under the msvc version of windows and what happens is select() returns a ready state for $stdin whether a key is hit or not. Then getc() blocks? because there's nothing yet to be gotten. Worse no I/O seems to be going on until the user hits the return key and then whammo I see either the end result of the loops or it appears more likely getc blocks internally under cover until it sees a CR in the stream.

Is there a workaround?

Thanks

···

--
J Lambert

Hi Jon,

this is what I use:

--- CODE ---

···

##
# getch and kbhit for win32
# Sean O'Halpin
#
require 'dl/import'
module Win32API
  extend DL::Importer

  dlload 'crtdll.dll'

##
# kbhit - returns 0 if nothing waiting, non-zero otherwise
#
  extern 'int _kbhit()', :stdcall

##
# getch - blocks waiting for one character of input from console
# Note: returns integer representing character
# Use getch.chr to get one character string
#
  extern 'int _getch()', :stdcall

  alias :kbhit :_kbhit
  alias :getch :_getch

  module_function :kbhit, :getch
end

if __FILE__ == $0

  puts "kbhit"
  puts "Hit any key"

  while true
    x = Win32API.kbhit
    if x > 0
      puts Win32API.getch.chr
      break
    else
      print "."
    end
  end
end
--- END CODE ---

HTH,

Sean

In article <000701c5c27a$d77058b0$0200000a@agamemnon>,
  "Jon A. Lambert" <jlsysinc@alltel.net> writes:

However I ran this under the msvc version of windows and what happens is
select() returns a ready state for $stdin whether a key is hit or not.
Then getc() blocks? because there's nothing yet to be gotten. Worse no I/O
seems to be going on until the user hits the return key and then whammo I
see either the end result of the loops or it appears more likely getc blocks
internally under cover until it sees a CR in the stream.

Is there a workaround?

I heard Ruby 1.9 is improved recently. See [ruby-talk:156899].

···

--
Tanaka Akira