perltrap
СОДЕРЖАНИЕ
ИМЯ
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