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

79

Часто я делаю следующее:

print "Input text: "
input = gets.strip

Есть ли изящный способ сделать это в одну строку? Что-то вроде:

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

Проблема заключается в том, что он ожидает ввода перед отображением приглашения. Есть идеи?

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

Ответы:

77

Ознакомьтесь с Highline :

require "highline/import"
input = ask "Input text: "
Марк-Андре Лафортюн
источник
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]
rbnewb
источник
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
12

Следуя примеру @Bryn:

def prompt(default, *args)
  print(*args)
  result = gets.strip
  return result.empty? ? default : result
end
Тьяго Фернандес
источник
4

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

$ ruby -e 'print "Input text: "; input=gets.strip; puts input'
Input text: foo
foo
maerics
источник
5
Это не совсем однострочный; вы используете точку с запятой, и это, вероятно, не соответствует изящной части его запроса.
альтернатива
1
$ ruby ​​-e 'print («Ввод текста:») || (input = gets.strip) && (добавляет input) »
Ларс Хаугсет
1

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

require 'inquirer'
inputs = Ask.input 'Input text'
Redithion
источник