Вывод на консоль при сохранении пользовательского ввода в ruby - PullRequest
5 голосов
/ 03 марта 2010

У меня есть скрипт ruby, который одновременно и асинхронно получает и отображает сообщения с сервера, а также разрешает ввод данных пользователем на консоли. Когда сообщение получено, оно в настоящее время записывается в середине того, что печатает пользователь. Сам вход не искажен, но выглядит ужасно. В идеале это сохранит текущий ввод пользователя, выведет сообщение, а затем восстановит ввод в следующей строке. Я сделал это в c, перехватывая каждое нажатие клавиши, но все, что я помню, это то, что это было серьезной проблемой. Я довольно новичок в ruby, поэтому я не уверен, есть ли хороший способ сделать это или как это сделать.

Пример: пользователь печатает >abcde, и приходит сообщение hello, а пользователь вводит fgh после. Консоль теперь будет показывать:

>abcdehellofgh

и пользователь может продолжить ввод в конце. Я хотел бы показать:

hello
>abcdefgh

Ответы [ 2 ]

2 голосов
/ 11 марта 2010

Две важные части моего предложения:
1. system ("stty raw -echo") # для мгновенного получения любого набранного символа в сочетании с
2. использование STDIN.getc со строковым переменным, служащим в качестве буфера ввода, для перепечатки ввода пользователя.

Нажатие 9 (& логическая переменная input_message) используется для очень простой симуляции сообщений вашего сервера.
(Быть более реалистичным привело бы к раздутию примера, не добавляя много, так как вам все равно придется адаптировать идею к вашему сценарию.)

Нажмите x для выхода.

Пример вывода:

$ ruby simultaneous_input_and_output.rb
Hello World!9
The incoming message is: true
Hello World!9x

You entered:
Hello World!9x
End!



#!/usr/bin/ruby

$input_buffer = "";  
incoming_message = false

begin  
  system("stty raw -echo")  

  begin   
    str = STDIN.getc  
    print str.chr  

    $input_buffer = $input_buffer + str.chr  
    if str.chr == '9'  
      incoming_message = true  
    end  
    if incoming_message   
      puts "\nThe incoming message is: " + incoming_message.to_s  
      print $input_buffer  
      incoming_message = false  
    end  
  end while (str.chr != 'x')  
ensure  
  system("stty -raw echo")  
end  

puts "\n\nYou entered:"   
puts $input_buffer  
puts "End!"    

P.S .: для системы ("stty raw -echo") см. (пользователь Jay) Как получить один символ без нажатия клавиши ввода?

1 голос
/ 03 марта 2010

Я столкнусь с почти такой же проблемой.

Я решил изменить свой подход. Я собираюсь написать простой клиент с текстовым полем ввода внизу и окном сообщений для остальной части экрана.

Клиент и сервер будут обмениваться данными, используя какой-то формат сообщения - YAML, вероятно, поскольку он хорошо работает с Ruby, но это может быть значительно проще.

(Я не уверен, что это точно ответ на ваш вопрос.)

...