私のPerlプログラムにハードコードされた設定を上書きすることができますか?
-
21-08-2019 - |
質問
私はそれが使用するディレクトリとファイルのトップに近い変数を設定Perlスクリプトを持っています。また、いくつかの変数は、コマンドライン引数として設定する必要があります。 例:
use Getopt::Long;
my ($mount_point, $sub_dir, $database_name, $database_schema);
# Populate variables from the command line:
GetOptions(
'mount_point=s' => \$mount_point,
'sub_dir=s' => \$sub_dir,
'database_name=s' => \$database_name,
'database_schema=s' => \$database_schema
);
# ... validation of required arguments here
################################################################################
# Directory variables
################################################################################
my $input_directory = "/${mount_point}/${sub_dir}/input";
my $output_directory = "/${mount_point}/${sub_dir}/output";
my $log_directory = "/${mount_point}/${sub_dir}/log";
my $database_directory = "/db/${database_name}";
my $database_scripts = "${database_directory}/scripts";
################################################################################
# File variables
################################################################################
my $input_file = "${input_dir}/input_file.dat";
my $output_file = "${output_dir}/output_file.dat";
# ... etc
これは私のdevの、テスト、および本番環境で正常に動作します。しかし、私は、開発とテストのために(デバッガに行かなくても)それが簡単に特定の変数を上書きするために作るしようとしていました。 (例えば、私は私のinput_file =「/tmp/my_input_file.dat」を設定する場合)。
:私の考えは、これを処理するGETOPTIONS機能を使用するには、このようなものでしたGetOptions(
'input_directory=s' => \$input_directory,
'output_directory=s' => \$output_directory,
'database_directory=s' => \$database_directory,
'log_directory=s' => \$log_directory,
'database_scripts=s' => \$database_scripts,
'input_file=s' => \$input_file,
'output_file=s' => \$output_file
);
GETOPTIONSは(私の知る限りでは)一回呼び出すことができます。私の最初のsnippitにおける最初の4つの引数は、直接、上記の最後の7はオプションで、必要とされています。私は理想的な状況は、デフォルトで私の最初のコードsnippitのように設定することだと思うし、その後何とか引数は、コマンドラインで渡された場合に設定されていることをそれらのいずれかをオーバーライドします。私はハッシュですべての私のオプションを保存して、エントリがハッシュに存在しない限り、デフォルト値で各変数を設定する際にそのハッシュを使用して考えたが、それは追加のロジックの多くを追加しているようです。スクリプトの中で2つの異なる場所でGETOPTIONSを呼び出す方法はありますか?
それはどんな意味があるかどうかわからない。
ありがとうございます。
解決
ここでは別のアプローチです。これは、オプションを保存するために名前の配列やハッシュを使用しています。これは、すべてのオプションが本当にオプションになりますが、コマンドラインで「--debug」が含まれない限り、必要なものを検証します。関係なく、あなたが「--debug」を使用するかどうかの、あなたは他の人のいずれかをオーバーライドすることができます。
それはあなたにとって重要な場合は、あなたはもちろん、より明示的なロジックチェックを行うことができます。私はあなただけとにかく「INPUT_FILE」と「output_fileの」変数を上書きするつもりなら「MOUNT_POINT」などの基本的なオプションを省略する方法の例として、「--debug」に含まれていました。
ここでの主なアイデアは、配列内のオプション名のセットを保つことによって、あなたは比較的少ないコードでグループに対して、論理チェックを含めることができるということです。
use Getopt::Long;
my @required_opts = qw(
mount_point
sub_dir
database_name
database_schema
);
my @internal_opts = qw(
input_directory
output_directory
log_directory
database_directory
database_scripts
input_file
output_file
);
my @opt_spec = ("debug", map { "$_:s" } @required_opts, @internal_opts);
# Populate variables from the command line:
GetOptions( \(my %opts), @opt_spec );
# check required options unless
my @errors = grep { ! exists $opts{$_} } @required_options;
if ( @errors && ! $opts{debug} ) {
die "$0: missing required option(s): @errors\n";
}
################################################################################
# Directory variables
###############################################################################
my $opts{input_directory} ||= "/$opts{mount_point}/$opts{sub_dir}/input";
my $opts{output_directory} ||= "/$opts{mount_point}/$opts{sub_dir}/output";
my $opts{log_directory} ||= "/$opts{mount_point}/$opts{sub_dir}/log";
my $opts{database_directory} ||= "/db/$opts{database_name}";
my $opts{database_scripts} ||= "$opts{database_directory}/scripts";
################################################################################
# File variables
################################################################################
my $opts{input_file} ||= "$opts{input_directory}/input_file.dat";
my $opts{output_file} ||= "$opts{output_directory}/output_file.dat";
# ... etc
他のヒント
これが鳴ります。私はPerlがこれにを極めるの章全体を捧げました。あなたがプログラムをテストするために、ソースコードを変更する必要はありません。
設定が簡単に追加する機能をファイル作るCPAN上の多くのPerlモジュールがあります。入力データに最も適したものを選択します。
あなたの場所でより良い構成モデルを取得したら、あなたは簡単にデフォルト値を設定することができます。、複数の場所(ファイル、コマンドラインなど)から値を取得し、簡単に別の値を使用してプログラムをテストします。
私は、彼らはまだundefをしていると示すようにそれらを割り当てた場合ならば、私は、その後、テストをする「undefを」input_directory
らを設定して行い、その後、getoptsは、それらを入れて、どうなるかと思います。ユーザーが技術的に洗練されている場合、十分な「その後、私は最初のを探して追加の解析を行うだろう、「私は、相対パスを与える場合、それは$mount_point/$sub_dir
する相対的だ」理解する/".のp>
GETOPTIONSは、その入力データとしてアレイと呼ぶことができます。 ドキュメントをお読みください。