Один лайнер у Ruby для відображення підказки, отримання введення та призначення змінної?


79

Часто я виявляю, що роблю наступне:

print "Input text: "
input = gets.strip

Чи є витончений спосіб зробити це в один рядок? Щось на зразок:

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

Проблема в тому, що він чекає введення перед тим, як відобразити підказку. Будь-які ідеї?


Зробити це функцією, яка приймає підказний текст і повертає введений текст? Якщо ви хочете отримати привабливішого і вам потрібні кілька циклів підказки / введення, ви можете змусити функцію взяти масив підказок і блок, а потім прокрутити по підказках і дати кожен вхід.
asm

Відповіді:



76

Я думаю, що ідеться з чимось на зразок того, що запропонував Марк-Андре, буде правильним шляхом, але навіщо вводити цілу тонну коду, коли ви можете просто визначити дворядкову функцію вгорі будь-якого сценарію, який ви збираєтеся використовувати :

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

name = prompt "Input name: "

2
Дійсно, це теж добре працюватиме. Поки ви не захочете додати деяку перевірку вводу. Або якесь значення за замовчуванням. Або не показувати, що набрано, тому що ви запитуєте пароль ...
Марк-Андре Лафортун

4
Що стосується 5-секундного сценарію, я б сказав, що це такий шлях.
Уілл Річардсон,

1
Я додав би .chompметод після того, як getsінакше змінна містила б \nсимвол нового рядка в кінці.
Тома Ністор

32

Впевнений один лайнер. Витончена ... ну не зовсім так.

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

2
Я думаю, input = (print 'Name: '; gets.rstrip)це читабельніше. Але обидва рішення мають проблеми зі nilзначеннями. У Ruby 2.3 з ними можна витончено впоратися input = (print 'Name: '; gets&.rstrip).
michau

14

Я знаю, що це питання застаріле, але я хотів би показати, що я використовую як свій стандартний метод отримання вхідних даних.

require 'readline'

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

Це дуже приємно, тому що якщо користувач додає дивні пробіли в кінці або на початку, він видаляє їх і зберігає історію того, що вони ввели в минулому (змініть значення trueна, falseщоб не робити цього.). І, якщо ARGVвін не порожній, тоді getsспробує прочитати з файлу ARGV, а не отримувати введення. Крім того, Readlineце частина стандартної бібліотеки Ruby, тому вам не потрібно встановлювати будь-які дорогоцінні камені. Крім того, ви не можете переміщати курсор під час використання gets, але можете за допомогою Readline.

І я знаю, що метод не є одним рядком, але це коли ви його викликаєте

name = input "What is your name? "

"ПРИМІТКА: [Readline::readline ] завершує інтерпретатор ruby ​​і не повертає стан терміналу після того, як користувач натиснув '^ C' під час очікування рядка введення."
ma11hew28,

Мені подобається це та пропозиція @Andrew Grimm як найкращих альтернатив використаннюhighline/import
Chux Uzoeto


4

Проблема із запропонованим рішенням полягає в тому, що рядок, який слід надрукувати, не може бути побудований, доки вхід не буде прочитаний, вилучений та призначений. Ви можете розділити кожен рядок крапкою з комою:

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

5
Це насправді не однорядковий; ви використовуєте крапку з комою, і це, мабуть, не відповідало б витонченій частині його запиту.
альтернатива

1
$ ruby ​​-e 'print ("Введіть текст:") || (input = gets.strip) && (ставить введення)'
Ларс Хогсет,

1

Я знайшов дорогоцінний камінь Inquirer випадково, і мені це дуже подобається, я вважаю його набагато охайнішим і простішим у використанні, ніж Highline, хоча йому не вистачає валідації самостійно.
Ваш приклад можна написати так

require 'inquirer'
inputs = Ask.input 'Input text'
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.