Забудьте на секунду о Getopt :: Std. Как модуль (или любой другой код) узнает, что bar
было значением a
, а не первым позиционным аргументом? Без средств для этого ваша грамматика будет неоднозначной, и для нее невозможно написать синтаксический анализатор.
Это можно решить одним из трех способов. (Ну, наверняка есть и другие.)
Решение 1 Разрешить повторение параметра и флага.
prog -a foo -a bar pos0 pos1
use Getopt::Long qw( GetOptions );
GetOptions(
'?|h|help' => \&help,
'a=s' => \my @opt_a,
)
or usage();
Решение 2 Используйте -a
, чтобы указать, что означают позиционные аргументы.
prog -a foo bar
use Getopt::Long qw( GetOptions );
GetOptions(
'?|h|help' => \&help,
'a' => \my @opt_a,
'b' => \my $opt_b,
)
or usage();
( $opt_a ? 1 : 0 ) + ( $opt_b ? 1 : 0 ) == 1
or usage("-a or -b must be specified, but not both");
my $opt_action = $opt_a ? 'a' : 'b';
@ARGV > 0
or usage("Invalid number of arguments");
Решение 3 Предположим, что все значения, следующие за -a
, принадлежат -a
Оказывается, есть стандартный способ обозначить начало позиционных аргументов. Использование --
будет отличать guish значения параметров от позиционных аргументов.
prog -a foo bar -- pos0 pos1
use Getopt::Long qw( GetOptions );
GetOptions(
'?|h|help' => \&help,
'a=s{1,}' => \my @opt_a,
)
or usage();
Однако --
обычно используется для защиты от позиционных аргументов, начинающихся с -
. Странно защищаться от позиционных аргументов не , начинающихся с -
.
Это также подвержено ошибкам. У людей возникнет искушение сделать следующее:
prog -a foo pos0 # XXX Doesn't work as expected!
Примечания:
- Я использовал Getopt :: Long. Если Getopt :: Std тоже может это сделать, отлично. Я использовал то, что знал.
- См. this для примера реализации
help
и usage
.