2009-06-04 8 views
1

Ich bin gezwungen (durch Engineering-Politik), Getopt::Euclid zu verwenden, um Argumente zu meinem Perl-Programm zu analysieren. Ich habe drei Argumente, foo, bar und blah.Wie erkenne ich Kombinationsargumentfehler mit Getopt :: Euclid?

Es ist legitim, keine von diesen zu haben und stattdessen andere Argumente zu verwenden.

Wenn foo vorhanden ist, dann sollte genau einer von bar oder blah vorhanden sein, und wenn entweder bar oder blah vorhanden sind, dann muss foo vorhanden sein.

Nach dem Lesen der CPAN-Dokumentation sehe ich keine Möglichkeit, Euclid zum Erkennen und Erzwingen dieser Einschränkungen zu erhalten. Wenn Euclid diese Beschränkungen durchsetzen kann, würde ich gerne verstehen, wie.

Ansonsten werde ich die Bedingungen selbst erkennen, möchte aber Euclid in der Erzeugung die --help Ausgabe entlocken, wenn die Bedingungen verletzt werden, kann aber nicht sehen, wie das zu tun, aus dem Programm entweder. Ideen?

Antwort

1

Nun, es sieht so aus, als könnten Sie den OPTIONS-Abschnitt für Ihre Optionen verwenden und es wird sich nicht beschweren, wenn sie nicht da sind, aber ich sehe keine Logik, um abhängige Optionen zu erlauben, also müssten Sie das schreiben Logik selbst. Ich sehe keine Funktionen auch, die aus der Nutzung gedruckt werden, aber man konnte immer

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

sagen, welches das Skript ($0) mit dem gleichen Interpreter läuft ($^X) es mit aufgerufen wurde und übergeben sie die Argument --help. Es ist hässlich, aber es sollte funktionieren.

#!/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) 
0

Sieht mir (nie benutzt G :: E und haben nicht getestet), wie Sie es nur eine Möglichkeit, so zu tun wollen:

=head1 OPTIONS 

=over 

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

dann $ARGV{'--foo'}{'foo'} verwenden und entweder $ARGV{'--foo'}{'bar'} oder $ARGV{'--foo'}{'baz'}.

Ich nehme an, ich nehme an, dass sie alle Argumente nehmen; Du hast das nicht klargestellt.

Update: scheint zu funktionieren, obwohl es irreführende Fehlermeldungen gibt, wenn Sie bar oder baz weglassen oder beides angeben. Wenn keiner der Schalter Argumente nehmen, können Sie tun:

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

=for Euclid 
    false: --foo --baz 

und $ARGV{'--foo'} wird für Bar, false für baz wahr sein, und nicht vorhanden, wenn auch nicht.

Auf lange Sicht, können Sie besser dran Senden der Autor Getopt :: Euclid sein ein Patch, der so etwas wie erlaubt: Es kann sinnvolle Fehlermeldungen erzeugen, wenn inkonsistent Optionen angegeben werden

=item --foo 

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

=item --bar 

=for Euclid 
    requires: --foo 

=item --baz 

=for Euclid 
    requires: --foo 

so.

0

Was ist mit den Funktionen, die im Abschnitt "Placeholder-Einschränkungen" des Getopt :: Euclid-Handbuchs beschrieben sind? Insbesondere diese Form:

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

Die EXPRESSION_INVOLVING kann jeder beliebiger Perl-Ausdruck sein, glaube ich. Es muss nicht einmal die Option selbst beinhalten.So können die Constraint-Ausdrücke für bar und blah jeweils überprüfen, dass der andere nicht existiert und dass foo existiert.

Das einzige Problem ist, dass dies wahrscheinlich eine Reihenfolge Abhängigkeit von Ihren Argumenten auferlegt. Dies wäre legal: --foo --bar; aber das würde nicht: --bar --foo, denn wenn das Argument --bar gelesen wird, weiß Euclid noch nicht --foo, also krächzt es. Also, wenn Sie diese Route gehen, stellen Sie sicher, eine Fehlermeldung zu diesem Zweck für --bar angeben.

0

Sie können das Schlüsselwort 'exclude' ab Version 0.2.4 von Getopt :: Euclid (veröffentlicht im Juni 2011) verwenden, um Argumente anzugeben, die sich gegenseitig ausschließen.

Verwandte Themen