Могу ли я вызвать Getopts несколько раз в Perl? - PullRequest
1 голос
/ 06 июня 2011

Я новичок в Perl, поэтому, пожалуйста, постарайтесь набраться терпения к этому моему вопросу.

Похоже, что если я сделаю несколько вызовов метода perl Getopts :: Long :: GetOpts, второй вызов полностью игнорируется.

  1. Это нормально ?? (почему)

  2. Каковы альтернативы этому процессу ??

(На самом деле я написал модуль, где я делаю вызов GetOpts, и скрипт, использующий мой модуль, тоже пытается это сделать, но кажется, что скрипт не получает требуемые опции)

Спасибо, Neeraj

Ответы [ 4 ]

8 голосов
/ 06 июня 2011

Getopts :: Long изменяет @ARGV, пока он работает, поэтому он может оставить значения без переключателей в @ARGV, когда завершит обработку переключателей.Поэтому, когда вы делаете второй вызов, в @ARGV ничего не остается для анализа и ничего полезного не происходит.

Однако, есть GetOptionsFromArray:

По умолчанию GetOptions анализирует параметры, присутствующие в глобальном массиве @ARGV.Специальная запись GetOptionsFromArray может использоваться для анализа параметров из произвольного массива.

Таким образом, вы можете использовать GetOptionsFromArray для копии @ARGV (или некоторого другого массива), если вам нужно проанализироватьсписок несколько раз.

3 голосов
/ 06 июня 2011

Я запускал GetOptions из GetOpts::Long несколько раз в одной программе.У меня есть .optrc файл, содержащий параметры командной строки, которые могут быть переопределены командной строкой.Примерно так же работают .cvsrc и .exrc.

Чтобы сделать это, я запускаю GetOptions для файла .optrc и затем для того, что находится в @ARGV.В старых версиях GetOptions мне приходилось сохранять @ARGV, бросать .optrc в @ARGV, обрабатывать его с GetOptions, а затем восстанавливать @ARGV и запускать GetOptions для этого.Новые версии GetOpts :: Long теперь позволяют указывать массив вместо использования @ARGV.

0 голосов
/ 13 декабря 2013

Разве это не то, для чего предназначено ключевое слово "local"?

{
    local @ARGV = @ARGV;
    our $opt_h;
    &getopts('h');
    &printUsage if $opt_h;
}


# Now that the local version of @ARGV has gone out of scope, the original version of @ARGV is restored.

while (@ARGV){
    my $arg = shift @ARGV;
0 голосов
/ 23 сентября 2012

Создание копий @ARGV заставит вас снова и снова анализировать один и тот же набор параметров.Если это то, что вы хотите, хорошо.Но.

Предположим, у вас есть набор модулей, которые вы используете в вашей программе, которые могут распознавать только часть вашего @ARGV.Вам нужно вызывать GetOptions для каждого из этих модулей, использовать каждую из опций, которую модуль может распознать, и оставить остальные опции в @ARGV для обработки другими модулями.

Вы можете настроить Getopt :: Long, чтобы сделать это, вызвав

Getopt::Long::Configure qw/pass_through/;

Но смотрите perldoc Getopt :: Long для различных побочных эффектов конфигурации!

Пример: скрипт(o1.pl) способен распознавать несколько опций и два модуля (o1 :: p1 и o1 :: p2), которые должны читать свои собственные опции

o1.pl:

! /Источник usr / bin / perl

use Getopt::Long;

use o1::p1;
use o1::p2;
# now o1::p1 and o1::p2 already consumed recognizable options
#no need to configure pass_through since main:: will get to see only its options
#Getopt::Long::Configure(qw/pass_through/);

my %main_options = ( 'define' => {}, );
print "main: \@ARGV = " . join (', ', @ARGV) . "\n";
GetOptions(\%main_options, "main-vi=i","verbose",'define=s');

use Data::Dumper;
print "main_options: ", Dumper(\%main_options);
print "p1 options: ", Dumper(\%o1::p1::options);
print "p2 options: ", Dumper(\%o1::p2::options);
exit 0;

o1 :: p1 (в o1 / p1.pm):

package o1::p1;
use Getopt::Long;
Getopt::Long::Configure qw/pass_through/;

%options = ();
print "package p1: \@ARGV = " . join (', ', @ARGV) . "\n";;

GetOptions(\%options, "p1-v1=s", "p1-v2=i");


1;

o1 :: p2 source (в o1 / p2.pm):

package o1::p2;
use Getopt::Long;
Getopt::Long::Configure 'pass_through';

%options = ();
print "package p2: \@ARGV=". join (', ', @ARGV). "\n";
GetOptions(\%options, "p2-v1=s", "p2-v2=i");

1;

при запуске o1.pl с:

perl o1.pl  --main-vi=1 --verbose  --define a=ss --p1-v1=k1 --p1-v2=42 --define b=yy --p2-v1=k2  --p2-v2=66

даст следующий (ожидаемый) вывод (p1 использовал свои параметры, затем p2 сделал это, затем main был оставлен со чем оно знает):

package p1: @ARGV = --main-vi=1, --verbose, --define, a=ss, --p1-v1=k1, --p1-v2=42, --define, b=yy, --p2-v1=k2, --p2-v2=66
package p2: @ARGV=--main-vi=1, --verbose, --define, a=ss, --define, b=yy, --p2-v1=k2, --p2-v2=66
main: @ARGV = --main-vi=1, --verbose, --define, a=ss, --define, b=yy
main_options: $VAR1 = {
          'verbose' => 1,
          'define' => {
                        'a' => 'ss',
                        'b' => 'yy'
                      },
          'main-vi' => 1
        };
p1 options: $VAR1 = {
          'p1-v1' => 'k1',
          'p1-v2' => 42
        };
p2 options: $VAR1 = {
          'p2-v1' => 'k2',
          'p2-v2' => 66
        };
...