【问题标题】:How to include unequivocal information in Exception in Ruby-optparse?如何在 Ruby-optparse 的异常中包含明确的信息?
【发布时间】:2022-08-22 06:24:26
【问题描述】:

在 Ruby 中的 optparse 中定义选项处理时,如果满足某个条件,我想引发异常 (OptionParser::ParseError),然后想救援异常,以便使用自定义消息优雅地退出,而不是让 Ruby 异常中止。

我设法做到了,使用 Exception 对象的error.message (下面附有示例代码,如果给定的参数是奇数,则会引发异常)。但是,我无法检索诸如给出的论点之类的基本信息。

此外,由于该算法依赖于包含在 Exception 对象中的文本消息(字符串),因此从定义上来说,准确错误的检测不可能是完美的。碰巧引发的任何其他异常对象都可能包含类似的字符串。那并不理想。

我怎样才能提出一个目标OptionParser::ParseError,它有关于错误的明确信息并在以后检索信息?

# my_prog.rb 
require \'optparse\'
opts = OptionParser.new() do |opt|
  optnum = nil
  opt.on(\"-n\", \"--num NUM\", Integer, \"must be even\") do |v|
    raise OptionParser::InvalidArgument, \"Odd number\" if v.odd?
    optnum = v
  end

  begin
    opt.parse!(ARGV)
  rescue OptionParser::InvalidArgument => err
    if err.message.include? \"Odd number\"
      # err.message => \"invalid argument: -n Odd number\"
      warn \"--num must be even.\"
      exit 1
    end
    raise
  end
end
p opts

运行my_prog.rb -n 5 会捕获异常(在这种特殊情况下),但例如我无法检索用户给定的选项“5”。

    标签: ruby command-line command-line-arguments


    【解决方案1】:

    更好的方法可能是将自定义 Exception 对象定义为 OptionParser::ParseError 的子类

    然后,您可以完全控制引发异常的方式和时间。然后,当你拯救它时,它是明确的。

    一个OptionParser::ParseError 对象有一个常量Reason 和两个属性argsadditionalReason 说这是什么错误。 args 是一个最多包含 2 个元素的数组,其中第一个元素是给定的主选项,第二个是参数(如果有的话)。 additional 是额外的(我认为它没有记录在案并且可能仅在内部使用,因此规范可能会在未来发生变化?)

    这是示例代码。由于OptionParser 允许指定可选参数的三种形式(short、long 带空格和 long 带=),err.args 相应地具有多种模式。

    # my_prog2.rb
    require 'optparse'
    class NonEvenNumberOption < OptionParser::ParseError
      const_set(:Reason, 'number must be even')
    end
    
    opts = OptionParser.new() do |opt|
      opt.on("-n", "--num NUM", Integer, "must be even") do |v|
        raise NonEvenNumberOption, v if v.odd?
        ### Alternatively,
        # raise NonEvenNumberOption.new(v, additional: "extra info") if v.odd?
        ### which is accessible with  err.additional 
      end
    
      begin
        opt.parse!(ARGV)
      rescue NonEvenNumberOption => err
        # err.args is one of ["-n", 5], ["--num", 5], ["--num=5"]
        warn "ERROR: "+err.reason+": "+err.args.join(" ")
        exit 1
      end
    end
    

    然后,my_prog2.rb -n 5 输出
    ERROR: number must be even: -n 5

    我已经发布了一个相当广泛的Ruby-optparse sample code 要点,其中包括上述要点。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-20
      • 2011-02-18
      • 2014-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多