perltrap
СОДЕРЖАНИЕ
ИМЯ
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++ как операторы деления, незавершенные регулярные выражения или оператор 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,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. -
Обратные ссылки в заменах используют "$" вместо "\".
-
Метасимволы совпадения шаблонов "(", ")", и "|" не имеют обратных слешей.
-
Оператор диапазона —
..., а не запятая.
Ловушки Shell
Опытные программисты shell должны обратить внимание на следующее:
-
Оператор обратных кавычек выполняет интерполяцию переменных без учёта наличия одинарных кавычек в команде.
-
Оператор обратных кавычек не выполняет преобразование возвращаемого значения, в отличие от csh.
-
Shells (особенно csh) выполняют несколько уровней подстановки в каждой командной строке. Perl выполняет подстановку только в определённых конструкциях, таких как двойные кавычки, обратные кавычки, угловые скобки и шаблоны поиска.
-
Shells интерпретируют скрипты небольшими частями. Perl компилирует всю программу перед её выполнением (за исключением
BEGINблоков, которые выполняются во время компиляции). -
Аргументы доступны через @ARGV, а не $1, $2 и т. д.
-
Окружение не предоставляется автоматически как отдельные скалярные переменные.
-
Оператор сравнения shell использует "= ", "!=", "<" и т. д. для строковых сравнений и "-eq", "-ne", "-lt" и т. д. для числовых сравнений. Это обратный порядок по отношению к Perl, который использует
eq,ne,ltдля строковых сравнений и==,!=<и т. д. для числовых сравнений.
Ловушки Perl
Опытные программисты Perl должны обратить внимание на следующее:
-
Помните, что многие операции ведут себя по-разному в контексте списка, чем в скалярном. Подробности см. в perldata.
-
Избегайте «голых слов» (barewords), если это возможно, особенно полностью прописных. По внешнему виду невозможно определить, является ли «голое слово» функцией или строкой. Использование кавычек для строк и скобок для вызовов функций позволит избежать путаницы.
-
По внешнему виду невозможно определить, являются ли встроенные функции унарными операторами (например, 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–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.36.0/perltrap