Один лайнер в 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) && (добавляет input) »
Ларс Хаугсет

1

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

require 'inquirer'
inputs = Ask.input 'Input text'
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.