Чего Perlish путь состоит в том, чтобы выполнить итерации от объекта n в конец массива?

Если Вы хотите что-то, что даст Вам различную метрику программного обеспечения (сложность и т.д.) для Вашего кода затем, я настоятельно рекомендую SourceMonitor от Campswood Software . Это работает на C и C++ также, и это свободно.

6
задан Thomas Owens 5 October 2009 в 15:52
поделиться

8 ответов

Помимо использования модуля Getopt, как писал Синан, я бы, вероятно, пойти с:

my ( $operation, $file, @things ) = @ARGV;

А затем вы можете:

for my $thing_to_do ( @things ) {
...
}
17
ответ дан 8 December 2019 в 02:03
поделиться

IMHO, способ Perlish для выполнения того, что вам нужно, - это использовать один из модулей Getopt на CPAN .

Если вы все еще хотите сделать это вручную , Я бы выбрал второй вариант (это похоже на то, как мы обрабатываем первый аргумент вызова метода):

die "Must provide filename and operation\n" unless @ARGV >= 2;

my $op = shift @ARGV;
my $file = shift @ARGV;

if ( @ARGV ) {
    # handle the other arguments;
}
12
ответ дан 8 December 2019 в 02:03
поделиться

Я бы настоятельно рекомендовал использовать Getopt :: Long для анализа аргументов командной строки. Это стандартный модуль, он отлично работает и делает именно то, что вы пытаетесь сделать, с легкостью.

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

my $first_option = undef;
my $second_option = undef;

GetOptions ('first-option=s' => \$first_option, 
            'second-option=s' => \$second_option);

die "Didn't pass in first-option, must be xxxyyyzzz."
    if ! defined $first_option;
die "Didn't pass in second-option, must be aaabbbccc."
    if ! defined $second_option;

foreach my $arg (@ARGV) {
    ...
}

Это позволяет вам иметь длинное имя параметра и автоматически подставлять информацию в переменные для вас, и позволяет вам тестировать Это. Он даже позволяет вам добавлять дополнительные команды позже, без необходимости выполнять дополнительный анализ аргументов, например, добавляя параметр «версия» или «справка»:

# adding these to the above example...
my $VERSION = '1.000';
sub print_help { ... }

# ...and replacing the previous GetOptions with this...
GetOptions ('first-option=s' => \$first_option, 
            'second-option=s' => \$second_option)
            'version' => sub { print "Running version $VERSION"; exit 1 },
            'help' => sub { print_help(); exit 2 } );

Затем вы можете вызвать его из командной строки, используя - , - , первая буква или весь параметр, а GetOptions все расскажет за вас. Это делает вашу программу более надежной и легкой для понимания; Вы могли бы сказать, что это более "предположительно".

9
ответ дан 8 December 2019 в 02:03
поделиться

Вы можете использовать срез для извлечения второго. до последних элементов, например:

[dsm@localhost:~]$ perl -le 'print join ", ", @ARGV[2..$#ARGV];' 1 2 3 4 5 6 7 8 9 10 00
3, 4, 5, 6, 7, 8, 9, 10, 00
[dsm@localhost:~]$ 

однако вам, вероятно, следует использовать shift (или даже лучше, GetOpt :: Long )

6
ответ дан 8 December 2019 в 02:03
поделиться

Самый стандартный способ делать что-то в Perl - через CPAN.

Так что мой первый выбор будет Getopt :: Лонг . Также есть руководство по DevShed: Обработка параметров командной строки с помощью Perl

7
ответ дан 8 December 2019 в 02:03
поделиться

ответ deepesz - один из хороших вариантов.

Также нет ничего плохого в вашем втором варианте:

my $op     = shift; # implicit shift from @ARGV
my $file   = shift; 
my @things = @ARGV;

# iterate over @things;

Вы также можете пропустить копирование @ARGV в @things и работать непосредственно с ним. Однако, если сценарий не будет очень коротким, очень простым и вряд ли станет более сложным со временем, я бы не стал слишком много сокращать.

Выберете ли вы подход deepesz или этот, в значительной степени дело вкуса.

. Решение, что лучше, на самом деле вопрос философии. Суть проблемы в том, следует ли вам изменять глобальные переменные, такие как @ARGV . Кто-то скажет, что в этом нет ничего страшного, если это делается на видном месте. Другие будут возражать, чтобы оставить @ARGV нетронутым.

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

Getopt :: Long , как уже упоминалось. тоже отличный выбор.

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

Getopt :: Long , как уже упоминалось. тоже отличный выбор.

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

Getopt :: Long , как уже упоминалось. тоже отличный выбор.

3
ответ дан 8 December 2019 в 02:03
поделиться

Взгляните на MooseX :: Getopt , потому что он может возбудить ваш аппетит к еще большему Moosey! .

Пример MooseX :: Getopt:

# getopt.pl

{
    package MyOptions;
    use Moose;
    with 'MooseX::Getopt';

    has oper   => ( is => 'rw', isa => 'Int', documentation => 'op doc stuff' );
    has file   => ( is => 'rw', isa => 'Str', documentation => 'about file' );
    has things => ( is => 'rw', isa => 'ArrayRef', default => sub {[]} );

    no Moose;
}

my $app = MyOptions->new_with_options;

for my $thing (@{ $app->things }) {
    print $app->file, " : ", $thing, "\n";
}

# => file.txt : item1
# => file.txt : item2
# => file.txt : item3

Произойдет указанное выше при запуске следующим образом:

perl getopt.pl --oper 1 --file file.txt --things item1 --things item2 --things item3


Эти Moose типы проверяются ... ./ getopt --oper "not a number" выдает:

Value "not a number" invalid for option oper (number expected)

И бесплатно вы всегда получаете список использования; -)

usage: getopt.pl [long options...]
         --file         bit about file
         --oper         op doc stuff
         --things    

/ I3az /

3
ответ дан 8 December 2019 в 02:03
поделиться

Для более общего случая с любым массивом:

for(my $i=2; $i<@array; $i++) {
    print "$array[$i]\n";
}

Этот цикл проходит по массиву, начиная с третьего элемента (индекс 2). Очевидно, что конкретный пример, который вы указали, ответ depesz является наиболее простым и лучшим.

0
ответ дан 8 December 2019 в 02:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: