Pregunta

¿Cómo puedo obtener un solo carácter de teclado del terminal con Ruby sin presionar Intro? Intenté Curses :: getch , pero eso no me funcionó.

¿Fue útil?

Solución

http: //blade.nagaokaut. ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/2999

#!/usr/bin/ruby

begin
  system("stty raw -echo")
  str = STDIN.getc
ensure
  system("stty -raw echo")
end
p str.chr

(Probado en mi sistema OS X, puede que no sea portátil para todas las plataformas Ruby). Consulte http://www.rubyquiz.com/quiz5.html para obtener algunas sugerencias adicionales, incluso para Windows.

Otros consejos

Desde Ruby 2.0.0, hay una 'io / console' en la barra de datos con esta función

require 'io/console'
STDIN.getch

@Jay dio una gran respuesta, pero hay dos problemas:

  1. Puedes estropear el estado tty predeterminado;
  2. Ignora los caracteres de control (^ C para SIGINT, etc.).

Una solución simple para eso es guardar el estado anterior de tty y usar los siguientes parámetros:

  • -icanon : deshabilita la entrada canónica (procesamiento ERASE y KILL);
  • isig : habilita la comprobación de los caracteres frente a los caracteres de control especiales INTR, QUIT y SUSP.

Al final, tendrías una función como esta:

def get_char
  state = `stty -g`
  `stty raw -echo -icanon isig`

  STDIN.getc.chr
ensure
  `stty #{state}`
end
El modo

Raw ( stty raw -echo ) desafortunadamente hace que el control-C se envíe como un carácter, no como un SIGINT. Entonces, si desea bloquear entradas como las anteriores, pero permitir que el usuario presione control-C para detener el programa mientras está esperando, asegúrese de hacer esto:

Signal.trap("INT") do # SIGINT = control-C
  exit
end

Y si desea una entrada sin bloqueo, es decir, verifique periódicamente si el usuario ha presionado una tecla, pero mientras tanto, vaya a hacer otras cosas, entonces puede hacer esto:

require 'io/wait'

def char_if_pressed
  begin
    system("stty raw -echo") # turn raw input on
    c = nil
    if $stdin.ready?
      c = $stdin.getc
    end
    c.chr if c
  ensure
    system "stty -raw echo" # turn raw input off
  end
end

while true
  c = char_if_pressed
  puts "[#{c}]" if c
  sleep 1
  puts "tick"
end

Tenga en cuenta que no necesita un controlador SIGINT especial para la versión sin bloqueo, ya que tty solo está en modo raw por un breve momento.

Nota: Esta es una respuesta anterior y la solución ya no funciona en la mayoría de los sistemas.

Pero la respuesta aún podría ser útil para algunos entornos, donde los otros métodos no funcionan. Por favor, lea los comentarios a continuación.


Primero debes instalar highline:

gem install highline

A continuación, intente si el método de Highline funciona para usted:

require "highline/system_extensions"
include HighLine::SystemExtensions

print "Press any key:"
k = get_character
puts k.chr

Y si está creando la aplicación curses , debe llamar

nocbreak

http: //www.ruby-doc.org/stdlib-1.9.3/libdoc/curses/rdoc/Curses.html#method-c-cbreak

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top