How to capture a pressed key?

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.

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]

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

Rubyist wrote:

···

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.

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.

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.

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

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.

···

On 24. jan. 2006, at 16.56, Rubyist wrote:

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.

--
Marius Friis
mariusfriis@mac.com

Gulp! I thought that could be done in two or three lines... :frowning: