Question

Comment obtenir un seul caractère du clavier du terminal avec Ruby sans appuyer sur Entrée? J'ai essayé Curses :: getch , mais cela n'a pas vraiment fonctionné pour moi.

Était-ce utile?

La solution

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

(Testé sur mon système OS X, peut ne pas être portable sur toutes les plates-formes Ruby). Voir http://www.rubyquiz.com/quiz5.html pour des suggestions supplémentaires, y compris pour Windows.

Autres conseils

Depuis ruby ??2.0.0, il y a un 'io / console' dans la bibliothèque standard avec cette fonctionnalité

require 'io/console'
STDIN.getch

@Jay a donné une excellente réponse, mais il y a deux problèmes:

  1. Vous pouvez gâcher l'état du tty par défaut;
  2. Vous ignorez les caractères de contrôle (^ C pour SIGINT, etc.).

Une solution simple consiste à enregistrer l'état précédent et à utiliser les paramètres suivants:

  • -icanon - désactive l'entrée canonique (traitement ERASE et KILL);
  • isig - permet de vérifier les caractères par rapport aux caractères de contrôle spéciaux INTR, QUIT et SUSP.

À la fin, vous auriez une fonction comme celle-ci:

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

  STDIN.getc.chr
ensure
  `stty #{state}`
end
Le mode

Raw ( stty raw -echo ) entraîne malheureusement l'envoi de control-C sous forme de caractère et non de SIGINT. Donc, si vous souhaitez bloquer l'entrée comme ci-dessus, mais que vous autorisez l'utilisateur à appuyer sur Control-C pour arrêter le programme en attente, assurez-vous de procéder ainsi:

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

Et si vous voulez une entrée non bloquante - c’est-à-dire, vérifiez périodiquement si l’utilisateur a appuyé sur une touche, mais dans l’intervalle, faites autre chose - vous pouvez le faire:

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

Notez que vous n'avez pas besoin d'un gestionnaire SIGINT spécial pour la version non bloquante car le terminal est en mode brut pendant un bref instant.

Remarque: il s'agit d'une ancienne réponse et la solution ne fonctionne plus sur la plupart des systèmes.

Mais la réponse pourrait toujours être utile pour certains environnements, où les autres méthodes ne fonctionnent pas. Veuillez lire les commentaires ci-dessous.

Vous devez d’abord installer Highline:

gem install highline

Essayez ensuite si la méthode highline fonctionne pour vous:

require "highline/system_extensions"
include HighLine::SystemExtensions

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

Et si vous construisez une malédiction , vous devez appeler

.
nocbreak

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top