Рубиновый пропуск получает после предыдущего получения с параметром

У меня есть многострочный ввод с использованием параметра Get, который прекрасно работает. Проблема в том, что он пропускает мой следующий получает...

print "Multi-line response: "
response = gets("done").chomp

print "One line response: "
oneLine = gets.chomp

Первые две строки работают как положено (я могу вводить несколько строк текста, пока не наберу готово и не нажму клавишу ввода). Затем он печатает "Однострочный ответ: " и выходит из программы. Я никогда не получаю вход для oneLine.

Почему это происходит?

2 ответа

Решение

Kernel#gets может на самом деле принять аргумент, разделитель. Это говорит Ruby, когда прекратить чтение из стандартного ввода. Если вы не предоставите этот аргумент, значение по умолчанию \n ($/) используется. Вот что происходит при запуске вашей программы:

  • gets просит все до первого done,
  • Вы набираете что-то, затем набираете "Готово", затем нажимаете "Ввод". Это ключ, потому что теперь поток ввода заканчивается done\n но gets только прочитал до done,
  • gets просит все до первого \n это \n находится сразу после done, а также gets уже есть, потому что вы уже набрали его, чтобы он больше не просил вас.

Вот почему у вас нет возможности вводить что-либо после первого gets, Чтобы устранить эту проблему, вы должны сделать разделитель "done\n"или возможно "\ndone\n", если вы хотите, чтобы он был строго на своей линии.

При звонке gets("done") Руби читает STDIN, пока не найдет done, Это не обязательно должно быть в одной строке или даже в начале или конце строки. Ruby вернется, как только вы введете строку, содержащую done,

Теперь Ruby будет просто читать ввод, пока он не израсходует done, Остальная часть ввода не будет прочитана, но будет сохранена в буфере. Таким образом, в вашем случае, если вы введете одну строку, содержащую done в ваш терминал и нажмите Enter, Ruby будет использовать только готовый, но не перевод строки.

Новая строка (или, как правило, остальная часть строки после done) будет потребляться только следующим gets, Из-за этого ваш второй gets возвращается напрямую.

Чтобы это исправить, лучше использовать аргумент-разделитель, чтобы gets это использовать цикл:

response = ""
while line = gets do
  response << line
  break if line == "done\n"
end
response.chomp!
Другие вопросы по тегам