Spec-Zone.ru › Perl 5.34

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

  • Члены объекта не могут быть доступны как переменные. Ближайший эквивалент 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.

  • Избегайте "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–2021 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.34.0/perltrap

Spec-Zone.ru

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