Ruby 在上一个带参数的获取之后跳过获取

Ruby skipping gets after previous gets with parameter

我有一个使用 gets 参数的多行输入,效果很好。问题是它跳过了我的下一个 gets...

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

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

前两行 运行 符合预期(我可以输入多行文本,直到我输入 done 并按回车键)。然后打印 "One line response: " 并退出程序。我从来没有输入过 oneLine。

为什么会这样?

Kernel#gets 实际上可以带一个参数,一个分隔符。这告诉 Ruby 何时停止从标准输入读取。如果您不提供此参数,则使用默认值 \n ($/)。以下是您的程序运行时发生的情况:

  • gets 询问所有内容,直到第一个 done
  • 你输入一些东西,然后输入完成,然后按回车键。这是关键,因为现在输入流以 done\n 结尾,但 gets 只读到 done.
  • gets 询问所有内容,直到第一个 \n 这个 \ndone 之后立即找到,并且 gets 已经有了它,因为你已经输入它,这样它就不会再要求您了。

这就是为什么您在第一个 gets 之后没有机会输入任何内容的原因。要消除此问题,您应该将分隔符设置为 "done\n",或者如果您希望它严格在自己的行上,则可能设置为 "\ndone\n"

当调用 gets("done") 时,Ruby 读取 STDIN,直到它找到任何 done。这不一定需要在一行上,甚至不需要在行的开头或结尾。一旦您输入包含 done.

的行,Ruby 将 return

现在,Ruby 将只读取输入,直到它消耗完 done。输入的其余部分不会被读取,但会保存在缓冲区中。因此,在您的情况下,如果您在终端中输入包含 done 的单行并按回车键,Ruby 将只消耗完成而不消耗换行符。

换行符(或者通常是 done 之后的其余行)只会被下一个 gets 使用。因此,您的第二个 gets return 直接。

要解决此问题,比使用 gets 的分隔符参数更好的方法是使用循环:

response = ""
while line = gets do
  response << line
  break if line == "done\n"
end
response.chomp!