我有一个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

这工作在我的开发,测试和生产环境优良。不过,我试图使它更容易忽略某些变量(无需进入调试器)用于开发和测试。 (例如,如果我想设置我的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只能被调用一次(据我所知)。第4个参数,我的第一SNIPPIT需要,直接在上面最后7是可选的。我认为理想的情况下将设置默认为我的第一个代码片段,然后以某种方式超越任何人,如果论点在命令行通过已设定。我想到了存储在哈希我的所有选项,然后设置了,除非一个条目中的散列中存在的默认值的每个变量在使用散列,但似乎增添了不少额外的逻辑。有没有办法来调用两个不同的地方GetOptions脚本?

如果让任何意义不确定。

谢谢!

有帮助吗?

解决方案

下面的另一种方法。它使用名称的阵列和存储选项的哈希值。它使所有的选择确实是可选的,但除非你在命令行上“--debug”验证所需的项目。不管你是否使用“--debug”,您可以覆盖任何其他人。

您可以做更明确的逻辑检查,如果这对你很重要的,当然。我列入“--debug”作为如何忽略基本的选项,如“装入点”,如果你只是要覆盖“INPUT_FILE”和“OUTPUT_FILE”变量反正一个例子。

的主要思想这里是通过保持套选项名称的数组中,可以包括对所述组逻辑检查以相对少的代码。

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模块。选择最适合您的输入数据之一。

一旦你的地方,你可以轻松地设置默认值,采取从多个地方(文件,命令行等)值,并且轻松地测试不同值的程序。获得更好的配置模型

我想我会做什么设置input_directory等人以“民主基金”,然后把它们放在getopts的,再后来,测试,如果他们仍然民主基金,如果是将它们分配如图所示。如果用户在技术上是复杂的不够了解,“如果我给一个相对路径是相对于$mount_point/$sub_dir”,那么我会做更多的分析寻找最初的“/".

GetOptions可以以与阵列作为输入数据被调用。阅读文档

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top