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