Forum: Ruby How to capture a pressed key?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
333f1bc25c9b3ca4f1bf59a7efc9a79a?d=identicon&s=25 Rubyist (Guest)
on 2006-01-24 17:58
(Received via mailing list)
Hi,

How can I capture a key from keyboard in a console program? I mean, I
want to get an answer consisted of only one letter and the user will
not press "enter". Just a key, that's all.

Thank you.
1d5ce8497508c41bee8b1dc6ae7692d9?d=identicon&s=25 unknown (Guest)
on 2006-01-24 18:05
(Received via mailing list)
print "Enter your name: "
name = gets

http://www.rubycentral.com/book/tut_io.html

to get the first letter of 'name' you would access it by name[0,1]
333f1bc25c9b3ca4f1bf59a7efc9a79a?d=identicon&s=25 Rubyist (Guest)
on 2006-01-24 18:14
(Received via mailing list)
Oh, I know the "gets". But user will need to press "enter" in order to
"gets" to get something. I want to let the interpreter get a letter
WITHOUT pressing the enter key.
A083f2c63fc0be7f8f19006c9dbdff86?d=identicon&s=25 Dale Martenson (Guest)
on 2006-01-24 18:29
(Received via mailing list)
Are you running on Windows or Linux?

In Windows, you can do something like this:

  require 'Win32API'

  $win32_console_kbhit = Win32API.new("msvcrt", "_kbhit", [], 'I')
  $win32_console_cputs = Win32API.new("msvcrt", "_cputs", ['P'], 'I')
  $win32_console_getch = Win32API.new("msvcrt", "_getch", [], 'I')

  def console_input_ready?
    $win32_console_kbhit.call != 0
  end

  def console_input
    $win32_console_getch.call
  end

  def console_output( str )
    $win32_console_cputs.call( str )
  end

  while true
    if console_input_ready? then
        ch = console_input
        print "ch: <#{ch.chr}>\n"
        break
    else
        console_output( "." )
        sleep 0.5
    end
  end
333f1bc25c9b3ca4f1bf59a7efc9a79a?d=identicon&s=25 Rubyist (Guest)
on 2006-01-24 18:29
(Received via mailing list)
Gulp! I thought that could be done in two or three lines... :-(
Fc911c27e2e95b4abe12ed98a4b22d69?d=identicon&s=25 Marius Friis (Guest)
on 2006-01-24 21:13
(Received via mailing list)
You might want to look into the curses/ncurses library for Ruby. This
does what
you want, but there might be a bit too much overhead for what your
planning to do.

Another thing that comes to mind is using non-blocking IO on stdin.
not even sure if this is possible tho.
5224d56434a3d237408c217605df8a56?d=identicon&s=25 Payton Swick (Guest)
on 2006-01-25 03:58
(Received via mailing list)
It's just not as easy as it may seem.  This is true of any language.
Basically it depends on the environment (UI) that you're using to
interface with the user.  I would suggest (perhaps) Ncurses, since it's
designed to handle that sort of thing (the shell isn't).  Perhaps I'll
write a simple Ncurses gem to do this for you sometime...

Good luck.

-Payton
09db9a9e7139626ab3f82c66ab3e6449?d=identicon&s=25 Konstantin Levinski (Guest)
on 2006-01-25 04:55
(Received via mailing list)
require 'curses'
def get_char_now();
   Curses.init_screen
   char = Curses.getch
   Curses.close_screen
   return char
end

---
warning - code is approximate, you have to lookup Curses docs.
Depending on your application, it might make sense just to use curses
for everything, then there is no need to start/stop it every time.

Curses work on windows in cygwin, I haven't tried the native installer.
This topic is locked and can not be replied to.