【问题标题】:Ruby optparse behavior wrt InvalidOption vs MissingArgument exceptionsRuby optparse 行为 wrt InvalidOption vs MissingArgument 异常
【发布时间】:2014-09-01 18:39:50
【问题描述】:

我有一个 ruby​​ cli 解析脚本,似乎存在某种用于解析选项的正则表达式行为:

op = OptionParser.new do |x|

      x.on("--output-config PATH", "The filesystem location for the output config file") do |output_config|
        options[:output_config] = output_config
      end

      x.on("-j", "--json", "If this is set, then json is output instead of tabular form") do 
         options[:disp_json] = true
      end

       x.on("-h", "--help", "Show this message") do 
        puts op
        exit 0
       end

       x.on("-v", "--version", "Show version") do 
         puts "version #{VERSION_NUMBER}"
         exit 0
       end
  end


  # do input validation and check leftovers for proper commands
  begin
  # parse options, parse! removes elements from ARGV so leftovers are positional arg(s)
    op.parse!(ARGV)
    options[:config_file] = ARGV[0] if ARGV[0]

  rescue OptionParser::InvalidOption, OptionParser::MissingArgument
    puts "###############  #{$!.to_s}  ###############"
    puts ""
    puts op
    exit 1
  end

如果我这样称呼它:

script -a

它输出以下(预期行为)

###############  invalid option: -a  ###############

或者

script --output-config

它输出以下(预期行为)

###############  missing argument: --output-config  ###############

所以这就是奇怪的地方:

script --output

它输出以下(不是预期的行为)

 ###############  missing argument: --output  ###############

或者

script --ou

它输出以下(不是预期的行为)

 ###############  missing argument: --ou  ###############

基本上,您传递的任何与正则表达式匹配的“输出配置”都会传递给块

x.on("--output-config PATH"....

这是我看到的 MissingArgument 与 InvalidOption 行为的原因。

是我使用 optparse 错误还是库中的错误?

####### 编辑

如果我添加另一个 x.on:

x.on("--out PATH", "The filesystem location for the output config file") do |output_config|
    options[:output_config2] = output_config
end

并传递-o(一个破折号,即一个短格式)或--o(两个破折号),它不会抛出异常(我专门在处理未执行时拯救了OptionParser::AmbiguousOption)。而是执行最短匹配,即 --out。如果我通过--outp,则执行较长的那个。这对我来说似乎很不稳定。

####### 编辑 2
> ./my_app --output-c
###############  missing argument: --output-c

MissingArgument 异常仅将标志显示为已通过,而不是“预期”。它清楚地知道它与“--output-config”匹配,所以我希望能够知道这一点,以便我给用户的错误消息清晰明确。有没有一种方法可以确定在引发 MissingArgument 异常时匹配的 optparser 是什么?

【问题讨论】:

    标签: ruby command-line-interface optparse


    【解决方案1】:

    这是带有长选项的标准行为。我很难找到任何支持文档,但只要我一直在使用长选项(即从很久以前开始),我就一直在使用长选项的这个功能。

    您可以使用 GNU 版本的 ls(1) 轻松查看:

    $ ls --h
    ls: option '--h' is ambiguous
    Try `ls --help' for more information.
    
    $ ls --he
    Usage: ls [OPTION]... [FILE]...
    List information about the FILEs (the current directory by default).
    Sort entries alphabetically if none of -cftuvSUX nor --sort.
    ...
    
    $ ls --help
    Usage: ls [OPTION]... [FILE]...
    List information about the FILEs (the current directory by default).
    Sort entries alphabetically if none of -cftuvSUX nor --sort.
    ...
    

    有多个选项以--h 开头所以--h 是选项错误,只有一个选项以--he 开头所以--he--help 相同。

    如果您添加了--output-pancakes 选项,那么如果您说--output,您应该会收到关于歧义的投诉,但--output-c--output-p 会起作用。

    您没有错误地使用该库。这也不是一个错误。这是一项功能。

    【讨论】:

    • --out 不同,--out 与选项完全匹配,因此没有歧义。如果我添加一个--output-pancakes PATH 选项并只使用--output,那么我会得到一个OptionParser::AmbiguousOption。解析是故意模糊的。
    • 好的,刚刚确认你说的是真的。它会自动将短格式转换为长格式这一事实呢?此外,如果 optparse 自动尝试匹配选项(即 --ou => --out)只是一个事实,那么当捕获 MissingArgument 异常时,很高兴知道该参数缺少哪个显式列出的选项,所以用户可以看到帮助菜单并知道哪个选项有他们留下的必需参数。
    • 您能否更新您的问题以涵盖您最后的评论,以便我可以看到您在做什么?
    猜你喜欢
    • 2014-01-21
    • 2022-08-22
    • 2013-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多