Obsługa argumentów wiersza poleceń to podstawowe zadanie dla programów w Perl. Historycznie Perl udostępnił zmienną @ARGV do uzyskiwania dostępu do argumentów przekazanych do skryptu. Problemem jest to, że skomplikowane scenariusze mogą obejmować flagi oraz parametry klucz-wartość, co wymaga ręcznego przetwarzania tablicy @ARGV. Przy niewłaściwym podejściu można niepoprawnie obsłużyć parametry, pominąć obowiązkowe wartości lub przetworzyć zbędne, co prowadzi do błędów w logice programu.
Rozwiązaniem jest systematyczne przetwarzanie: iteracja przez @ARGV, analiza zawartości, obsługa kluczy i ich wartości.
Przykład kodu:
my %args; while (my $arg = shift @ARGV) { if ($arg =~ /^--(\w+)=?(.*)/) { my ($key, $val) = ($1, $2); if ($val eq '' && @ARGV) { $val = shift @ARGV; # następna wartość } $args{$key} = $val eq '' ? 1 : $val; } else { push @{$args{'_free'}}, $arg; } } print "Otrzymano foo: $args{foo} " if exists $args{foo};
Kluczowe cechy:
Co się stanie, jeśli argument zostanie przekazany w formie '--flag value', a nie '--flag=value'?
Jeśli przetwarzać tylko rozdzielenie przez '=', wartością będzie pusty ciąg, a następny element tablicy zostanie zignorowany jako samodzielny argument. Rozwiązanie — uwzględnić obie opcje podczas analizy:
if ($arg =~ /^--(\w+)=?(.*)/)
i jeśli $val jest pusty, wziąć następny element.
Jak Perl zachowuje się z argumentami zawierającymi spacje?
Perl nie dzieli argumentów wewnątrz @ARGV na podstawie spacji, całe dzielenie odbywa się w powłoce. Dlatego "--foo=bar baz" trafi jako dwa różne elementy, jeśli nie umieścić ciągu w cudzysłowie w wierszu poleceń. Należy to uwzględnić i zawsze wymagać od użytkownika, aby odpowiednio skonwertował spacje.
Czy można modyfikować @ARGV za pomocą shift, nie tracąc oryginalnych argumentów?
Shift zmienia samą tablicę, oryginalnej listy argumentów nie można przywrócić. Jeśli trzeba zachować oryginalną zawartość @ARGV, należy ją wcześniej sklonować:
my @original_argv = @ARGV;
Skrypt przetwarzał tylko klucze w postaci '--foo=bar', ignorując '--foo bar', i kończył działanie z błędem w przypadku braku wartości.
Zalety:
Wady:
Dodano obsługę obu składni oraz sprawdzanie długości @ARGV, umożliwiono flagi-przełączniki.
Zalety:
Wady: