Ruby中的一个衬里用于显示提示,获取输入并分配给变量?


79

我经常发现自己在做以下事情:

print "Input text: "
input = gets.strip

是否有一种优美的方法可以一站式完成?就像是:

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

问题在于它在显示提示之前要等待输入。有任何想法吗?


使它成为接受提示文本并返回输入文本的函数吗?如果您想变得更高级并且需要多个提示/输入周期,则可以使该函数采用一系列提示和一个Block,然后遍历这些提示并产生每个输入。
asm

Answers:



76

我认为可以采用类似Marc-Andre建议的方法,但是当您只需要在要使用的任何脚本的顶部定义两行函数时,为什么要引入大量代码:

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

name = prompt "Input name: "

2
确实,这也很好。直到要添加一些输入检查。或一些默认值。或不显示,因为您询问密码什么类型的...
马克-安德烈·Lafortune

4
对于5秒钟的脚本,我会说这是要走的路。
理查森

1
我将附加该.chomp方法,gets否则变量\n末尾将包含换行符。
Toma Nistor

32

一位班轮黑客肯定。优美...不完全是。

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

2
我认为input = (print 'Name: '; gets.rstrip)更具可读性。但是,这两种解决方案都存在nil价值问题。在Ruby 2.3中,可以使用优雅地处理它们input = (print 'Name: '; gets&.rstrip)
michau's

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标准库的一部分,因此您无需安装任何gems。此外,使用时您不能移动光标gets,但可以使用Readline

而且,我知道该方法不是一行,而是当您调用它时

name = input "What is your name? "

“注意:[Readline::readline ]终止ruby解释器,并且在用户等待输入行时按'^ C'后不返回终端状态。”
ma11hew28 2014年

我喜欢这个,@ Andrew Grimm的建议是最好的替代选择highline/import
Chux Uzoeto 2014年


4

您提出的解决方案的问题在于,只有在读取,剥离和分配输入之后才能构建要打印的字符串。您可以用分号分隔每行:

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

5
那不是真正的一行。您使用的是分号,可能不适合他的要求的优美部分。
替代

1
$ ruby​​ -e'print(“ Input text:”)|||(input = gets.strip)&&(puts input)'
Lars Haugseth

1

我偶然发现了Inquirer宝石,我真的很喜欢它,尽管它本身没有输入验证,但我发现它比Highline更加简洁易用。
您的示例可以这样写

require 'inquirer'
inputs = Ask.input 'Input text'
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.