Spec-Zone.ru › Perl 5.28

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.

  • Оператор соответствия — "=~", а не "~". ("~" — это оператор дополнения по модулю 2, как и в 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.

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

  • Shells интерпретируют скрипты понемногу. 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> не является именем дескриптора файла, это операция readline для этого дескриптора. Прочитанные данные присваиваются $_ только в том случае, если чтение файла является единственным условием в цикле 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.28.3/perltrap

Spec-Zone.ru

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