web-dev-qa-db-ja.com

Rubyのoptparseを使用して名前のない引数を解析する方法

次のようなコマンドラインを解析する必要があります

  script.rb <mandatory filename> [options]

optparse で。

確かに、ファイル名を処理するカスタムコードを記述してから、ARGVをoptparseに渡すことができますが、もっと簡単な方法があるのではないでしょうか。

編集:そのようなコマンドラインを解析する別のハッキーな方法があります。それは、['--mandatory-filename'] + ARGVをoptparseに渡してから、--mandatory-filenameオプションを処理することです。

33
Leonid Shevtsov

最初 parse! optparseを使用して、ARGVをスキャンし、ARGVが空の場合はレイズします。そのようです:

op.parse!
filename = ARGV.pop
raise "Need to specify a file to process" unless filename

必須のファイル名はOptionParserによって処理されず、ARGVに残されます。存在しない場合は、手動で発生させてください。

46
Julik

JulikとShadowfirebirdが言ったことをフォローアップするために:OptionParserで解析するときは、parse!parseの機能が異なることに注意してください。前者は、渡された配列から理解できるすべての引数を削除し、後者はそれらを残します。これにより、必要な引数が存在するかどうかを判断するための条件が変更されます。

9
Geoff

すべての状況に当てはまるわけではありませんが、次のように1つのコマンドラインで複数のファイルを処理できると便利なことがよくあります。

script.rb [options] file1 file2 ...

file1は必須ですが、file2以降はオプションです。

これを行うために私が知っている最善の方法は、次の規則に従います。

options = {}
optparse = OptionParser.new do |opts|
  opts.banner = "Usage: script.rb [options] file1 file2 ..."

  opts.on('-a', '--an-option ARG', 'Set some option') do |arg|
    options[:a] = arg
  end

  ...
end
optparse.parse!

# Check required conditions
if ARGV.empty?
  puts optparse
  exit(-1)
end

ファイルが提供されていない場合は、使用状況バナーとオプションの説明を含むヘルプメッセージが表示されます。ファイルが存在する場合、ARGVに残るのはそれらだけです。

5
adamlamar

最近追加されたかどうかはわかりませんが、以前の回答のいずれにもoptparse.parseは、解析されたオプションを削除した後、ARGV値を返します。

これを行う場合:

rest = optparse.parse!

指定されたファイルを含む配列を取得します(不明なオプションとともに)。このように、オプションがファイルの前にあるか後にあるかを気にする必要はありません。

2
SystematicFrank

Optparseは、パラメーターAFAIKを使用した引数のみを実行します。ファイル名を処理する「正しい」方法は、optparseの外部で処理することです。 this の質問に答えて、このためのサンプルコードをいくつか投稿しました。

ところで、それはかなり珍しいコマンドラインです。それがあなたのためだけなら、結構ですが、他の人はそれがかなり直感に反していると感じるでしょう。 script.rb [options] <filename>.。

0
Shadowfirebird