2010-03-03 21 views
5

Tôi có một tập lệnh ruby ​​đồng thời và không đồng bộ nhận và hiển thị tin nhắn từ máy chủ và cho phép người dùng nhập vào bảng điều khiển. Khi nhận được một tin nhắn, nó hiện đang được viết ở giữa những gì người dùng đang gõ. Bản thân đầu vào không bị cắt xén, nhưng có vẻ khủng khiếp. Lý tưởng nhất, nó sẽ lưu đầu vào hiện tại của người dùng, xuất thông báo, và sau đó khôi phục đầu vào trên dòng tiếp theo. Tôi đã làm điều này trong c bằng cách ngăn chặn mọi đột quỵ quan trọng, nhưng tất cả những gì tôi nhớ là nó là một rắc rối lớn. Tôi khá mới với ruby, vì vậy tôi không chắc chắn nếu có một cách tốt để làm điều này, hoặc làm thế nào để làm điều đó.Đầu ra cho bàn điều khiển trong khi vẫn giữ đầu vào của người dùng trong ruby ​​

Ví dụ: Người dùng đang nhập >abcde và thông báo hello xuất hiện và loại người dùng fgh sau đó. Bảng điều khiển sẽ hiển thị:

>abcdehellofgh 

và người dùng có thể tiếp tục nhập ở cuối. Tôi muốn nó hiển thị:

hello 
>abcdefgh 
+1

Bạn có thể chấp nhận một giải pháp sử dụng thư viện ncurses không? –

+0

Chắc chắn. Tôi không quen với gói đó, nhưng tôi sẽ mở để xem ví dụ. – captncraig

+0

Nhìn vào ncurses sâu hơn, nó chắc chắn trông giống như những gì tôi cần, tôi chỉ không chắc chắn làm thế nào để thực hiện điều này cả. Thư viện khá phức tạp, và các ràng buộc ruby ​​không được ghi chép đầy đủ. – captncraig

Trả lời

2

Hai bộ phận quan trọng của đề nghị của tôi là:
1. hệ thống ("-echo liệu stty") # để ngay lập tức nhận được bất kỳ ký tự được nhập nào kết hợp với
2. sử dụng STDIN.getc với một chuỗi-var phục vụ như một bộ đệm đầu vào để in lại đầu vào của người dùng.

Nhấn 9 (& biến boolean incoming_message) được sử dụng để mô phỏng cực kỳ đơn giản cho thông điệp máy chủ của bạn.
(Thực tế hơn sẽ làm nổi bật ví dụ mà không cần thêm nhiều, vì bạn phải điều chỉnh ý tưởng cho kịch bản của mình.)

Nhấn x để thoát.

Mẫu đầu ra:

$ 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!"  

PS: cho hệ thống ("-echo liệu stty") xem (Thành viên Jay) How to get a single character without pressing enter?

+0

Tôi đã làm điều này cho một chương trình trò chuyện được viết cho một lớp mạng. Nó hoạt động rất tốt. – Lolindrath

1

Tôi sẽ phải đối mặt với khá nhiều vấn đề tương tự.

Tôi đã quyết định thay đổi cách tiếp cận của mình. Tôi sẽ viết một máy khách đơn giản có hộp nhập văn bản ở dưới cùng và cửa sổ thông báo cho phần còn lại của màn hình.

Máy khách và máy chủ sẽ trao đổi dữ liệu bằng cách sử dụng một số loại định dạng tin nhắn - YAML, có lẽ, vì nó hoạt động tốt với Ruby, nhưng nó có thể là một cái gì đó đơn giản hơn đáng kể.

(Tôi không chắc chắn này chính là câu trả lời cho câu hỏi của bạn, tuy nhiên.)

+0

Giải pháp tốt của nó, và tôi đồng ý rằng nó có thể là một thiết kế tốt hơn, nhưng tôi hiện đang bị ràng buộc để làm theo cách này. – captncraig

Các vấn đề liên quan