IO#getc behavior

yes,

but a very platform specific:

···

-------------------------------------------------
require 'Win32API'

$stdout.sync=true
kbhit = Win32API.new("msvcrt", "_kbhit", , 'I')
getch = Win32API.new("msvcrt", "_getch", , 'I')

while true
    sleep 0.01 while kbhit.call.zero?
    c = getch.call
    puts(c.chr)
end
-------------------------------------------------

cheers

Simon

-----Original Message-----
From: Jon A. Lambert [mailto:jlsysinc@alltel.net]
Sent: Monday, September 26, 2005 11:14 AM
To: ruby-talk ML
Subject: 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

Thanks Simon and Sean..

By way of followup to anyone having similar problems ...

I had success with this:

if RUBY_PLATFORM =~ /win32/
  require 'Win32API'
  Kbhit = Win32API.new("msvcrt", "_kbhit", [], 'I')
  Getch = Win32API.new("msvcrt", "_getch", [], 'I')
  def getkey
    sleep 0.01
    return nil if Kbhit.call.zero?
    c = Getch.call
    c = Getch.call + 256 if c.zero? || c == 0xE0
    c
  end
else
  def getkey
    select( [$stdin], nil, nil, 0.01 ) ? c = $stdin.getc : c = nil
  end
end

You've got to check getch for extended scancodes.

Also I use an echo/no echo option later in the code and
found getche() works like Unices getc() in that regard and to get Unices getc() to not echo and still allow CTL-C interrupts
handled by Ruby I had to do this upon starting...

    if !WIN32 && $opts.echo
      system('stty cbreak -echo')
    end

and this upon exiting..

    if !WIN32 && $opts.echo
      system('stty -cbreak echo')
    end

···

--
J Lambert

I'm sure I read somewhere that Win32API is being phased out in favour of DL

Sean

···

On 9/26/05, Kroeger Simon (ext) <simon.kroeger.ext@siemens.com> wrote:

require 'Win32API'