首页 > 解决方案 > 在 Ruby 中禁用 OptionParser 标志的自动完成

问题描述

#!/usr/bin/env ruby

require 'optparse'

options = {}
OptionParser.new do |opts|
  opts.on("--language LANGUAGE", ["Ruby", "JavaScript"]) do |language|
    options[:language] = language
  end 
end.parse!

puts "Language: #{options[:language]}"

如果我运行./bin/example --language Ru它,它将输出:

语言:红宝石

我希望禁用此autocomplete/closest match行为并在未提供确切名称时提高 OptionParser 但是我从他们的文档中看不到这样做的方法。

有任何想法吗?

标签: ruby

解决方案


搜索设置定义在 self.regexp

该方法complete似乎返回所有不同的标志。

该方法self.regexp定义了使用的搜索查询

class OptionParser
  module Completion
    def self.regexp(key, icase)
      Regexp.new('\A' + Regexp.quote(key).gsub(/\w+\b/, '\&\w*'), icase)
    end
  end
end

正则表达式是用以下标志构建的

\A从字符串的开头搜索

\w*搜索任何匹配的字符

使用作为with传递的方法对象进行candidate迭代。是在课堂上调用的。 &method(:each)proc&method objectCompletion

candidates = candidate(key, icase, pat, &method(:each)).sort_by {|k, v, kn| kn.size}

iterates里面的方块self.candidate

def self.candidate(key, icase = false, pat = nil, &block)
  pat ||= Completion.regexp(key, icase)
  candidates = []
  block.call do |k, *v|
    // Search and add candidates
  end
  candidates
end

运行以下iterator检查each条目。我仍然没有 100% 理解这个检查,负责查找标志。

block.call do |k, *v|
  (if Regexp === k
     kn = ""
     k === key
   else
     kn = defined?(k.id2name) ? k.id2name : k
     pat === kn
   end) or next
  v << k if v.empty?
  candidates << [k, v, kn]
end
candidates

推荐阅读