コマンドライン引数の処理は、スクリプト起動時に渡されたすべてのパラメータを含む組み込み配列@ARGVを介して行われます(スクリプト自体の名前を除く)。これは、すべてのCLI Perlアプリケーションにとって基本的な方法ですが、データ型、エンコーディング、パラメータの分割、ファイルの自動読み込みなどに関連する多くの注意点が存在します。
Perlの初期バージョンから、配列@ARGVは起動引数の標準的な「エントリーポイント」として機能しており、Cのargv[]に似ています。しかし、Perlは汎用プログラミング言語でありテキスト処理のために多くの追加のトリックを取り入れ、例えば、<>式は@ARGVの内容と「連携」しており、引数として渡されたファイルを直接読み取ることを可能にします。
@ARGVを単純に読み取ることは簡単なケースにのみ適しています。複雑なCLIプログラムでは、オプション(--help、-o fileなど)を処理する必要があります。この場合、インデックスによるデータの単純な読み取りは安全ではなく、不便になります。さらに、スペースや非標準の記号を含む引数や、異なるエンコーディングの引数を処理するのがさらに難しくなります。また、<>演算子を介してファイルを自動的に開く際の問題や、例えば@ARGVの要素が「-」(stdin)と等しい場合の予期しない挙動もあります。
単純な引数の読み取り:
foreach my $arg (@ARGV) { print "Arg: $arg "; }
通常、オプションには特別なモジュールGetopt::Longを使用します:
use Getopt::Long; my $help; GetOptions('help' => \$help);
@ARGVからすべてのファイルを読み取る場合、ファイルの内容はループを介して直接読み取れます:
while (<>) { print; }
コマンドライン引数の1つが単独のダッシュ(-)の場合、どうなりますか?
この場合、<>演算子を使用すると、Perlは'-'をファイル名ではなく標準入力(stdin)として解釈します。
perl script.pl - file.txt # 最初にstdinから、次にfile.txtから読み取る
スクリプト内で@ARGVを安全に変更できますか?
はい、これは処理済みの引数を削除するための標準的な手法です。通常、オプションを処理した後、@ARGVには「生」のファイル名や未認識のパラメータのみを残します。
@ARGVのUTF-8引数を扱う際にエンコード/デコードを行う必要がありますか?
これはロケールと環境に依存します。デフォルトでは、Perlは@ARGVのエンコーディングを変換せず、「そのまま」受け入れます。したがって、ファイル名(またはパラメータ)に非ASCII文字が含まれている場合、Perlでの操作が必要な場合は、明示的にEncodeを使用して文字列をデコードすることが望ましいです。
ログを解析するユーティリティはファイルのリストを受け取ります。ユーザーが誤って'-'を指定します:
perl parse.pl - access.log
結果として、突然プログラムが停止し、キーボードからの入力を待っている状態になります。
長所:
短所:
CLIプログラムはGetopt::Longを介して引数を読み取り、すべてのマイナスオプションを明示的に処理し、@ARGVにはファイル名のみを残します:
perl report.pl --input access.log --output report.txt
長所:
短所: