2

CLIユーティリティとして使用する必要がある Ruby の宝石に取り組んでいます。

コマンドで使用され、非常に柔軟なように見えるThorを使用することにしました ( : linkとの違いについて)。railsrake

問題は、入力エラーを処理する方法が見つからないことです。たとえば、間違ったオプションを入力すると、Thor は自動的に適切な警告を返します。

$ myawesomescript blabla
Could not find command "blabla".

しかし、解決できないコマンドを使用すると、事態は悪化します。たとえば、「help」デフォルト コマンドがあり、「hello」コマンドを定義しました。「h」と入力すると、次のようになります。

$ myawesomescript h
/Users/Tom/.rvm/gems/ruby-2.0.0-p0/gems/thor-0.18.1/lib/thor.rb:424:in `normalize_command_name': Ambiguous command h matches [hello, help] (ArgumentError)
    from /Users/Tom/.rvm/gems/ruby-2.0.0-p0/gems/thor-0.18.1/lib/thor.rb:340:in `dispatch'
    from /Users/Tom/.rvm/gems/ruby-2.0.0-p0/gems/thor-0.18.1/lib/thor/base.rb:439:in `start'
    from /Users/Tom/Documents/ruby/myawesomescript/bin/myawesomescript:9:in `<top (required)>'
    from /Users/Tom/.rvm/gems/ruby-2.0.0-p0/bin/myawesomescript:23:in `load'
    from /Users/Tom/.rvm/gems/ruby-2.0.0-p0/bin/myawesomescript:23:in `<main>'
    from /Users/Tom/.rvm/gems/ruby-2.0.0-p0/bin/ruby_noexec_wrapper:14:in `eval'
    from /Users/Tom/.rvm/gems/ruby-2.0.0-p0/bin/ruby_noexec_wrapper:14:in `<main>'
myawesomescript $

「h」と入力するだけではだめで、コマンドの名前を変更できることはわかっていますが、ユーザーにこの種のエラー メッセージを表示させたくありません。

そのメソッドを次のようにオーバーライドしようとしました:

def normalize_command_name(meth)
  super(meth)
rescue ArgumentError => e
  puts "print something useful"
end

...しかし、うまくいきません


新しい詳細:

OK、そのメソッドはインスタンスではなくクラスで宣言されていることに気付きました。私は次のことを試してみましたが、うまくいくようですが、理想的ではなく、少しハックです:

ファイル: lib/myawesomescript/thor_overrides.rb

require 'thor'

class Thor
  class << self

    protected
      def normalize_command_name(meth)
        return default_command.to_s.gsub('-', '_') unless meth

        possibilities = find_command_possibilities(meth)
        if possibilities.size > 1
          raise ArgumentError, "Ambiguous command #{meth} matches [#{possibilities.join(', ')}]"
        elsif possibilities.size < 1
          meth = meth || default_command
        elsif map[meth]
          meth = map[meth]
        else
          meth = possibilities.first
        end

        meth.to_s.gsub('-','_') # treat foo-bar as foo_bar
      rescue ArgumentError => e
        # do nothing
      end
      alias normalize_task_name normalize_command_name
  end
end

そこに次の行を追加しました。

rescue ArgumentError => e
  # do nothing

そして、それはトリックを行います.どこか別のコードがエラーメッセージを処理しているようです:

$ myawesomescript h
Could not find command "h".

とにかく、もっと良い方法はありますか?

4

1 に答える 1