私のPerlプログラムにハードコードされた設定を上書きすることができますか?

StackOverflow https://stackoverflow.com/questions/356337

  •  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

他のヒント

私は、彼らはまだundefをしていると示すようにそれらを割り当てた場合ならば、私は、その後、テストをする「undefを」input_directoryらを設定して行い、その後、getoptsは、それらを入れて、どうなるかと思います。ユーザーが技術的に洗練されている場合、十分な「その後、私は最初のを探して追加の解析を行うだろう、「私は、相対パスを与える場合、それは$mount_point/$sub_dirする相対的だ」理解する/".

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top