2010-05-22 23 views
66

Thường thì tôi thấy mình làm như sau:Một lớp lót trong Ruby để hiển thị lời nhắc, nhận đầu vào và gán cho một biến?

print "Input text: " 
input = gets.strip 

Có cách duyên dáng để làm điều này trong một dòng? Một cái gì đó như:

puts "Input text: #{input = gets.strip}" 

Vấn đề với điều này là nó chờ đầu vào trước khi hiển thị lời nhắc. Bất kỳ ý tưởng?

+0

Biến nó thành hàm có văn bản nhập và trả về văn bản nhập liệu? Nếu bạn muốn nhận được fancier và cần nhiều chu kỳ nhắc nhở/đầu vào, bạn có thể làm cho hàm nhận một mảng các lời nhắc và một Block sau đó lặp qua các lời nhắc và mang lại cho mỗi đầu vào. – asm

Trả lời

67

Check-out highline:

require "highline/import" 
input = ask "Input text: " 
4

Vấn đề với giải pháp đề xuất của bạn là chuỗi cần in không thể được xây dựng cho đến khi đầu vào được đọc, tước, và được giao. Bạn có thể tách riêng từng dòng bằng dấu chấm phẩy:

$ ruby -e 'print "Input text: "; input=gets.strip; puts input' 
Input text: foo 
foo 
+5

Đó không thực sự là một dòng; bạn đang sử dụng dấu chấm phẩy và điều đó có lẽ sẽ không phù hợp với phần duyên dáng của yêu cầu của anh ấy. – alternative

+1

$ ruby ​​-e 'print ("Văn bản đầu vào:") || (input = gets.strip) && (đặt đầu vào)' –

64

Tôi nghĩ rằng đi với một cái gì đó giống như những gì Marc-Andre gợi ý sẽ là con đường để đi, nhưng tại sao mang lại một tấn toàn bộ mã khi bạn chỉ có thể xác định một chức năng hai dòng ở trên cùng của bất kỳ tập lệnh nào bạn sẽ sử dụng:

def prompt(*args) 
    print(*args) 
    gets 
end 

name = prompt "Input name: " 
+2

Thật vậy, điều đó cũng sẽ hoạt động tốt. Cho đến khi bạn muốn thêm một số kiểm tra đầu vào. Hoặc một số giá trị mặc định.Hoặc không hiển thị những gì được nhập bởi vì bạn yêu cầu mật khẩu ... –

+4

Đối với tập lệnh 5 giây, tôi sẽ nói rằng đây là cách để thực hiện. – javanut13

28

One liner hack sure. Duyên dáng ... cũng không chính xác.

input = [(print 'Name: '), gets.rstrip][1] 
+12

Đó chỉ là đủ xấu để làm việc! –

+1

Tôi nghĩ 'input = (print 'Name:'; gets.rstrip)' dễ đọc hơn. Nhưng cả hai giải pháp đều có vấn đề với giá trị 'nil'. Trong Ruby 2.3 chúng có thể được xử lý một cách duyên dáng với 'input = (print 'Name:'; get & .rstrip)'. – michau

11

Sau @ dẫn Bryn của:

def prompt(default, *args) 
    print(*args) 
    result = gets.strip 
    return result.empty? ? default : result 
end 
8

Tôi biết câu hỏi này là cũ, nhưng tôi mặc dù tôi muốn hiển thị những gì tôi sử dụng như phương pháp tiêu chuẩn của tôi để có được đầu vào.

require 'readline' 

def input(prompt="", newline=false) 
    prompt += "\n" if newline 
    Readline.readline(prompt, true).squeeze(" ").strip 
end 

Đây là thật sự tốt đẹp bởi vì nếu người dùng thêm không gian kỳ lạ ở cuối hay ở đầu, nó sẽ loại bỏ những người, và nó giữ một lịch sử của những gì họ bước vào trong quá khứ (Thay đổi true để false để không làm điều đó.). Và nếu ARGV không trống, thì gets sẽ cố gắng đọc từ một tệp trong ARGV, thay vì nhận dữ liệu nhập. Ngoài ra, Readline là một phần của thư viện chuẩn của Ruby nên bạn không phải cài đặt bất kỳ loại đá quý nào. Ngoài ra, bạn không thể di chuyển con trỏ khi sử dụng gets, nhưng bạn có thể với Readline.

Và, tôi biết phương pháp này không phải là một dòng, nhưng nó là khi bạn gọi nó

name = input "What is your name? " 
+0

"LƯU Ý: [[' Readline :: readline'] (http://www.ruby-doc.org/stdlib-2.1.1/libdoc/readline/rdoc/Readline.html#method-c-readline)] chấm dứt thông dịch viên ruby ​​và không trả lại trạng thái thiết bị đầu cuối sau khi người dùng nhấn '^ C' khi đợi đường vào. " – ma11hew28

+0

Tôi thích đề xuất này và đề xuất của @Andrew Grimm là giải pháp thay thế tốt nhất để sử dụng 'highline/import' –

1

Tôi tìm thấy Inquirer đá quý một cách tình cờ và tôi thực sự thích nó, tôi thấy nó cách gọn gàng hơn và dễ sử dụng hơn Highline, mặc dù nó thiếu xác nhận đầu vào của chính nó.
Ví dụ của bạn có thể được viết như thế này

require 'inquirer' 
inputs = Ask.input 'Input text' 
Các vấn đề liên quan