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++ как операторы деления, незавершенные регулярные выражения или оператор определённого-или.
-
Вы не можете взять адрес чего-либо, хотя похожий оператор в 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.
-
Shell (особенно csh) выполняет несколько уровней подстановок в каждой командной строке. Perl выполняет подстановку только в определённых конструкциях, таких как двойные кавычки, обратные кавычки, угловые скобки и шаблоны поиска.
-
Shell интерпретирует скрипты по частям. Perl компилирует всю программу перед её выполнением (за исключением
BEGINблоков, которые выполняются во время компиляции). -
Аргументы доступны через @ARGV, а не через $1, $2 и т. д.
-
Окружение не становится доступным как отдельные скалярные переменные автоматически.
-
Оператор
testshell использует "=", "!=", "<" и т. д. для строковых сравнений и "-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.32.0/perltrap