5

我正在使用 Ruby 编写一个小型命令行实用程序来搜索 Pubmed。现在,我提示用户进行查询并显示结果,用户可以选择附加到查询或输入全新的查询。我想添加编辑当前查询的功能;即提示应该预先填充上一个查询的可编辑版本,如下所示:

Enter query: <PREVIOUS QUERY HERE>

在提示旁边打印出上一个查询很容易,但是如何使此输出可编辑,就好像用户自己键入一样?

@casper:感谢您对 Casper 的回复。我尝试了您在下面提供的代码,它确实可以自行运行。奇怪的是,当我尝试在 gem 中使用它时,它似乎不起作用。我的 gem 叫做 db_hippo。我在 gemspec 中添加了 rb-readline 作为依赖项,并将 RbReadline 的扩展名放在 lib/db_hippo/rb-readline.rb

module DbHippo
  module RbReadline
    <CASPER'S EXTENSION HERE>
  end
end

我希望在 DbHippo 的另一个子模块 DbHippo::Source 中使用该功能。在 DbHippo::Source 中,我在顶部添加了:

require 'rb-readline'
require 'db_hippo/rb-readline'

然后在 DbHippo::Source 的一种方法中,我有:

RbReadline.prefill_prompt(query)
query = Readline.readline("Query: ", true)

查询变量绝对不是空的,但由于某种原因,在这种情况下,提示不会被预填充。我还注意到,如果我将扩展名放在同一个文件 (lib/db_hippo/rb-readline) 中而不使其成为 DbHippo 的子模块,我会收到错误:未初始化的常量 DbHippo::Source::Readline (NameError)在线:

query = Readline.readline("Query: ", true)

这一切似乎都与模块、require 语句和 gem 的正确命名有关。这是我尝试构建的第一个宝石。知道这里出了什么问题吗?

4

2 回答 2

5

也许谷歌人会发现这很有用。

在 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!将是可编辑的

于 2014-06-01T00:04:57.193 回答
3

你可以用RbReadline做到这一点:

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}"
于 2012-06-14T02:17:33.780 回答