1. ホーム
  2. ruby

[解決済み] Rubyで本当に安いコマンドラインオプションのパース

2022-08-30 11:14:07

質問

編集: お願いします。 をお願いします。 , をお願いします。 は、返信する前に、この投稿の下部に記載されている2つの要件を読んでください。人々は、明らかに要件を満たしていない彼らの新しい宝石やライブラリや何物かを投稿し続けています。

時々、簡単なスクリプトにいくつかのコマンドライン オプションを非常に安価にハックしたいと思います。getopts やパース、またはそのようなものを扱うことなく、それを行う楽しい方法は、次のとおりです。

...
$quiet       = ARGV.delete('-d')
$interactive = ARGV.delete('-i')
...
# Deal with ARGV as usual here, maybe using ARGF or whatever.

これは通常の Unix オプション構文とは異なり、" のようなオプション以外のコマンドラインパラメータを受け付けるからです。 myprog -i foo bar -q のように、オプション以外のコマンド ライン パラメータを受け入れるため、通常の Unix オプション構文とは異なりますが、私はこれに耐えることができます。(Subversionの開発者のように、これを好む人もいます。時々私もそうします)。

存在するかしないかだけのオプションは、上記よりもはるかに単純に実装することができません。(1つの代入、1つの関数呼び出し、1つの副作用。) " のようなパラメータを取るオプションを扱う、同様にシンプルな方法はありますか? -f ファイル名 "?

EDITです。

トロロップの作者が「ライブラリは 1 つの [800 行] ファイルに収まる」と言及するまでわからなかったので、先ほどは言わなかったのですが、私はきれいな構文だけでなく、次のような特徴を持つ手法も求めています。

  1. コードの全体をスクリプト ファイルに含めることができる (実際のスクリプト自体は数十行に過ぎないかもしれませんが、それを圧倒することなく)、1 つのファイルを bin ディレクトリにドロップして使うことができます。もし、require 文がなく、いくつかのオプションを解析するコードが数十行以下であるような Ruby スクリプトを書けないのであれば、この要件は不合格です。

  2. コードは、どこか他の場所からカットアンドペーストするのではなく、トリックを実行するコードを直接入力するために、そのコードを十分に記憶できるほど小さく、シンプルであることです。インターネットにアクセスできないファイアウォールで保護されたサーバーのコンソールにいて、クライアントが使用するスクリプトをすばやく作成したい状況を考えてみてください。あなたのことは知りませんが、(上記の要件を満たせないことに加えて) 簡略化したマイクロオプトパースの 45 行を記憶することさえ、私には気にならないことなのです。

どのように解決するのですか?

私がいつも使っている標準的なテクニックを紹介します。

#!/usr/bin/env ruby

def usage(s)
    $stderr.puts(s)
    $stderr.puts("Usage: #{File.basename($0)}: [-l <logfile] [-q] file ...")
    exit(2)
end

$quiet   = false
$logfile = nil

loop { case ARGV[0]
    when '-q' then  ARGV.shift; $quiet = true
    when '-l' then  ARGV.shift; $logfile = ARGV.shift
    when /^-/ then  usage("Unknown option: #{ARGV[0].inspect}")
    else break
end; }

# Program carries on here.
puts("quiet: #{$quiet} logfile: #{$logfile.inspect} args: #{ARGV.inspect}")