Обработка аргументов командной строки — базовая задача для Perl‑программ. Исторически Perl предоставил переменную @ARGV для доступа к аргументам, переданным скрипту. Проблема в том, что сложные сценарии могут включать флаги и ключ‑значение параметры, что потребует ручного разбора массива @ARGV. При неправильном подходе можно некорректно обработать параметры, пропустить обязательные значения или обработать лишние, что приводит к ошибкам в логике программы.
Решение — использовать систематизированную обработку: итерацию через @ARGV, анализ содержимого, обработку ключей и их значений.
Пример кода:
my %args; while (my $arg = shift @ARGV) { if ($arg =~ /^--(\w+)=?(.*)/) { my ($key, $val) = ($1, $2); if ($val eq '' && @ARGV) { $val = shift @ARGV; # следующее значение } $args{$key} = $val eq '' ? 1 : $val; } else { push @{$args{'_free'}}, $arg; } } print "Got foo: $args{foo} " if exists $args{foo};
Ключевые особенности:
Что произойдет, если аргумент передается в виде '--flag value', а не '--flag=value'?
Если обрабатывать только разделение через '=', значением будет пустая строка, и следующий элемент массива будет проигнорирован как самостоятельный аргумент. Решение — учитывать оба варианта при разборе:
if ($arg =~ /^--(\w+)=?(.*)/)
и если $val пуст, брать следующий элемент.
Как Perl ведёт себя с аргументами, содержащими пробелы?
Perl не разделяет аргументы внутри @ARGV по пробелам, все деление делает shell. Поэтому "--foo=bar baz" попадет как два разных элемента, если не брать строку в кавычки в командной строке. Это следует учитывать и всегда требовать от пользователя экранировать пробелы.
Можно ли модифицировать @ARGV при помощи shift, не потеряв исходные аргументы?
Shift меняет сам массив, оригинальный список аргументов восстановить нельзя. Если нужно сохранить исходное содержимое @ARGV, его нужно клонировать заранее:
my @original_argv = @ARGV;
Скрипт обрабатывал только ключи вида '--foo=bar', игнорируя '--foo bar', и падал с ошибкой при отсутствии значения.
Плюсы:
Минусы:
Добавили обработку обоих синтаксисов и проверку длины @ARGV, разрешили флаги‑переключатели.
Плюсы:
Минусы: