Ruby中的预填充提示符
我正在使用Ruby编写一个用于搜索Pubmed的小命令行实用程序。现在,我提示用户进行查询并显示结果,用户可以选择附加到查询或输入全新的查询。我想添加编辑当前查询的功能;i、 e.提示应预先填写上一个查询的可编辑版本,如下所示:Ruby中的预填充提示符,ruby,command-prompt,Ruby,Command Prompt,我正在使用Ruby编写一个用于搜索Pubmed的小命令行实用程序。现在,我提示用户进行查询并显示结果,用户可以选择附加到查询或输入全新的查询。我想添加编辑当前查询的功能;i、 e.提示应预先填写上一个查询的可编辑版本,如下所示: Enter query: <PREVIOUS QUERY HERE> 然后在DbHippo::Source的一个方法中,我有: RbReadline.prefill_prompt(query) query = Readline.readline("Quer
Enter query: <PREVIOUS QUERY HERE>
然后在DbHippo::Source的一个方法中,我有:
RbReadline.prefill_prompt(query)
query = Readline.readline("Query: ", true)
查询变量肯定不是空的,但是由于某种原因,在这个上下文中,提示符没有被预先填充。我还注意到,如果我将扩展名放在同一个文件(lib/db_hippo/rb readline)中,而不将其作为DbHippo的子模块,则会得到错误:行上的未初始化常量DbHippo::Source::readline(namererror):
query = Readline.readline("Query: ", true)
这一切似乎都与模块、require语句和gems的正确命名有关。这是我尝试制作的第一块宝石。你知道这里出了什么问题吗?你可以用:
也许谷歌会发现这很有用 使用Ruby 2.1上的纯
Readline
,您可以使用:
def ask(prompt, default=nil)
if default
Readline.pre_input_hook = -> {
Readline.insert_text(default)
Readline.redisplay
# prevent re-trigger on every `readline`
Readline.pre_input_hook = nil
}
end
data = Readline.readline("#{prompt}: ")
return data.chomp
end
ask("MOAR...?", "COMPUTARS!") # displays: MOAR...? COMPUTARS!
在提示下,文本
COMPUTARS代码>将可编辑是。您不能将我的扩展代码放入DbHippo
模块中。这是因为我的扩展代码是monkey patchingRbReadline
,这是一个顶级模块。如果将补丁代码放入DbHippo
中,您将创建一个新模块DbHippo::RbReadline
,并且原始未补丁代码仍将存在于顶级RbReadline
模块中。除此之外,您现在有两个RbReadline
模块,ruby将很难区分它们。因此,使一切工作都非常糟糕:-/所以只需将我的monkey补丁保持在顶层,您就可以了。我通常在lib
dir中创建一个名为extensions
或类似的文件夹,把所有的猴子补丁都放进去。然后您只需要求“db hippo/extensions/rb readline”
,任何阅读代码的人都会非常清楚发生了什么。还要注意的是,在需要扩展代码之前,您必须要求“rb readline”
。确保它按正确的顺序运行,否则它将无法工作。如果您不确定是否将扩展文件重命名为其他文件,例如readline patch.rb
,以确保在包含补丁代码之前包含rb readline
gem(当您有一个与全局gem同名的文件时,可能会混淆rubygems)。很好的解释,我现在已经完成了所有工作。谢谢你的帮助!经过数小时的搜索、谷歌搜索和挖掘,我终于找到了一个非常干净的解决方案,多亏了你们!!非常感谢。但是,在钩子处理程序中清除Readline.pre\u input\u hook
是非常谨慎的。如果不这样做,它将继续在每个读取行上触发(包括irb
prompt:D)
query = Readline.readline("Query: ", true)
require 'rubygems'
require 'rb-readline'
module RbReadline
def self.prefill_prompt(str)
@rl_prefill = str
@rl_startup_hook = :rl_prefill_hook
end
def self.rl_prefill_hook
rl_insert_text @rl_prefill if @rl_prefill
@rl_startup_hook = nil
end
end
RbReadline.prefill_prompt("Previous query")
str = Readline.readline("Enter query: ", true)
puts "You entered: #{str}"
def ask(prompt, default=nil)
if default
Readline.pre_input_hook = -> {
Readline.insert_text(default)
Readline.redisplay
# prevent re-trigger on every `readline`
Readline.pre_input_hook = nil
}
end
data = Readline.readline("#{prompt}: ")
return data.chomp
end
ask("MOAR...?", "COMPUTARS!") # displays: MOAR...? COMPUTARS!