1

私は(エンジニアリングポリシーにより)Getopt::Euclidを使用してPerlプログラムへの引数を解析することを余儀なくされています。foo、bar、blahの3つの引数があります。

これらのいずれも持たず、代わりに他の引数を使用することは正当です。

fooが存在する場合は、barまたはblahのいずれかが正確に存在する必要があり、barまたはblahのいずれかが存在する場合は、fooが存在する必要があります。

CPANのドキュメントを読んだ後、Euclidにこれらの制限を検出して適用させる方法がわかりません。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

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 に答える
0

私には(G :: Eを使用したことがなく、テストもしていません)、それが1つのオプションに過ぎないふりをしたいようです:

=head1 OPTIONS

=over

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

次に、と または$ARGV{'--foo'}{'foo'}のいずれかを使用し$ARGV{'--foo'}{'bar'}ます$ARGV{'--foo'}{'baz'}

私は、それらがすべて引数を取ると仮定していると思います。あなたはそれを明確にしませんでした。

更新: bar または baz を省略したり、両方を指定したりすると、誤解を招くエラー メッセージが表示されますが、動作するようです。どのスイッチも引数を取らない場合は、次のことができます。

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

=for Euclid
    false: --foo --baz

barの$ARGV{'--foo'}場合は 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 に答える