perl 如何使用Getopt::欧几里得检测组合参数错误?

lx0bsm1f  于 2022-11-15  发布在  Perl
关注(0)|答案(4)|浏览(128)

我被迫(根据工程政策)使用Getopt::Euclid来解析Perl程序的参数,我有三个参数,foo,bar和blah。
不使用这些参数而使用其他参数是合理的。
如果foo出现,则bar或blah中的一个应该出现,如果bar或blah中的一个出现,则foo必须出现。
在阅读CPAN文档后,我看不出有任何方法可以让欧几里得检测并强制执行这些限制。如果Euclid可以强制执行这些限制,我想知道是怎么做到的。
否则,我会自己检测条件,但是如果条件被违反了,我想诱使欧几里得生成帮助输出,但是在程序内部也看不到怎么做,有什么想法吗?

csga3l58

csga3l581#

好吧,看起来你可以使用OPTIONS部分作为你的选项,如果它们不在那里,它不会抱怨,但是我没有看到任何允许依赖选项的逻辑,所以你必须自己写逻辑。我也没有看到任何函数可以打印出用法,但是你总是可以说

system $^X, $0, "--help";

它将使用与调用脚本时相同的解释器($^X)运行脚本($0),并将参数--help传递给它。

#!/usr/bin/perl

use strict;
use warnings;

use Getopt::Euclid;

sub usage {
    my $message = shift;
    print "$message\n\n";
    system $^X, $0, "--help";
}

if (keys %ARGV) {
    unless (exists $ARGV{'--foo'}) {
        usage "--foo must be present if --bar or --blah is present";
        exit -1;
    }

    if ($ARGV{'--bar'} and $ARGV{'--blah'}) {
        usage "only one of --bar or --blah may be present";
        exit -1;
    }
}

unless ($ARGV{'--foo'}) {
    print "Doing nothing\n";
    exit 0;
}

print "fooing bar\n"  if $ARGV{'--bar'};
print "fooing blah\n" if $ARGV{'--blah'};

__END__

=head1 NAME 

foo.pl - foo the bar 

=head1 VERSION

1.0

=head1 usage 

    foo.pl [options]

=head1 OPTIONS

=over

=item --foo

do the foo (requires --bar or --blah)

=item --bar

what to do the foo to (requires --foo)

=item --blah

what to do the foo to (requires --foo)

=item --help

=back

=head1 AUTHOR

Chas. J. Owens IV

=head1 BUGS

Hopefully none

=head1 COPYRIGHT

Copyright (c) 2009, Chas. J. Owens IV. All Rights Reserved.
This module is free software. It may be used, redistributed
and/or modified under the terms of the Perl Artistic License
(see http://www.perl.com/perl/misc/Artistic.html)
ujv3wf0j

ujv3wf0j2#

在我看来(从未使用过G::E,也没有测试过),你想假装这只是一个选项:

=head1 OPTIONS

=over

=item --foo <foo> --bar <bar> | --foo <foo> --baz <baz>

然后使用$ARGV{'--foo'}{'foo'}$ARGV{'--foo'}{'bar'}$ARGV{'--foo'}{'baz'}
我想我假设他们都有论据;你没说清楚
Update:看起来是可行的,尽管如果省略bar或baz或者同时指定这两个参数,它会给出误导性的错误信息。如果没有一个开关带参数,你可以:

=item --foo --bar | --foo --baz

=for Euclid
    false: --foo --baz

$ARGV{'--foo'}对于bar将为真,对于baz将为假,且如果两者都不存在,则不存在。
从长远来看,您最好向Getopt::欧几里得作者发送一个补丁,该补丁允许以下内容:

=item --foo

=for Euclid
    requires: --bar | --baz

=item --bar

=for Euclid
    requires: --foo

=item --baz

=for Euclid
    requires: --foo

因此,如果指定了不一致的选项,它可能会生成有意义的错误消息。

mbjcgjjk

mbjcgjjk3#

Getopt::欧几里得手册中“占位符约束”一节中描述的特性如何?具体来说,这个表单:

PLACEHOLDER.type: TYPE [, EXPRESSION_INVOLVING(PLACEHOLDER)]

我相信EXPRESSION_INVOLVING可以是任意的perl表达式,它甚至不需要包含选项本身,所以bar和blah的约束表达式都可以检查另一个不存在而foo存在。
唯一的问题是,这可能会对你的论证强加一种顺序依赖。这是法律的的:--foo --bar;但这不会:--bar --foo,因为当--bar参数被读取时,欧几里得还不知道--foo,所以它会出错,所以如果你走这条路,一定要为--bar指定一个错误消息。

lokaqttq

lokaqttq4#

自Getopt::欧几里得0.2.4版(2011年6月发布)以来,您可以使用'exclude'关键字来指定互斥的参数。

相关问题