Spec-Zone.ru › Perl 5.32

perltrap

СОДЕРЖАНИЕ

  • ИМЯ
  • ОПИСАНИЕ
    • Ловушки Awk
    • Ловушки C/C++
    • Ловушки JavaScript
    • Ловушки Sed
    • Ловушки Shell
    • Ловушки Perl

ИМЯ

perltrap - Ловушки Perl для неопытных

ОПИСАНИЕ

Самая большая ловушка – это забыть use warnings или использовать переключатель -w; см. warnings и "-w" в perlrun. Вторая по величине ловушка – это не сделать весь свой код исполняемым под use strict. Третья по величине ловушка – это не прочитать список изменений в этой версии Perl; см. perldelta.

Ловушки Awk

Пользователи awk должны обратить особое внимание на следующее:

  • Программа Perl выполняется только один раз, а не один раз для каждой строки ввода. Неявный цикл можно сделать с помощью -n или -p.

  • Модуль English, загруженный через

    use English;

    позволяет обращаться к специальным переменным (например, $/) с именами (например, $RS), как будто они находятся в awk; см. perlvar для получения подробной информации.

  • После всех простых операторов в Perl требуются точки с запятой (кроме конца блока). Перевод строки не является разделителем операторов.

  • Фигурные скобки необходимы в if и while.

  • Переменные в Perl начинаются с "$", "@" или "%".

  • Индексы массивов начинаются с 0. То же самое относится к позициям строк в substr() и index().

  • Вы должны определить, имеет ли ваш массив числовые или строковые индексы.

  • Значения хешей не появляются при простом обращении к ним.

  • Вы должны решить, хотите ли вы использовать строковые или числовые сравнения.

  • Чтение строки ввода не разбивает её для вас. Вы должны разбить её на массив самостоятельно. И оператор split() имеет другие аргументы, чем в awk.

  • Текущая строка ввода обычно находится в $_, а не в $0. Обычно в ней нет символа новой строки. ($0 — имя исполняемой программы.) См. perlvar.

  • $<цифра> не относится к полям — она относится к подстрокам, сопоставленным последним шаблоном.

  • Оператор print() не добавляет разделители полей и записей, если не задать $, и $\. Вы можете установить $OFS и $ORS, если используете модуль English.

  • Вы должны открыть файлы перед выводом в них.

  • Оператор диапазона – это "..", а не запятая. Оператор запятая работает как в C.

  • Оператор совпадения – это "=~", а не "~". ("~" — это оператор побитового дополнения, как в C.)

  • Оператор возведения в степень – это "**", а не "^". "^" — это оператор XOR, как в C. (Вы чувствуете, что awk в принципе несовместим с C.)

  • Оператор конкатенации – это ".", а не пустая строка. (Использование пустой строки сделало бы /pat/ /pat/ неразборчивым, потому что третий слеш интерпретировался бы как оператор деления — лексический анализатор, в действительности, немного контекстно чувствителен к операторам, таким как "/", "?", и ">". И, собственно, "." сам по себе может быть началом числа.)

  • Ключевые слова next, exit, и continue работают по-другому.

  • Следующие переменные работают по-другому:

    Awk       Perl
    ARGC      scalar @ARGV (compare with $#ARGV)
    ARGV[0]   $0
    FILENAME  $ARGV
    FNR       $. - something
    FS        (whatever you like)
    NF        $#Fld, or some such
    NR        $.
    OFMT      $#
    OFS       $,
    ORS       $\
    RLENGTH   length($&)
    RS        $/
    RSTART    length($`)
    SUBSEP    $;
  • Вы не можете установить $RS на шаблон, только на строку.

  • В случае сомнений, запустите конструкцию awk через a2p и посмотрите, что получится.

Ловушки C/C++

Программисты, знакомые с C и C++, должны обратить внимание на следующее:

  • Фигурные скобки необходимы в if и while.

  • Вы должны использовать elsif вместо else if.

  • Ключевые слова break и continue из C в Perl становятся last и next, соответственно. В отличие от C, они не работают внутри do { } while конструкций. См. "Управление циклами" в perlsyn.

  • Оператор switch называется given/when и доступен только в Perl 5.10 или более поздних версиях. См. "Операторы switch" в perlsyn.

  • Переменные в Perl начинаются с "$", "@" или "%".

  • Комментарии начинаются с "#", а не "/*" или "//". Perl может интерпретировать комментарии C/C++ как операторы деления, незавершенные регулярные выражения или оператор определённого-или.

  • Вы не можете взять адрес чего-либо, хотя похожий оператор в Perl — это обратная косая черта, которая создаёт ссылку.

  • ARGV должно быть заглавным. $ARGV[0] — это argv[1] в C, а argv[0] превращается в $0.

  • Системные вызовы, такие как link(), unlink(), rename() и т. д., возвращают ненулевое значение при успешном выполнении, а не 0. (system(), однако, возвращает ноль при успешном выполнении.)

  • Обработчики сигналов работают с именами сигналов, а не с числами. Используйте kill -l для получения их имён на вашей системе.

Ловушки JavaScript

Внимательные программисты JavaScript должны обратить внимание на следующее:

  • В Perl бинарный + всегда является сложением. $string1 + $string2 преобразует обе строки в числа, а затем складывает их. Чтобы конкатенировать две строки, используйте оператор ..

  • Унарный оператор + ничего не делает в Perl. Он существует, чтобы избежать синтаксических неоднозначностей.

  • В отличие от for...in, оператор for (также пишется foreach) Perl не допускает, чтобы левая часть была произвольным выражением. Она должна быть переменной:

    for my $variable (keys %hash) {
         ...
    }

    Кроме того, не забудьте keys, поскольку foreach my $kv (%hash) {} итерируется по ключам и значениям, и обычно не является полезным ($kv было бы ключом, затем значением и так далее).

  • Чтобы проитерироваться по индексам массива, используйте foreach my $i (0 .. $#array) {}. foreach my $v (@array) {} итерируется по значениям.

  • Perl требует фигурных скобок после if, while, foreach, и т. д.

  • В Perl else if пишется как elsif.

  • ? : имеет более высокий приоритет, чем присваивание. В JavaScript можно написать:

    condition ? do_something() : variable = 3

    и переменная присваивается только если условие ложно. В Perl вам нужны скобки:

    $condition ? do_something() : ($variable = 3);

    Или просто используйте if.

  • Perl требует точек с запятой для разделения операторов.

  • Переменные, объявленные с my, влияют только на код после объявления. Вы не можете написать $x = 1; my $x; и ожидать, что первое присваивание повлияет на ту же переменную. Вместо этого оно присвоит значение ранее объявленной переменной во внешней области видимости или глобальной переменной.

    Также обратите внимание, что переменная становится видимой только в последующем операторе. Это означает, что в my $x = 1 + $x вторая $x относится к ранее объявленной переменной.

  • Переменные my имеют область видимости текущего блока, а не текущей функции. Если вы напишете {my $x;} $x;, вторая $x не ссылается на ту, которая была объявлена внутри блока.

  • Члены объекта не могут быть доступны как переменные. Наиболее близкий аналог with(object) { method() } в Perl — for, который может сделать $_ псевдонимом для объекта:

    for ($object) {
        $_->method;
    }
  • Объект или класс, к которому применяется метод, передаётся как один из аргументов метода, а не как отдельное значение this.

Ловушки Sed

Опытные программисты sed должны обратить внимание на следующее:

  • Программа Perl выполняется только один раз, а не один раз для каждой строки ввода. Неявный цикл можно сделать с помощью -n или -p.

  • Обратные ссылки в подстановках используют "$" вместо "\".

  • Метасимволы для сопоставления шаблонов "(", ")", и "|" не имеют обратных косых черт.

  • Оператор диапазона — это ..., а не запятая.

Ловушки Shell

Опытные программисты shell должны обратить внимание на следующее:

  • Оператор обратных кавычек выполняет интерполяцию переменных, не учитывая наличие одинарных кавычек в команде.

  • Оператор обратных кавычек не выполняет преобразование возвращаемого значения, в отличие от csh.

  • Shell (особенно csh) выполняет несколько уровней подстановок в каждой командной строке. Perl выполняет подстановку только в определённых конструкциях, таких как двойные кавычки, обратные кавычки, угловые скобки и шаблоны поиска.

  • Shell интерпретирует скрипты по частям. Perl компилирует всю программу перед её выполнением (за исключением BEGIN блоков, которые выполняются во время компиляции).

  • Аргументы доступны через @ARGV, а не через $1, $2 и т. д.

  • Окружение не становится доступным как отдельные скалярные переменные автоматически.

  • Оператор test shell использует "=", "!=", "<" и т. д. для строковых сравнений и "-eq", "-ne", "-lt" и т. д. для числовых сравнений. Это противоположно Perl, который использует eq, ne, lt для строковых сравнений и ==, != < и т. д. для числовых сравнений.

Ловушки Perl

Опытные программисты Perl должны обратить внимание на следующее:

  • Помните, что многие операции ведут себя по-разному в контексте списка и в скалярном контексте. Подробнее см. perldata.

  • Избегайте неявных имен (barewords), особенно полностью прописных. По внешнему виду невозможно определить, является ли bareword функцией или строкой. Используя кавычки для строк и скобки для вызовов функций, вы никогда не перепутаете их.

  • По внешнему виду нельзя определить, являются ли встроенные функции унарными операторами (например, chop() и chdir()) или операторами для списков (например, print() и unlink()). (За исключением прототипирования, пользовательские подпрограммы могут быть только операторами для списков, а не унарными). См. perlop и perlsub.

  • Люди с трудом запоминают, что некоторые функции по умолчанию используют $_, @ARGV или что-то ещё, но другие, которые вы могли бы ожидать, не делают этого.

  • Конструкт <FH> не является именем дескриптора файла, это операция чтения строки из этого дескриптора. Прочитанные данные присваиваются $_ только в том случае, если чтение файла является единственным условием в цикле while:

    while (<FH>)      { }
    while (defined($_ = <FH>)) { }..
    <FH>;  # data discarded!
  • Помните, что не следует использовать = когда вам нужно =~; эти два конструкта сильно отличаются:

    $x =  /foo/;
    $x =~ /foo/;
  • Конструкт do {} не является настоящим циклом, для которого можно использовать управляющие конструкции циклов.

  • Используйте my() для локальных переменных, когда это возможно (но см. perlform в тех случаях, когда этого нельзя делать). Используя local(), вы фактически создаёте локальное значение для глобальной переменной, что открывает возможность непредвиденных побочных эффектов динамического области видимости.

  • Если вы локализуете экспортируемую переменную в модуле, её экспортируемое значение не изменится. Локальное имя становится псевдонимом для нового значения, но внешнее имя по-прежнему является псевдонимом для исходного.

Как и всегда, если что-либо из этого будет официально объявлено ошибкой, оно будет исправлено и удалено.

© 1993–2020 Larry Wall and others
Licensed under the GNU General Public License version 1 or later, or the Artistic License.
The Perl logo is a trademark of the Perl Foundation.
https://perldoc.perl.org/5.32.0/perltrap

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API