我可以在perl中多次调用Getopts吗?

时间:2011-06-06 15:14:33

标签: perl getopt-long

我是perl的菜鸟,所以请耐心等待我的这个问题。

似乎如果我多次调用perl Getopts :: Long :: GetOpts方法,第二次调用将被完全忽略。

  1. 这是正常的吗?(为什么)

  2. 这个过程有哪些替代方案?

  3. (实际上我已经编写了一个模块,我在其中进行GetOpts调用,使用我的模块的脚本也尝试这样做,但似乎脚本没有获得所需的选项)

    谢谢, Neeraj

4 个答案:

答案 0 :(得分:8)

Getopts :: Long在@ARGV工作时更改@ARGV,这就是在处理交换机时,@ARGV中的非切换值会落后的情况。因此,当您进行第二次调用时,@ARGV中没有任何内容可以解析,也没有任何有用的内容。

但是,有GetOptionsFromArray

  

默认情况下,GetOptions会解析全局数组GetOptionsFromArray中存在的选项。可以使用特殊条目GetOptionsFromArray来解析来自任意数组的选项。

因此,如果需要多次解析列表,可以在@ARGV(或其他一些数组)的副本上使用{{1}}。

答案 1 :(得分:3)

我在一个程序中多次从GetOpts::Long运行GetOptions。我所拥有的是一个.optrc文件,其中包含可以被命令行覆盖的命令行选项。 .cvsrc.exrc的工作方式大致相同。

为了做到这一点,我在.optrc文件上运行GetOptions,然后在@ARGV中运行。在旧版本的GetOptions中,我必须保存@ARGV,将.optrc投入@ARGV,使用GetOptions处理它,然后恢复@ARGV并运行GetOptions。较新版本的GetOpts :: Long现在允许您指定数组而不是仅使用@ARGV

答案 2 :(得分:0)

制作@ARGV的副本会让你忙着一遍又一遍地解析同一组选项。如果这是你想要的,那很好。但

假设您在程序中使用了一组模块,这些模块只能识别@ARGV的一部分。您要做的是从每个模块中调用GetOptions,使用模块能够识别的每个选项,并将其余选项留在@ARGV中以供其他模块处理。

您可以通过调用

配置Getopt :: Long来执行此操作
Getopt::Long::Configure qw/pass_through/;

但请参阅perldoc Getopt :: Long以了解各种配置副作用!

示例:一个脚本(o1.pl)能够识别几个选项和两个模块(o1 :: p1和o1 :: p2)必须阅读自己的选项

o1.pl:

!在/ usr / bin中/ perl的

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 source(在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 source(in 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 with:

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
        };

答案 3 :(得分:0)

这不是关键字“本地”应该是什么类型的东西吗?

{
    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;