在Ruby中输出控制台并保留用户输入

5
我有一个Ruby脚本,同时异步地从服务器接收和显示消息,并允许用户在控制台上输入。当接收到消息时,它目前正在被写入到用户正在输入的内容中间。输入本身并不会混乱,但看起来很糟糕。理想情况下,它应该保存用户当前的输入,在下一行输出消息,然后恢复输入。我曾经在C语言中做过类似的事情,但我记得那是非常麻烦的。我对Ruby比较新,所以我不确定是否有好的方法来解决这个问题,或者如何解决。
示例:用户正在输入>abcde,此时收到消息hello,然后用户继续输入fgh。控制台现在将显示:
>abcdehellofgh

用户可以在结尾继续输入。我希望它显示为:
hello
>abcdefgh

1
你能接受一个使用ncurses库的解决方案吗? - Wayne Conrad
当然。我不熟悉那个包,但我很愿意看一个例子。 - captncraig
深入研究ncurses后,它看起来确实是我需要的东西,但我完全不确定如何实现。该库相当复杂,而且ruby绑定文档不太完善。 - captncraig
2个回答

2
我的提议的两个重要部分是:
1. system("stty raw -echo") # 与
结合使用,立即获取任何键入的字符
2. 使用带有字符串变量作为输入缓冲区的 STDIN.getc 以重新打印用户输入。

按9(和布尔变量 incoming_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.: 要使用system("stty raw -echo")请参考Jay用户的建议。 如何在不按回车键的情况下获取单个字符?


我为一个网络课程编写的聊天程序做了这个。它运行得非常好。 - Lolindrath

1

我将面临几乎相同的问题。

我决定改变我的方法。我将编写一个简单的客户端,底部有一个文本输入框和一个消息窗口占据屏幕的其余部分。

客户端和服务器将使用某种消息格式交换数据--可能是 YAML,因为它与 Ruby 配合得非常好,但也可以是更简单的东西。

(我不确定这是否完全回答了你的问题。)


这是一个不错的解决方法,我同意这可能是更好的设计,但目前我受到限制只能用这种方式来做。 - captncraig

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接