我想使用这些规则处理脚本选项:
如果没有要求4,我可以先处理配置文件,然后再处理命令行,允许后面的选项覆盖之前的选项。优雅。
但是如果在命令行中指定了配置文件,我需要将其全部丢弃并重新启动,这会使一切都突然变得混乱和复杂。
这是一个优雅的perl成语吗?
答案 0 :(得分:1)
规则5使事情复杂化...... 但是,在命令行中通过-M加载的模块在脚本中提到的模块之前加载 - 包括Getopt :: Long。因此,我们可以在默认配置存储在一个简短的自定义模块中进行操作;
# DefaultConf.pm
use strict;
use warnings;
while (<DATA>) {
chomp ; # Remove the newline
s/ \s* \#.* //x ; # Strip comments
next if / ^ \s* $ /x ; # Ignore blank lines
my @a = split(" ", $_, 2); # Break into 2 pieces and unshift
unshift(@ARGV, $_) for reverse @a ; # onto ARGV in reverse order
}
# print "===\n", join(" ", @ARGV), "\n", "===\n"; # debug
1;
__DATA__
# Default App config data here
--verbose
-n # single old-style switch with comment
# another comment
--files file1.txt, file2.txt
perl忽略__DATA__
之后的文本,但程序员可以通过DATA
文件句柄使用。在这里,我们可以使用一个限制存储脚本的默认配置 - 每行只有一个选项(带参数)。注释可以在选项规范的末尾使用,也可以使用perl注释字符用于整行,&#39;#&#39;。
这可以从命令行中使用,如下所示:
perl -MDefaultConf my_app.pl --verbose=0 --files file12.txt --log
my_app.pl
正常加载Getopt::Long
,但由于我们的自定义模块是通过命令行上的-M加载的,因此首先加载。因此,我们可以小提琴在@ARGV
获得贪婪的小手之前Getopt::Long
。此后,实际选项处理由Getopt::Long
完成,因此我们自定义模块末尾的选项语法完全相同。
希望内联注释使代码自我解释 - 唯一的诀窍就是当有两个&#34;件&#34; (比方说,一个选项及其单个参数),我们需要将它们按反向顺序推送到@ARGV的前面(unshift - not push),这样如果相同在命令行中提到了option,它在后面处理,因此优先。
使用此方法,您可以为不同的&#34;运行情况提供大量配置文件&#34;通过-M选项选择,或者根据要求,您可以在没有任何使用CLI选项的情况下运行,或者使用CLI选项优先的组合。
关于规则5的最后评论 - 仅核心模块。由于此限制,您必须使用此(或类似)模块 - NOT 核心模块。虽然它很小且易于理解,但它没有测试,并且它没有被部署在数百个地方,如Config::Tiny
所说的那样。 Config::Tiny
长度不超过100行(不包括空格和注释),大约一小时就可以完全理解。当然,每个人的环境和限制都是不同的 - 这只是需要考虑的事情。