2015-07-22 5 views
0

Я обновляю существующий скрипт Perl, который использует GetOptions от Getopt::Long. Я хочу добавить параметр, который берет строку в качестве ее параметра и может иметь только одно из трех значений: малый, средний или большой. Есть ли способ заставить Perl выкинуть ошибку или убить скрипт, если указано другое значение строки? До сих пор у меня есть:GetOptions Check Option Values ​​

my $value = 'small'; 
GetOptions('size=s' => \$value); 

ответ

1

Один из способов заключается в использовании grep, чтобы проверить, если значение является законным:

use warnings; 
use strict; 
use Getopt::Long; 

my $value = 'small'; 
GetOptions('size=s' => \$value); 

my @legals = qw(small medium large); 
die "Error: must specify one of @legals" unless grep { $_ eq $value } @legals; 

print "$value\n"; 
0

Это может быть излишним, но и взглянуть Getopt::Again, который реализует проверку через его process configuration value на аргумент командной строки.

use strict; 
use warnings; 
use Getopt::Again; 

opt_add my_opt => (
    type  => 'string', 
    default  => 'small',  
    process  => qr/^(?:small|medium|large)$/, 
    description => "My option ...", 
); 

my (%opts, @args) = opt_parse(@ARGV); 
+0

Я не видел, что Getopt :: Long действительно имеет ту особенность тоже. Рассмотрите это как альтернативу TIMTOWTDI. – simbabque

3

Вы можете использовать подпрограмму для обработки этой опции. User-defined subroutines to handle options

my $size = 'small'; # default 
GetOptions('size=s' => \&size); 
print "$size\n"; 

sub size { 
    my %sizes = (
      small => 1, 
      medium => 1, 
      large => 1 
    ); 

    if (! exists $sizes{$_[1]}) { 
     # die "$_[1] is not a valid size\n"; 

     # Changing it to use an exit statement works as expected 
     print "$_[1] is not a valid size\n"; 
     exit; 
    } 

    $size = $_[1]; 
} 

Я положил размеры в хэш, но вы можете использовать массив и Grep как показал toolic.

+1

Странно. Это не «умрет» для меня, если я использую что-то вроде '-size foo' – toolic

+0

Согласно документам, он должен был умереть, но вы правы, это не так. Позвольте мне запустить еще один тест. –

+0

Perl v5.12.2. Он умирает, если я использую 'GetOptions ('size = s' => \ & size) или die;' – toolic

0

Альтернативой Getopt :: Long является Getopt::Declare, который имеет встроенную поддержку шаблонов, но чуть более многословен:

use strict; 
use warnings; 

use feature qw/say/; 
use Getopt::Declare; 

my $args = Getopt::Declare->new(
    join "\n", 
     '[strict]', 
     "-size <s:/small|medium|large/>\t small, medium, or large [required]" 
) or exit(1); 

say $args->{-size}; 

Тест работает:

[hmcmillen]$ perl test.pl -size small 
small 
[hmcmillen]$ perl test.pl -size medium 
medium 
[hmcmillen]$ perl test.pl -size large 
large 
[hmcmillen]$ perl test.pl -size extra-large 
Error: incorrect specification of '-size' parameter 
Error: required parameter -size not found. 
Error: unrecognizable argument ('extra-large') 

(try 'test.pl -help' for more information) 
1

Это всего лишь один из нескольких проверок вам необходимо выполнить после возврата GetOptions.

  • Необходимо проверить, удалось ли выполнить GetOptions.
  • Возможно, вам потребуется проверить значение, предоставленное для каждого необязательного аргумента.
  • Возможно, вам нужно будет проверить количество аргументов в @ARGV.
  • Возможно, вам придется проверить аргументы в @ARGV.

Вот как я выполняю эти проверки:

use Getopt::Long qw(); 

my %sizes = map { $_ => 1 } qw(small medium large); 

my $opt_size; 

sub parse_args { 
    Getopt::Long::Configure(qw(:posix_default)); 

    $opt_size = undef; 

    Getopt::Long::GetOptions(
     'help|h|?' => \&exit_with_usage, 
     'size=s' => \$opt_size, 
    ) 
     or exit_bad_usage(); 

    exit_bad_usage("Invalid size.\n") 
     if defined($size) && !$sizes{$size}; 

    exit_bad_usage("Invalid number of arguments.\n") 
     if @ARGV; 
} 

Вот как я обрабатывать неудачи:

use File::Basename qw(basename); 

sub exit_with_usage { 
    my $prog = basename($0); 
    print("usage: $prog [options]\n"); 
    print("  $prog --help\n"); 
    print("\n"); 
    print("Options:"); 
    print(" --size {small|medium|large}\n"); 
    print("  Controls the size of ...\n" 
    exit(0); 
} 

sub exit_bad_usage { 
    my $prog = basename($0); 
    warn(@_) if @_; 
    die("Use $prog --help for help\n"); 
    exit(1); 
} 
Смежные вопросы