Spec-Zone.ru › Perl 5.38

perltrap

СОДЕРЖАНИЕ

  • ИМЯ
  • ОПИСАНИЕ
    • Ловушки Awk
    • Ловушки C/C++
    • Ловушки JavaScript
    • Ловушки Sed
    • Ловушки оболочки
    • Ловушки 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. См. "Loop Control" в perlsyn.

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

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

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

  • Вы не можете взять адрес чего-либо, хотя аналогичный оператор в 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, Perl's for (также пишется foreach) не позволяет использовать в левой части произвольное выражение. Она должна быть переменной:

       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 не относится к переменной, объявленной внутри блока.

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

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

Ловушки Sed

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

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

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

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

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

Ловушки оболочки

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

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

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

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

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

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

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

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

Ловушки Perl

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

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

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

  • По внешнему виду невозможно определить, являются ли встроенные функции унарными операторами (например, 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–2023 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.38.0/perltrap

Spec-Zone.ru

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