Spec-Zone.ru › Perl 5.30

perltrap

СОДЕРЖАНИЕ

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

ИМЯ

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

ОПИСАНИЕ

Самая большая ловушка — забыть use warnings или использовать переключатель -w; см. warnings и 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; и ожидать, что первое присваивание повлияет на ту же переменную. Вместо этого оно будет присвоено переменной $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.

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

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

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

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

  • Оператор test шелла использует "=", "!=", "<" и т. п. для строковых сравнений и "-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.30.3/perltrap

Spec-Zone.ru

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