1

Problem: I've got a script that can be called in one of the following ways:

./script.pl -a
./script.pl [-w] -<i|d|r|t>

Meaning, the -w flag is optional, but either -i or -d or -r or -t must be specified.

If the user doesn't call the script in any of those ways, the function usage should be called.

My attempt:

sub fInv
{
    print "fInv"."\n";
}

sub fDisp
{
    print "fDisp"."\n";
}

sub fRanking
{
    print "fRanking"."\n";
}

sub fTickets
{
    print "fTickets"."\n";
}

sub usage
{
    print "Usage shown here.\n";
}

%options = (i => \&fInv, d => \&fDisp, r => \&fRanking, t => \&fTickets);

$write = 0;

GetOptions("a" => \&usage)
    or GetOptions("w" => \$write,
                    keys($options) => \&options) # This is clearly wrong
    or die usage;
4

2 回答 2

0

用 5 个变量来代表一个选择没有多大意义。

my $type;
my $opt_w;

my $set_type = sub {
   my ($new_type) = @_;
   die "-$type and -$new_type cannot be used together\n"
      if defined $type && $new_type ne $type;
   $type = $new_type;
};

GetOptions(
   'help|h|?' => \&help,
   ( map { $_ => $set_type } qw( a i d r t ) ),
   'w' => \$opt_w,
)
   or usage();

usage("One of -a, -i, -d, -r or -t must be specified\n")
   if !defined($type);

usage("-w cannot be used with -a\n")
   if $opt_w && $type eq 'a';

sub help {
    print "...detailed help...\n";
    exit(0);
}

sub usage {
    print(STDERR $_[0]) if @_;
    print(STDERR "usage: script -a\n");
    print(STDERR "       script [-w] {-i|-d|-r|-t}\n");
    print(STDERR "Use script --help for more information\n");
    exit(1);
}
于 2013-10-06T00:10:40.810 回答
0

基本上,使用所有各种选项并测试您想要的组合。

use strict;
use warnings;
use Getopt::Long;
use Pod::Usage;      # Learn something new!


my ( $opt_a, $opt_i, $opt_w, $opt_d, $opt_r, $opt_t, $opt_w );
GetOoptions {

     a    => \$opt_a,
     i    => \$opt_i,
     w    => \$opt_w,
     d    => \$opt_d,
     r    => \$opt_r,
     t    => \$opt_t,
     help => \$help,
} or die pod2usage ( -message => "You did it wrong" );

if ( $help ) {
    pod2usage;
}

if ( $opt_a and ( $opt_w or $opt_d or $opt_r or $opt_t ) ) {
    pod2usage ( -message => "Either use '-a' by itself, or the other parameters" );
}

if ( not ( $opt_w and $opt_w and $opt_d and $opt_r and $opt_t ) {
pod2usage ( -message => "You need to use parameters -d, -i, -r, or -t")

#
# And now to your regularly scheduled program
#

但是,我建议您使用long,即使用参数名称。默认情况下,Getopt::Long将允许参数缩写。如果-i整数,(我不知道,你没有给出太多线索来说明这些参数的含义),继续指定-integer为参数(并使用$integer代替$opt_i)。用户可以缩写-integer为,-i因为没有其他参数以 . 开头-i。你也可以使用别名

 "divider|i" => \$divider,

然后,用户可以使用-divider-i作为参数。

现在到这个 Pod::Usage...

Perl 有一个称为POD的文档系统(它代表Plain Old Documentation)。它很容易上手,它允许您将文档直接添加到您的程序中。

=pod

=head1 NAME

script.pl

=head1 SYNOPSIS

    ./script.pl -a

or

    ./script.pl [-w] -<i|d|r|t>

=head1 DESCRIPTION

blah, blah, blah, yadda, yadda, yadda

=head1 OPTIONS

perldoc您可以使用Perl 附带的命令查看此文档:

$ perldoc script.pl

这将完全打印出您的 POD。如果有人需要知道如何使用您的程序以及它的作用,它就在那里。

Pod::Usage默认情况下会打印出您的 POD 的概要部分,然后退出。当用户输入错误的选项或类型时,这很棒script.pl -help

有很多选择。例如,您可以打印出概要选项部分,或整个 POD,或选定的部分。

这是记录代码的好方法,应该受到每个人的鼓励。

我遇到的唯一问题是POD 文档中的文档没有特别提到命令段落(以等号开头的行)前后必须有一个空行。

于 2013-10-06T01:40:14.810 回答