1

我被迫(通过工程策略)使用Getopt::Euclid来解析我的 Perl 程序的参数。我有三个参数,foo、bar 和 blah。

没有这些并使用其他参数是合法的。

如果 foo 存在,则 bar 或 blah 中的一个应该存在,并且如果 bar 或 blah 存在,则 foo 必须存在。

阅读 CPAN 文档后,我看不出有任何方法可以让 Euclid 检测和执行这些限制。如果欧几里德可以强制执行这些限制,我想了解如何。

否则,我将自己检测条件,但如果违反条件,我想哄 Euclid 生成 --help 输出,但也无法从程序内部看到如何做到这一点。想法?

4

4 回答 4

1

好吧,看起来您可以将 OPTIONS 部分用于您的选项,如果它们不存在,它不会抱怨,但我看不到任何允许依赖选项的逻辑,因此您必须自己编写该逻辑。我也没有看到任何可以打印出使用情况的功能,但你总是可以说

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

它将使用调用它$0的相同解释器 ( )运行脚本 ( ) 并将参数传递给它。它很丑陋,但它应该可以工作。$^X--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)
于 2009-06-04T20:43:23.707 回答
0

在我看来(从未使用过 G::E 并且尚未测试)就像您想假装它只是一种选择:

=head1 OPTIONS

=over

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

然后使用$ARGV{'--foo'}{'foo'}and$ARGV{'--foo'}{'bar'}$ARGV{'--foo'}{'baz'}.

我想我假设他们都在争论;你没有说清楚。

更新:似乎有效,但如果您省略 bar 或 baz 或同时指定两者,它会给出误导性错误消息。如果没有一个开关带参数,你可以这样做:

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

=for Euclid
    false: --foo --baz

$ARGV{'--foo'}bar 为 true,baz 为 false,如果两者都不存在,则不存在。

从长远来看,您最好向 Getopt::Euclid 作者发送一个允许类似以下内容的补丁:

=item --foo

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

=item --bar

=for Euclid
    requires: --foo

=item --baz

=for Euclid
    requires: --foo

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

于 2009-06-05T01:52:13.783 回答
0

Getopt::Euclid 手册的“占位符约束”部分中描述的功能怎么样?具体来说,这种形式:

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

我相信,EXPRESSION_INVOLVING可以是任意的 perl 表达式。它甚至不必涉及选项本身。所以 bar 和 blah 的约束表达式可以分别检查另一个不存在并且 foo 确实存在。

唯一的问题是,这可能会对您的论点施加顺序依赖性。这将是合法的--foo --bar:但这不会:--bar --foo,因为当读取 --bar 参数时,Euclid 还不知道 --foo ,所以它会发牢骚。所以如果你走这条路,请确保为 --bar 指定一条错误消息。

于 2009-12-05T06:52:36.147 回答
0

从 Getopt::Euclid(2011 年 6 月发布)版本 0.2.4 开始,您可以使用 'exclude' 关键字来指定互斥的参数。

于 2013-02-09T01:17:54.203 回答