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

发布于 2024-11-14 06:04:19 字数 251 浏览 3 评论 0原文

我是 Perl 菜鸟,所以请耐心解答我的这个问题。

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

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

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

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

谢谢, 尼拉吉

I am a noob to perl, so please try to be patient with this question of mine.

It seems that if I make multiple calls to perl Getopts::Long::GetOpts method, the second call is completely ignored.

  1. Is this normal??(Why)

  2. What are the alternatives to this process??

(Actually Ive written a module, where I make a GetOpts call, an the script using my module tries to do that too, but it seems that script does not get the required options)

Thanks,
Neeraj

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

偏爱你一生 2024-11-21 06:04:19

Getopts::Long 在工作时会更改 @ARGV,这就是它在处理完开关后将非开关值留在 @ARGV 中的方式。因此,当您进行第二次调用时,@ARGV 中没有任何内容可供解析,也不会发生任何有用的事情。

但是,有 GetOptionsFromArray< /a>:

默认情况下,GetOptions 解析全局数组 @ARGV 中存在的选项。特殊条目 GetOptionsFromArray 可用于解析任意数组中的选项。

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

Getopts::Long alters @ARGV while it works, that's how it can leave non-switch values behind in @ARGV when it is done processing the switches. So, when you make your second call, there's nothing left in @ARGV to parse and nothing useful happens.

However, there is GetOptionsFromArray:

By default, GetOptions parses the options that are present in the global array @ARGV. A special entry GetOptionsFromArray can be used to parse options from an arbitrary array.

So you could use GetOptionsFromArray on a copy of @ARGV (or some other array) if you need to parse the list multiple times.

只有一腔孤勇 2024-11-21 06:04:19

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

为此,我对 .optrc 文件运行 GetOptions,然后对 @ARGV 中的内容运行。在旧版本的 GetOptions 中,我必须保存 @ARGV,将 .optrc 放入 @ARGV,使用 GetOptions 处理它,然后恢复 < code>@ARGV 并对其运行 GetOptions。较新版本的 GetOpts::Long 现在允许您指定数组,而不仅仅是使用 @ARGV

I've run GetOptions from GetOpts::Long multiple times in a single program. What I have is a .optrc file that contains command line options that can be overridden by the command line. Much the same way .cvsrc and .exrc work.

In order to do that, I run GetOptions on the .optrc file and then what's in @ARGV. In older versions of GetOptions, I had to save @ARGV, toss .optrc into @ARGV, process it with GetOptions, and then restore @ARGV and run GetOptions on that. Newer versions of GetOpts::Long now allow you to specify the array instead of using just @ARGV.

万水千山粽是情ミ 2024-11-21 06:04:19

制作 @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 源 (在 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 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
        };

Making copies of @ARGV will keep you busy parsing again and again the same set of options. If this is what you want, fine. But.

Suppose you have a set of modules you are using in your program which can recognize only a subset of your @ARGV. What you want to do is to call GetOptions from each of these module, consume each of the options the module is able to recognize and leave the rest of the options in @ARGV to be processed by the other modules.

You can configure Getopt::Long to do this by calling

Getopt::Long::Configure qw/pass_through/;

But see perldoc Getopt::Long for various configurations side effects!

Example: a script (o1.pl) able to recognize few options and two modules (o1::p1 and o1::p2) which must get to read their own options

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 (in 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;

running 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

will give you the following (expected) output (p1 consumed its options, then p2 did it, then main was left with what it knows about):

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
        };
离旧人 2024-11-21 06:04:19

这不正是关键字“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;

Isn't this the sort of the thing the keyword "local" is supposed to be for?

{
    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;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文