我是 perl 的菜鸟,所以请尽量对我的这个问题保持耐心。
似乎如果我多次调用 perl Getopts::Long::GetOpts 方法,第二次调用将被完全忽略。
这正常吗??(为什么)
这个过程的替代方案是什么?
(实际上我已经编写了一个模块,我在其中进行了 GetOpts 调用,使用我的模块的脚本也尝试这样做,但似乎脚本没有获得所需的选项)
谢谢,尼拉吉
我是 perl 的菜鸟,所以请尽量对我的这个问题保持耐心。
似乎如果我多次调用 perl Getopts::Long::GetOpts 方法,第二次调用将被完全忽略。
这正常吗??(为什么)
这个过程的替代方案是什么?
(实际上我已经编写了一个模块,我在其中进行了 GetOpts 调用,使用我的模块的脚本也尝试这样做,但似乎脚本没有获得所需的选项)
谢谢,尼拉吉
Getopts::Long在工作时会发生变化,这就是它在处理完开关@ARGV
后可以留下非开关值的方式。@ARGV
因此,当您进行第二次调用时,没有任何东西@ARGV
需要解析,也没有任何有用的事情发生。
但是,有GetOptionsFromArray
:
默认情况下,GetOptions 解析全局数组中存在的选项
@ARGV
。特殊条目 GetOptionsFromArray 可用于解析任意数组中的选项。
因此,如果您需要多次解析列表,您可以在(或其他数组)GetOptionsFromArray
的副本上使用。@ARGV
我GetOpts::Long
在一个程序中多次运行 GetOptions。我所拥有的是一个.optrc
文件,其中包含可以被命令行覆盖的命令行选项。方式.cvsrc
和.exrc
工作方式大致相同。
为此,我在 .optrc 文件上运行 GetOptions,然后在 .optrc 文件中运行什么@ARGV
。在较旧版本的 GetOptions 中,我必须保存@ARGV
、折腾.optrc
到 @ARGV、使用 处理它GetOptions
,然后恢复@ARGV
并在其上运行 GetOptions。较新版本的 GetOpts::Long 现在允许您指定数组而不是仅使用@ARGV
.
制作@ARGV 的副本将使您忙于一次又一次地解析同一组选项。如果这是你想要的,那很好。但。
假设您在程序中使用了一组模块,它们只能识别您的@ARGV 的一个子集。您要做的是从每个模块调用 GetOptions,使用模块能够识别的每个选项,并将 @ARGV 中的其余选项留给其他模块处理。
您可以通过调用配置 Getopt::Long 来执行此操作
Getopt::Long::Configure qw/pass_through/;
但是请参阅 perldoc Getopt::Long 了解各种配置的副作用!
示例:一个脚本 (o1.pl) 能够识别几个选项和两个模块(o1::p1 和 o1::p2),它们必须读取自己的选项
o1.pl:
use Getopt::Long;
use o1::p1;
use o1::p2;
# now o1::p1 and o1::p2 already consumed recognizable options
#no need to configure pass_through since main:: will get to see only its options
#Getopt::Long::Configure(qw/pass_through/);
my %main_options = ( 'define' => {}, );
print "main: \@ARGV = " . join (', ', @ARGV) . "\n";
GetOptions(\%main_options, "main-vi=i","verbose",'define=s');
use Data::Dumper;
print "main_options: ", Dumper(\%main_options);
print "p1 options: ", Dumper(\%o1::p1::options);
print "p2 options: ", Dumper(\%o1::p2::options);
exit 0;
o1::p1 源(在 o1/p1.pm 中):
package o1::p1;
use Getopt::Long;
Getopt::Long::Configure qw/pass_through/;
%options = ();
print "package p1: \@ARGV = " . join (', ', @ARGV) . "\n";;
GetOptions(\%options, "p1-v1=s", "p1-v2=i");
1;
o1::p2 源(在 o1/p2.pm 中):
package o1::p2;
use Getopt::Long;
Getopt::Long::Configure 'pass_through';
%options = ();
print "package p2: \@ARGV=". join (', ', @ARGV). "\n";
GetOptions(\%options, "p2-v1=s", "p2-v2=i");
1;
运行 o1.pl:
perl o1.pl --main-vi=1 --verbose --define a=ss --p1-v1=k1 --p1-v2=42 --define b=yy --p2-v1=k2 --p2-v2=66
将为您提供以下(预期的)输出(p1 使用了它的选项,然后 p2 做到了,然后 main 留下了它所知道的):
package p1: @ARGV = --main-vi=1, --verbose, --define, a=ss, --p1-v1=k1, --p1-v2=42, --define, b=yy, --p2-v1=k2, --p2-v2=66
package p2: @ARGV=--main-vi=1, --verbose, --define, a=ss, --define, b=yy, --p2-v1=k2, --p2-v2=66
main: @ARGV = --main-vi=1, --verbose, --define, a=ss, --define, b=yy
main_options: $VAR1 = {
'verbose' => 1,
'define' => {
'a' => 'ss',
'b' => 'yy'
},
'main-vi' => 1
};
p1 options: $VAR1 = {
'p1-v1' => 'k1',
'p1-v2' => 42
};
p2 options: $VAR1 = {
'p2-v1' => 'k2',
'p2-v2' => 66
};
这不就是关键字“local”应该用于的那种东西吗?
{
local @ARGV = @ARGV;
our $opt_h;
&getopts('h');
&printUsage if $opt_h;
}
# Now that the local version of @ARGV has gone out of scope, the original version of @ARGV is restored.
while (@ARGV){
my $arg = shift @ARGV;