# How to capture a pressed key?

**URL:** <https://www.ruby-forum.com/t/how-to-capture-a-pressed-key/96674>\
**Category:** Ruby\
**Created:** [January 24, 2006, 5:58pm UTC](https://www.ruby-forum.com/t/how-to-capture-a-pressed-key/96674 "2006-01-24T17:58:57Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![rubyist](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/bbe5ce/32.png) [@rubyist](https://www.ruby-forum.com/u/rubyist)\
**Post date:** [January 24, 2006, 5:58pm UTC](https://www.ruby-forum.com/t/how-to-capture-a-pressed-key/96674/1 "2006-01-24T17:58:57Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![rubyist](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/bbe5ce/32.png) [@rubyist](https://www.ruby-forum.com/u/rubyist)\
**Post date:** [January 24, 2006, 6:05pm UTC](https://www.ruby-forum.com/t/how-to-capture-a-pressed-key/96674/2 "2006-01-24T18:05:06Z")

</div>

print "Enter your name: "  
name = gets

[http://www.rubycentral.com/book/tut\_io.html](http://www.rubycentral.com/book/tut_io.html)

to get the first letter of ‘name’ you would access it by name[0,1]

---

<div class="post-metadata">

**Author:** ![rubyist](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/bbe5ce/32.png) [@rubyist](https://www.ruby-forum.com/u/rubyist)\
**Post date:** [January 24, 2006, 6:14pm UTC](https://www.ruby-forum.com/t/how-to-capture-a-pressed-key/96674/3 "2006-01-24T18:14:28Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![rubyist](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/bbe5ce/32.png) [@rubyist](https://www.ruby-forum.com/u/rubyist)\
**Post date:** [January 24, 2006, 6:29pm UTC](https://www.ruby-forum.com/t/how-to-capture-a-pressed-key/96674/4 "2006-01-24T18:29:45Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![rubyist](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/bbe5ce/32.png) [@rubyist](https://www.ruby-forum.com/u/rubyist)\
**Post date:** [January 24, 2006, 6:29pm UTC](https://www.ruby-forum.com/t/how-to-capture-a-pressed-key/96674/5 "2006-01-24T18:29:46Z")

</div>

Gulp! I thought that could be done in two or three lines… ☹

---

<div class="post-metadata">

**Author:** ![rubyist](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/bbe5ce/32.png) [@rubyist](https://www.ruby-forum.com/u/rubyist)\
**Post date:** [January 25, 2006, 3:58am UTC](https://www.ruby-forum.com/t/how-to-capture-a-pressed-key/96674/6 "2006-01-25T03:58:44Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![rubyist](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/bbe5ce/32.png) [@rubyist](https://www.ruby-forum.com/u/rubyist)\
**Post date:** [January 24, 2006, 9:13pm UTC](https://www.ruby-forum.com/t/how-to-capture-a-pressed-key/96674/7 "2006-01-24T21:13:44Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![rubyist](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/bbe5ce/32.png) [@rubyist](https://www.ruby-forum.com/u/rubyist)\
**Post date:** [January 25, 2006, 4:55am UTC](https://www.ruby-forum.com/t/how-to-capture-a-pressed-key/96674/8 "2006-01-25T04:55:56Z")

</div>

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.
