perldata
СОДЕРЖАНИЕ
- ИМЯ
- ОПИСАНИЕ
- СМОТРИТЕ ТАКЖЕ
ИМЯ
perldata - Типы данных Perl
ОПИСАНИЕ
Имена переменных
Perl имеет три встроенных типа данных: скаляры, массивы скаляров и ассоциативные массивы скаляров, известные как «хэши». Скаляр — это одна строка (любого размера, ограниченная только доступной памятью), число или ссылка на что-либо (что будет обсуждаться в perlref). Обычные массивы представляют собой упорядоченные списки скаляров, индексированных по номеру, начиная с 0. Хэши — это неупорядоченные коллекции скалярных значений, индексированных соответствующим строковым ключом.
Значения обычно ссылаются по имени или через именованную ссылку. Первая буква имени указывает, к какому типу структуры данных она относится. Остальная часть имени указывает на конкретное значение, на которое она ссылается. Обычно это один идентификатор, то есть строка, начинающаяся с буквы или нижнего подчеркивания и содержащая буквы, нижние подчеркивания и цифры. В некоторых случаях это может быть цепочка идентификаторов, разделенных :: (или устаревшим '); все, кроме последнего, интерпретируются как имена пакетов для поиска области имен, в которой необходимо найти конечный идентификатор (см. "Пакеты" в perlmod для получения подробностей). Для более углубленного обсуждения идентификаторов см. "Разбор идентификаторов". Можно заменить простой идентификатор выражением, которое создает ссылку на значение во время выполнения. Более подробное описание этого содержится ниже и в perlref.
Perl также имеет свои собственные встроенные переменные, имена которых не следуют этим правилам. У них странные имена, чтобы они случайно не совпадали с вашими обычными переменными. Строки, соответствующие скобочным частям регулярного выражения, сохраняются под именами, содержащими только цифры после $ (см. perlop и perlre). Кроме того, несколько специальных переменных, предоставляющих доступ к внутренней работе Perl, имеют имена, содержащие знаки препинания. Они описаны в perlvar.
Скалярные значения всегда обозначаются символом '$', даже при ссылке на скаляр, который является частью массива или хэша. Символ '$' по своему значению похож на английское слово «the», указывая на ожидаемое единственное значение.
$days # the simple scalar value "days"
$days[28] # the 29th element of array @days
$days{'Feb'} # the 'Feb' value from hash %days
$#days # the last index of array @days Целые массивы (и срезы массивов и хэшей) обозначаются символом '@', который действует примерно как слова «эти» или «те» в английском языке, указывая на ожидаемые множественные значения.
@days # ($days[0], $days[1],... $days[n])
@days[3,4,5] # same as ($days[3],$days[4],$days[5])
@days{'a','c'} # same as ($days{'a'},$days{'c'}) Целые хэши обозначаются символом '%':
%days # (key1, val1, key2, val2 ...) Кроме того, подпрограммы называются с помощью начального символа '&', хотя это необязательно, если это однозначно, точно так же, как слово «делать» часто является избыточным в английском языке. Элементы таблицы символов могут называться с начальным символом '*', но пока вам это не нужно (если вообще когда-либо :-).
Каждый тип переменной имеет собственное пространство имен, как и несколько идентификаторов, не являющихся переменными. Это означает, что вы можете без опасения использовать одно и то же имя для скалярной переменной, массива или хэша — или, что более важно, для дескриптора файла, дескриптора каталога, имени подпрограммы, имени формата или метки. Это означает, что $foo и @foo — это две разные переменные. Это также означает, что $foo[1] является частью @foo, а не частью $foo. Это может показаться немного странным, но это нормально, потому что это странно.
Поскольку ссылки на переменные всегда начинаются с '$', '@' или '%', «зарезервированные» слова фактически не зарезервированы по отношению к именам переменных. Однако они зарезервированы по отношению к меткам и дескрипторам файлов, у которых нет начального специального символа. Например, у вас не может быть дескриптор файла с именем «log». Подсказка: вы можете сказать open(LOG,'logfile') вместо open(log,'logfile'). Использование прописных дескрипторов файлов также улучшает читаемость и защищает вас от конфликта с будущими зарезервированными словами. Регистр значится — «FOO», «Foo» и «foo» — это разные имена. Имена, начинающиеся с буквы или нижнего подчеркивания, также могут содержать цифры и нижние подчеркивания.
Можно заменить такое буквенно-цифровое имя выражением, которое возвращает ссылку на соответствующий тип. Для описания этого см. perlref.
Имена, начинающиеся с цифры, могут содержать только дополнительные цифры. Имена, которые не начинаются с буквы, нижнего подчеркивания, цифры или знака обратного слэша, ограничены одним символом, например, $% или $$. (Большинство этих имен из одного символа имеют предопределенное значение для Perl. Например, $$ — это текущий идентификатор процесса. И все такие имена зарезервированы для возможного использования Perl.)
Разбор идентификаторов
До Perl 5.18 правила того, что является допустимым идентификатором, были немного размытыми. Однако, как правило, все определенное здесь должно работать в предыдущих версиях Perl, в то время как обратное — граничные случаи, работающие в предыдущих версиях, но не определенные здесь, вероятно, не будут работать в более новых версиях. Важно отметить, что следующее относится только к идентификаторам без ключевых слов, как они встречаются в исходном коде Perl, а не к идентификаторам, введенным с помощью символических ссылок, у которых ограничений гораздо меньше. Если работаете под влиянием use utf8; pragmy, применяются следующие правила:
/ (?[ ( \p{Word} & \p{XID_Start} ) + [_] ])
(?[ ( \p{Word} & \p{XID_Continue} ) ]) * /x То есть, «начальный» символ, за которым следует любое количество «продолжающих» символов. Perl требует, чтобы каждый символ в идентификаторе также соответствовал \w (это предотвращает некоторые проблемные случаи); и Perl дополнительно принимает имена идентификаторов, начинающиеся с нижнего подчеркивания.
Если не под use utf8, исходный код рассматривается как ASCII + 128 дополнительных универсальных символов, и идентификаторы должны соответствовать
/ (?aa) (?!\d) \w+ /x То есть, любой буквенно-цифровой символ в кодировке ASCII, при условии, что первый символ не является цифрой.
В Perl есть два разделителя пакетов: двойное двоеточие (::) и одиночная кавычка ('). Использование ' в качестве разделителя пакетов устарело и будет удалено в Perl 5.40. Обычные идентификаторы могут начинаться или заканчиваться двойным двоеточием и могут содержать несколько частей, разделенных двойными двоеточиями. Одиночные кавычки имеют аналогичные правила, но с исключением, что они не могут стоять в конце идентификатора: то есть, $'foo и $foo'bar допустимы, но $foo'bar' — нет.
Кроме того, если идентификатор предшествует сигилу — то есть, если идентификатор является частью имени переменной — он может быть необязательно заключен в фигурные скобки.
Хотя вы можете смешивать двойные двоеточия с одиночными кавычками, кавычки должны следовать за двоеточиями: $::::'foo и $foo::'bar допустимы, но $::'::foo и $foo'::bar — нет.
В совокупности грамматика для соответствия основному идентификатору становится
/
(?(DEFINE)
(?<variable>
(?&sigil)
(?:
(?&normal_identifier)
| \{ \s* (?&normal_identifier) \s* \}
)
)
(?<normal_identifier>
(?: :: )* '?
(?&basic_identifier)
(?: (?= (?: :: )+ '? | (?: :: )* ' ) (?&normal_identifier) )?
(?: :: )*
)
(?<basic_identifier>
# is use utf8 on?
(?(?{ (caller(0))[8] & $utf8::hint_bits })
(?&Perl_XIDS) (?&Perl_XIDC)*
| (?aa) (?!\d) \w+
)
)
(?<sigil> [&*\$\@\%])
(?<Perl_XIDS> (?[ ( \p{Word} & \p{XID_Start} ) + [_] ]) )
(?<Perl_XIDC> (?[ \p{Word} & \p{XID_Continue} ]) )
)
/x Между тем, специальные идентификаторы не следуют приведенным выше правилам; в основном все идентификаторы в этой категории имеют специальное значение, заданное Perl. Поскольку у них есть специальные правила разбора, их обычно нельзя полностью квалифицировать. Они имеют шесть форм (но не используйте формы 5 и 6):
-
Сигил, за которым следуют только цифры, соответствующие
\p{POSIX_Digit}, такие как$0,$1, или$10000. -
Сигил, за которым следует один символ, соответствующий свойству
\p{POSIX_Punct}, такой как$!или%+, за исключением символа"{", который не работает. -
Сигил, за которым следует знак обратного слэша и любой из символов
[][A-Z^_?\], такой как$^Vили$^]. -
Аналогично предыдущему, сигил, за которым следует текстовое голое слово в фигурных скобках, где первый символ — знак обратного слэша. Следующий символ — любой из символов
[][A-Z^_?\], за которым следуют буквенно-цифровые символы ASCII. Пример${^GLOBAL_PHASE}. -
Сигил, за которым следует любой одиночный символ в диапазоне
[\xA1-\xAC\xAE-\xFF]при отсутствии"use utf8". (При"use utf8", применяются обычные правила идентификаторов, приведенные ранее в этом разделе.) Использование неграфических символов (управляющих символов C1, ПРОБЕЛА, НЕПЕРЕРЫВНОГО и МЯГКОЙ ТИРЕ) запрещено с версии v5.26.0. Использование других символов не рекомендуется, так как они все зарезервированы для специального значения в Perl, и ни одно из них в настоящее время не имеет специального значения, хотя это может измениться без предварительного уведомления.Обратите внимание, что следствием этой формы является то, что существуют идентификаторы, допустимые только при
"use utf8", и наоборот, например, идентификатор$étatдопустим в"use utf8", но в противном случае считается одиночной переменной$éза которой следует голое слово"tat", комбинация которых является синтаксической ошибкой. -
Это сочетание двух предыдущих форм. Оно допустимо только при отсутствии
"use utf8"(при"use utf8"применяются обычные правила идентификаторов). Форма представляет собой сигил, за которым следует текст в фигурных скобках, где первый символ — любой из символов в диапазоне[\x80-\xFF]и за которым следуют буквенно-цифровые символы ASCII до заключительной фигурной скобки.Те же оговорки, что и в предыдущей форме: неграфические символы больше не разрешены с «use utf8», использование этой формы не рекомендуется, а utf8ность играет большую роль.
До Perl v5.24 неграфические ASCII управляющие символы также допускались в некоторых ситуациях; это было устарело с v5.20.
Контекст
Интерпретация операций и значений в Perl порой зависит от контекста, окружающего операцию или значение. Существуют два основных контекста: список и скаляр. Некоторые операции возвращают списки в контексте списка и скалярные значения в противном случае. Если это применимо к операции, об этом будет указано в документации к этой операции. Другими словами, Perl перегружает некоторые операции, основываясь на том, ожидается ли возвращаемое значение единственным или множественным. Некоторые слова на английском языке работают таким образом, например, «рыба» и «овцы».
Взаимно, операция предоставляет каждый из своих аргументов либо скалярный, либо списковый контекст. Например, если вы скажете
int( <STDIN> ) то операция с целыми числами предоставит скалярный контекст для оператора <>, который прочитает одну строку из стандартного ввода STDIN и передаст её обратно операции с целыми числами, которая затем определит целое значение этой строки и вернёт его. Если же вы скажете
sort( <STDIN> ) то операция сортировки предоставит списковый контекст для <>, которая будет читать все доступные строки до конца файла, и передаст этот список строк в процедуру сортировки, которая затем отсортирует эти строки и вернёт их как список в контекст, в котором находилась операция сортировки.
Присваивание немного специфично, поскольку оно использует свой левый аргумент для определения контекста правого аргумента. Присваивание скаляру вычисляет правую часть в скалярном контексте, а присваивание массиву или хэшу вычисляет правую часть в списковом контексте. Присваивание списку (или срезу, который по сути является списком) также вычисляет правую часть в списковом контексте.
Когда вы используете use warnings пragma или командную опцию Perl -w, вы можете увидеть предупреждения об бесполезном использовании констант или функций в «пустом контексте». Пустой контекст означает, что значение было проигнорировано, например, в операторе, содержащем только "fred"; или getpwuid(0);. Тем не менее, это всё ещё считается скалярным контекстом для функций, которым важно, вызываются ли они в списковом контексте или нет.
Пользовательские подпрограммы могут заботиться о том, вызываются ли они в пустом, скалярном или списковом контексте. Большинству подпрограмм об этом беспокоиться не нужно. Это потому, что и скаляры, и списки автоматически интерполируются в списки. См. "wantarray" в perlfunc, чтобы узнать, как динамически определить контекст вызова вашей функции.
Скалярные значения
Все данные в Perl являются скалярами, массивами скаляров или хэшами скаляров. Скаляр может содержать одно единственное значение в трёх различных формах: число, строка или ссылка. В целом, преобразование из одной формы в другую происходит прозрачно. Хотя скаляр напрямую не может содержать несколько значений, он может содержать ссылку на массив или хэш, который, в свою очередь, содержит несколько значений.
Скаляры не обязательно являются чем-то одним или другим. Нет места для объявления скалярной переменной как «строкового» типа, «числового» типа, «ссылочного» типа или любого другого. Из-за автоматического преобразования скаляров, операции, возвращающие скаляры, не должны (и не могут) заботиться о том, ищет ли вызывающий их строку, число или ссылку. Perl — это контекстно-полиморфный язык, чьи скаляры могут быть строками, числами или ссылками (включая объекты). Хотя строки и числа считаются практически одинаковыми для почти всех целей, ссылки являются жёстко типизированными, не преобразуемыми указателями со встроенным подсчётом ссылок и вызовом деструкторов.
Скалярное значение интерпретируется как ЛОЖЬ в булевом смысле, если оно не определено, является пустой строкой или числом 0 (или его строковым эквивалентом, «0»), и как ИСТИНА в противном случае. Булев контекст — это просто особый вид скалярного контекста, где никогда не происходит преобразование в строку или число. Отрицание истинного значения с помощью ! или not возвращает специальное ложное значение. При оценке как строки оно обрабатывается как "", а как число — как 0. Большинство операторов Perl, возвращающих истину или ложь, ведут себя таким образом.
На самом деле существует два вида пустых строк (иногда их называют «пустыми» строками), определённая и неопределённая. Определённая версия — это просто строка длиной ноль, например "". Неопределённая версия — это значение, которое указывает на отсутствие реального значения для чего-либо, например, при ошибке, в конце файла или при обращении к неинициализированной переменной или элементу массива или хэша. Хотя в ранних версиях Perl неопределённый скаляр мог стать определённым при первом использовании в месте, ожидающем определённое значение, это больше не происходит, за исключением редких случаев автовивификации, как описано в perlref. Вы можете использовать оператор defined() для определения, определено ли скалярное значение (это не имеет смысла для массивов или хэшей), и оператор undef() для создания неопределённого значения.
Чтобы узнать, является ли данная строка допустимым ненулевым числом, иногда достаточно проверить её на соответствие как числовому 0, так и лексическому «0» (хотя это вызовет шум, если включены предупреждения). Это потому, что строки, которые не являются числами, считаются 0, как и в awk:
if ($str == 0 && $str ne "0") {
warn "That doesn't look like a number";
} Этот метод может быть лучшим, потому что иначе вы не будете правильно обрабатывать такие обозначения IEEE, как NaN или Infinity. В других случаях вы можете предпочесть определить, может ли строка использоваться численно, вызвав функцию POSIX::strtod() или проверив свою строку с помощью регулярного выражения (как описано в perlre).
warn "has nondigits" if /\D/;
warn "not a natural number" unless /^\d+$/; # rejects -3
warn "not an integer" unless /^-?\d+$/; # rejects +3
warn "not an integer" unless /^[+-]?\d+$/;
warn "not a decimal number" unless /^-?\d+\.?\d*$/; # rejects .2
warn "not a decimal number" unless /^-?(?:\d+(?:\.\d*)?|\.\d+)$/;
warn "not a C float"
unless /^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/; Длина массива — скалярное значение. Вы можете найти длину массива @days, вычислив $#days, как и в csh. Однако это не длина массива; это индекс последнего элемента, который является другим значением, поскольку обычно есть нулевой элемент. Присваивание $#days фактически изменяет длину массива. Укорочение массива таким образом уничтожает промежуточные значения. Увеличение длины массива, который был ранее укорочен, не восстанавливает значения, которые были в этих элементах.
Вы также можете получить некоторое незначительное улучшение эффективности, предварительно увеличив размер массива, который будет большим. Вы также можете увеличить массив, присвоив значение элементу, находящемуся за пределами массива. Вы можете обнулить массив, присвоив ему пустой список (). Следующие выражения эквивалентны:
@whatever = ();
$#whatever = -1; Если вы оцениваете массив в скалярном контексте, он возвращает длину массива. (Обратите внимание, что это не относится к спискам, которые возвращают последнее значение, подобно оператору запятой в C, или встроенным функциям, которые возвращают то, что они сочтут нужным вернуть.) Следующее выражение всегда верно:
scalar(@whatever) == $#whatever + 1; Некоторые программисты предпочитают использовать явное преобразование, чтобы не оставлять никаких сомнений:
$element_count = scalar(@whatever); Если вы оцениваете хэш в скалярном контексте, он возвращает ложное значение, если хэш пуст. Если есть какие-либо пары ключ/значение, он возвращает истинное значение. Более точное определение зависит от версии.
До Perl 5.25 возвращаемое значение было строкой, состоящей из количества используемых бакетов и количества выделенных бакетов, разделенных слешем. Это практически полезно только для того, чтобы определить, плохо ли работает внутренний алгоритм хэширования Perl для вашего набора данных. Например, вы помещаете 10 000 элементов в хэш, но при вычислении %HASH в скалярном контексте получается "1/16", что означает, что только один из шестнадцати бакетов был задействован и предположительно содержит все 10 000 ваших элементов. Этого не должно происходить.
Начиная с Perl 5.25, возвращаемое значение — это количество ключей в хэше. Если вам нужен доступ к старому поведению, вы можете использовать Hash::Util::bucket_ratio() вместо него.
Если связанный хэш оценивается в скалярном контексте, вызывается метод SCALAR (с возвратом к FIRSTKEY) .
Вы можете предварительно выделить память для хэша, присвоив значения функции keys(). Это округляет выделенные бакеты до ближайшей степени двойки:
keys(%users) = 1000; # allocate 1024 buckets Конструкторы скалярных значений
Числовые литералы задаются в любом из следующих форматов с плавающей точкой или целых чисел:
12345
12345.67
.23E-10 # a very small number
3.14_15_92 # a very important number
4_294_967_296 # underscore for legibility
0xff # hex
0xdead_beef # more hex
0377 # octal (only numbers, begins with 0)
0o12_345 # alternative octal (introduced in Perl 5.33.5)
0b011011 # binary
0x1.999ap-4 # hexadecimal floating point (the 'p' is required) Вам разрешается использовать нижние подчеркивания в числовых литералах между цифрами для повышения удобочитаемости (но не несколько нижних подчеркиваний подряд: 23__500 не допустимо; 23_500 допустимо). Например, вы можете группировать двоичные цифры по три (как для аргумента Unix-стиля режима, такого как 0b110_100_100) или по четыре (для представления полубайтов, как в 0b1010_0110) или другими группами.
Строковые литералы обычно ограничены одинарными или двойными кавычками. Они работают примерно так же, как кавычки в стандартных оболочках Unix: строковые литералы в двойных кавычках подвергаются замене обратным слешем и переменных; строковые литералы в одинарных кавычках — нет (кроме \' и \\). Применяются обычные правила C-стиля обратного слеша для создания символов, таких как перевод строки, табуляция и т. д., а также некоторых более экзотических форм. См. "Операторы кавычек и подобные им" в perlop для получения списка.
Шестнадцатеричные, восьмеричные или двоичные представления в строковых литералах (например, '0xff') не преобразуются автоматически в их целые представления. Функции hex() и oct() выполняют эти преобразования за вас. См. "hex" в perlfunc и "oct" в perlfunc для получения дополнительной информации.
Шестнадцатеричные числа с плавающей точкой могут начинаться так же, как шестнадцатеричный литерал, и могут быть продолжены необязательной дробной шестнадцатеричной частью, но должны быть завершены p, необязательным знаком и степенью двойки. Этот формат полезен для точного представления чисел с плавающей точкой, избегая преобразований в десятичные числа с плавающей точкой и, следовательно, избегая возможной потери точности. Обратите внимание, что, хотя большинство современных платформ используют 64-битные числа с плавающей точкой IEEE 754, не все это делают. Другим потенциальным источником (низкоразрядных) различий являются режимы округления чисел с плавающей точкой, которые могут различаться между процессорами, операционными системами и компиляторами, и Perl не контролирует их.
Вы также можете непосредственно вставлять переводы строк в свои строки, т. е. они могут заканчиваться на другой строке, чем начинаются. Это удобно, но если вы забудете заключительную кавычку, ошибка не будет сообщена, пока Perl не найдёт другую строку, содержащую символ кавычки, что может произойти намного позже в скрипте. Подстановка переменных внутри строк ограничена скалярными переменными, массивами и срезами массивов или хэшей. (Другими словами, именами, начинающимися с $ или @, за которыми следует необязательное выражение в квадратных скобках в качестве индекса.) Следующий фрагмент кода выводит "Цена — $100."
$Price = '$100'; # not interpolated
print "The price is $Price.\n"; # interpolated В Perl нет двойной интерполяции, поэтому $100 остаётся без изменений.
По умолчанию, числа с плавающей точкой, подставляемые в строки, используют точку («.») в качестве десятичного разделителя. Если use locale активно, а POSIX::setlocale() был вызван, символ, используемый в качестве десятичного разделителя, зависит от локали LC_NUMERIC. См. perllocale и POSIX.
Разделение имён переменных с помощью фигурных скобок
Как и в некоторых оболочках, вы можете заключить имя переменной в фигурные скобки в качестве разделителя, чтобы избежать неоднозначности с последующими алфавитно-цифровыми символами и нижними подчеркиваниями или другим текстом. Вы также должны сделать это при интерполяции переменной в строку, чтобы отделить имя переменной от последующего двойного двоеточия или апострофа, так как иначе они будут обрабатываться как разделитель пакетов:
$who = "Larry";
print PASSWD "${who}::0:0:Superuser:/:/bin/perl\n";
print "We use ${who}speak when ${who}'s here.\n"; Без фигурных скобок Perl искал бы переменную $whospeak, $who::0, и $who's. Две последних были бы переменными $0 и $s в (предположительно) несуществующем пакете who.
Фактически, простой идентификатор внутри таких фигурных скобок принудительно преобразуется в строку, и аналогично внутри индекса хэша. Никакой цитирования не требуется. Наш предыдущий пример, $days{'Feb'}, может быть записан как $days{Feb}, и кавычки будут автоматически добавлены. Но всё более сложное в индексе будет интерпретировано как выражение. Это означает, например, что $version{2.0}++ эквивалентно $version{2}++, а не $version{'2.0'}++.
Существует аналогичная проблема с интерполяцией текста, который выглядит как обозначение доступа к массиву или хэшу. Размещение простой переменной, такой как $who, непосредственно перед текстом, подобным "[1]" или "{foo}", приведет к интерполяции переменной как доступа к элементу @who или значению, хранящемуся в %who:
$who = "Larry Wall";
print "$who[1] is the father of Perl.\n"; попытается получить доступ к индексу 1 массива с именем @who. Опять же, использование фигурных скобок предотвратит это:
$who = "Larry Wall";
print "${who}[1] is the father of Perl.\n"; будет обработано так же, как
$who = "Larry Wall";
print $who . "[1] is the father of Perl.\n"; Это обозначение также применяется к более сложным описаниям переменных, таким как доступ к массиву или хэшу с индексами. Например,
@name = qw(Larry Curly Moe);
print "Also ${name[0]}[1] was a member\n"; Без фигурных скобок вышеприведенный пример был бы распарсен как индекс массива второго уровня в массиве @name, и под use strict, скорее всего, сгенерировало бы фатальную ошибку, поскольку он был бы распарсен так:
print "Also " . $name[0][1] . " was a member\n"; а не как предполагалось:
print "Also " . $name[0] . "[1] was a member\n"; Аналогичный результат может быть получен, используя обратную косую черту на первом символе индекса или обозначения пакета, который не является частью переменной, к которой вы хотите получить доступ. Таким образом, вышеприведенный пример также можно записать:
@name = qw(Larry Curly Moe);
print "Also $name[0]\[1] was a member\n"; Однако для некоторых специальных переменных (переменных с несколькими символами в начале) обозначенный вид с использованием фигурных скобок является единственным способом ссылки на переменную, и единственным способом доступа к индексу переменной через интерполяцию.
Рассмотрим магический массив @{^CAPTURE}, который заполняется движком регулярных выражений содержимым всех буферов захвата в шаблоне (см. perlvar и perlre). Единственный способ доступа к одному из этих элементов внутри строки — через обозначенную форму в фигурных скобках:
"abc"=~/(.)(.)(.)/
and print "Second buffer is ${^CAPTURE[1]}"; эквивалентно
"abc"=~/(.)(.)(.)/
and print "Second buffer is " . ${^CAPTURE}[1]; Сообщая @^CAPTURE — это синтаксическая ошибка, поэтому обязательно следует ссылаться на неё как на @{^CAPTURE}, а для доступа к одному из её элементов в обычном коде необходимо написать ${^CAPTURE}[1] . Однако при интерполяции в строке "${^CAPTURE}[1]" будет эквивалентно ${^CAPTURE} . "[1]", что даже не ссылается на ту же самую переменную! Следовательно, индексы также должны быть помещены внутри фигурных скобок: "${^CAPTURE[1]}".
Обозначенная форма с использованием фигурных скобок может использоваться со всеми различными типами доступа к переменным, включая срезы массивов и хэшей. Например, такой код:
@name = qw(Larry Curly Moe);
local $" = " and ";
print "My favorites were @{name[1,2]}.\n"; выведет
My favorites were Curly and Moe. Специальные числа с плавающей точкой: бесконечность (Inf) и не число (NaN)
Значения с плавающей точкой включают специальные значения Inf и NaN, для бесконечности и не числа. Бесконечность может быть также отрицательной.
Бесконечность — результат определённых математических операций, которые выходят за пределы диапазона чисел с плавающей точкой, таких как 9**9**9. Не число — результат, когда результат неопределён или непредставим. Обратите внимание, что вы не можете получить NaN от некоторых распространённых операций «неопределённости» или «выхода за пределы диапазона», таких как деление на ноль или квадратный корень из отрицательного числа, поскольку Perl генерирует фатальные ошибки для них.
У бесконечности и не числа есть свои специальные правила арифметики. Общее правило состоит в том, что они «заразны»: Inf плюс один равно Inf, а NaN плюс один равно NaN. Интересно, когда вы объединяете бесконечности и не числа: Inf минус Inf и Inf деленное на Inf равны NaN (в то время как Inf плюс Inf равно Inf и Inf умножить на Inf равно Inf). NaN также интересно тем, что оно не равно никакому числу, включая себя: NaN != NaN.
Perl не понимает Inf и NaN как числовые литералы, но вы можете использовать их как строки, и Perl преобразует их по мере необходимости: "Inf" + 1. (Однако вы можете импортировать их из расширения POSIX; use POSIX qw(Inf NaN); и затем использовать их в качестве литералов.)
Обратите внимание, что при вводе (строка в число) Perl принимает Inf и NaN во многих форматах. Регистр игнорируется, и понимаются специфичные для Win32 формы, такие как 1.#INF, но на выходе значения нормализуются до Inf и NaN.
Строки версий
Литерал вида v1.20.300.4000 парсится как строка, составленная из символов с указанными порядковыми номерами. Эта форма, известная как v-строки, предоставляет альтернативный, более читабельный способ построения строк вместо несколько менее читаемой формы интерполяции "\x{1}\x{14}\x{12c}\x{fa0}". Это полезно для представления строк Юникода и для сравнения версий «чисел» с использованием операторов сравнения строк cmp, gt, lt и т. д. Если в литерале есть две или более точки, ведущее v можно опустить.
print v9786; # prints SMILEY, "\x{263a}"
print v102.111.111; # prints "foo"
print 102.111.111; # same Такие литералы принимаются как require, так и use для проверки версии. Обратите внимание, что использование v-строк для IPv4-адресов не является переносимым, если вы не используете также функции inet_aton()/inet_ntoa() пакета Socket.
Обратите внимание, что начиная с Perl 5.8.1, v-строки с одним числом (например, v65) не являются v-строками до оператора => (который обычно используется для разделения ключа хэша и значения хэша); вместо этого они интерпретируются как строковые литералы ('v65'). Они были v-строками с Perl 5.6.0 по Perl 5.8.0, но это вызвало больше путаницы и разрывов, чем пользы. Многочисленные v-строки, такие как v65.66 и 65.66.67 остаются v-строками всегда.
Специальные литералы
Специальные литералы __FILE__, __LINE__ и __PACKAGE__ представляют текущий имя файла, номер строки и имя пакета в данной точке вашей программы. __SUB__ возвращает ссылку на текущую подпрограмму. Их можно использовать только как отдельные токены; они не будут интерполированы в строки. Если нет текущего пакета (из-за пустого package; директивы), __PACKAGE__ имеет значение undef. (Но пустая package; больше не поддерживается, начиная с версии 5.10.) Вне подпрограммы __SUB__ имеет значение undef. __SUB__ доступна только начиная с версии 5.16 и только с use v5.16 или use feature "current_sub" объявлением.
Два управляющих символа ^D и ^Z, и токены __END__ и __DATA__ могут использоваться для обозначения логического конца сценария до фактического конца файла. Любой последующий текст игнорируется интерпретатором, если он не считывается программой, как описано ниже.
Текст после __DATA__ можно прочитать через файловый дескриптор PACKNAME::DATA, где PACKNAME — пакет, который был текущим, когда был встречен токен __DATA__. Файловый дескриптор остается открытым, указывающим на строку после __DATA__. Программа должна close DATA при завершении чтения из него. (Оставление его открытым приводит к утечке файловых дескрипторов, если модуль перезагружается по какой-либо причине, поэтому более безопасной практикой является его закрытие.) Для совместимости со старыми скриптами, написанными до введения __DATA__, __END__ ведет себя как __DATA__ в скрипте верхнего уровня (но не в файлах, загруженных с помощью require или do) и оставляет оставшееся содержимое файла доступным через main::DATA.
while (my $line = <DATA>) { print $line; }
close DATA;
__DATA__
Hello world. Файловый дескриптор DATA по умолчанию имеет те же уровни PerlIO, что и при чтении Perl файла для парсинга исходного кода. Обычно это означает, что файл читается побайтово, как если бы он был закодирован в Latin-1, но есть два основных способа, как это может быть иначе. Во-первых, если токен __END__/__DATA__ находится в области действия псевдонима use utf8, то файловый дескриптор DATA будет в режиме UTF-8. И, во-вторых, если исходный код читается из стандартного ввода Perl, то файловый дескриптор DATA фактически является псевдонимом файлового дескриптора STDIN и может быть в режиме UTF-8 из-за переменной окружения PERL_UNICODE или командных переключателей Perl.
См. SelfLoader для более подробного описания __DATA__ и примера его использования. Обратите внимание, что вы не можете читать из файлового дескриптора DATA в блоке BEGIN: блок BEGIN выполняется как только он виден (во время компиляции), в этот момент соответствующий токен __DATA__ (или __END__) ещё не виден.
Необработанные слова
Слово, которое не имеет другого толкования в грамматике, будет обрабатываться так, как будто это была строка в кавычках. Они известны как «необработанные слова». Как и с файловыми дескрипторами и метками, необработанное слово, состоящее только из строчных букв, рискует конфликтовать с будущими зарезервированными словами, и если вы используете псевдоним use warnings или переключатель -w, Perl предупредит вас о таких словах. Perl ограничивает необработанные слова (как и идентификаторы) примерно 250 символами. Будущие версии Perl, вероятно, уберут эти произвольные ограничения.
Некоторые люди могут захотеть полностью запретить необработанные слова. Если вы скажете
use strict 'subs'; то любое необработанное слово, которое не будет интерпретировано как вызов подпрограммы, вместо этого сгенерирует ошибку во время компиляции. Ограничение действует до конца вложенного блока. Вложенный блок может отменить это, сказав no strict 'subs'.
Интерполяция массивов
Массивы и срезы интерполируются в двойные кавычки, соединяя элементы разделителем, указанным в переменной $" ($LIST_SEPARATOR при «использовании English;»), по умолчанию пробелом. Следующие примеры эквивалентны:
$temp = join($", @ARGV);
system "echo $temp";
system "echo @ARGV"; Внутри поисковых шаблонов (которые также подвергаются замене двойных кавычек) существует неустранимая двусмысленность: должна ли /$foo[bar]/ интерпретироваться как /${foo}[bar]/ (где [bar] — это класс символов для регулярного выражения) или как /${foo[bar]}/ (где [bar] — индекс массива @foo)? Если @foo не существует иначе, то это, очевидно, класс символов. Если @foo существует, Perl делает обоснованное предположение о [bar], и почти всегда угадывает правильно. Если он ошибается, или если вы просто параноик, вы можете принудительно использовать правильную интерпретацию с фигурными скобками, как указано выше.
Если вы ищете информацию о том, как использовать здесь документы, которая раньше была здесь, то она перемещена в "Операторы кавычек и похожих на кавычки" в perlop.
Конструкторы списков значений
Значения списков обозначаются разделением отдельных значений запятыми (и заключением списка в круглые скобки, когда этого требует приоритет):
(LIST) В контексте, не требующем значения списка, значение того, что кажется литералом списка, просто значение последнего элемента, как и в операторе запятой C. Например,
@foo = ('cc', '-E', $bar); присваивает всё значение списка массиву @foo, но
$foo = ('cc', '-E', $bar); присваивает значение переменной $bar скалярной переменной $foo. Обратите внимание, что значение фактического массива в скалярном контексте — это длина массива; следующее присваивает значение 3 переменной $foo:
@foo = ('cc', '-E', $bar);
$foo = @foo; # $foo gets 3 Можно использовать необязательную запятую перед закрывающей скобкой литерала списка, чтобы можно было сказать:
@foo = (
1,
2,
3,
); Чтобы использовать здесь-документ для присвоения массива, по одной строке на элемент, можно использовать подход, подобный этому:
@sauces = <<End_Lines =~ m/(\S.*\S)/g;
normal tomato
spicy tomato
green chile
pesto
white wine
End_Lines СПИСКИ автоматически интерполируют подсписки. То есть, когда оценивается СПИСОК, каждый элемент списка оценивается в контексте списка, и полученное значение списка интерполируется в СПИСОК так, как если бы каждый отдельный элемент был членом СПИСКА. Таким образом, массивы и хэши теряют свою идентичность в СПИСКЕ — список
(@foo,@bar,&SomeSub,%glarch) содержит все элементы @foo, за которыми следуют все элементы @bar, за которыми следуют все элементы, возвращаемые подпрограммой с именем SomeSub, вызванной в контексте списка, за которыми следуют пары ключ/значение %glarch. Чтобы создать ссылку на список, который НЕ интерполируется, см. perlref.
Пустой список представляется как (). Интерполяция его в список не оказывает никакого влияния. Таким образом, ((),(),()) эквивалентно (). Аналогично, интерполяция массива без элементов такая же, как если бы этот массив не был интерполирован в этом месте.
Эта интерполяция сочетается с фактом, что открывающие и закрывающие скобки необязательны (за исключением случаев, когда это необходимо для приоритета), и списки могут заканчиваться необязательной запятой, что означает, что несколько запятых в списках являются допустимым синтаксисом. Список 1,,3 является конкатенацией двух списков, 1, и 3, первый из которых заканчивается этой необязательной запятой. 1,,3 это (1,),(3) это 1,3 (И аналогично для 1,,,3 это (1,),(,),3 это 1,3 и так далее.) Не рекомендуем использовать такое усложнение.
Значение списка также можно индексировать, как обычный массив. Для избежания неоднозначности необходимо поместить список в скобки. Например:
# Stat returns list value.
$time = (stat($file))[8];
# SYNTAX ERROR HERE.
$time = stat($file)[8]; # OOPS, FORGOT PARENTHESES
# Find a hex digit.
$hexdigit = ('a','b','c','d','e','f')[$digit-10];
# A "reverse comma operator".
return (pop(@foo),pop(@foo))[0]; Список можно присвоить только в том случае, если каждый элемент списка сам по себе подлежит присвоению:
($x, $y, $z) = (1, 2, 3);
($map{'red'}, $map{'blue'}, $map{'green'}) = (0x00f, 0x0f0, 0xf00); Исключением из этого является возможность присвоения к undef в списке. Это полезно для отбрасывания некоторых возвращаемых значений функции:
($dev, $ino, undef, undef, $uid, $gid) = stat($file); Начиная с Perl 5.22, можно также использовать (undef)x2 вместо undef, undef. (Можно также выполнить ($x) x 2, что менее полезно, так как это присваивание к одной и той же переменной дважды, перезаписывая первое присвоенное значение.)
Когда вы присваиваете список скаляров массиву, все предыдущие значения в этом массиве стираются, и количество элементов в массиве теперь будет равно количеству элементов в списке справа — списке, из которого производилось присвоение. Массив автоматически изменяет свой размер, чтобы точно вместить каждый элемент из списка справа.
use warnings;
my (@xyz, $x, $y, $z);
@xyz = (1, 2, 3);
print "@xyz\n"; # 1 2 3
@xyz = ('al', 'be', 'ga', 'de');
print "@xyz\n"; # al be ga de
@xyz = (101, 102);
print "@xyz\n"; # 101 102 Однако, когда вы присваиваете список скаляров другому списку скаляров, результаты отличаются в зависимости от того, содержит ли список слева — список, которому присваивается значение — такое же, большее или меньшее количество элементов, чем список справа.
($x, $y, $z) = (1, 2, 3);
print "$x $y $z\n"; # 1 2 3
($x, $y, $z) = ('al', 'be', 'ga', 'de');
print "$x $y $z\n"; # al be ga
($x, $y, $z) = (101, 102);
print "$x $y $z\n"; # 101 102
# Use of uninitialized value $z in concatenation (.)
# or string at [program] line [line number]. Если количество скаляров в списке слева меньше, чем в списке справа, то «лишние» скаляры в списке справа просто не будут присвоены.
Если количество скаляров в списке слева больше, чем в списке справа, «пропущенные» скаляры станут неопределёнными.
($x, $y, $z) = (101, 102);
for my $el ($x, $y, $z) {
(defined $el) ? print "$el " : print "<undef>";
}
print "\n";
# 101 102 <undef> Присвоение списка в скалярном контексте возвращает количество элементов, произведённых выражением справа от присвоения:
$x = (($foo,$bar) = (3,2,1)); # set $x to 3, not 2
$x = (($foo,$bar) = f()); # set $x to f()'s return count Это удобно, когда вы хотите выполнить присвоение списка в булевом контексте, потому что большинство функций списка возвращают пустой список после завершения, что, при присвоении, даёт 0, который интерпретируется как FALSE.
Это также источник полезного выражения для выполнения функции или операции в контексте списка, а затем подсчёта числа возвращаемых значений, путём присвоения пустому списку, а затем использования этого присвоения в скалярном контексте. Например, этот код:
$count = () = $string =~ /\d+/g; разместит в $count количество найденных в $string групп цифр. Это происходит, потому что поиск шаблона выполняется в контексте списка (поскольку он присваивается пустому списку) и, следовательно, возвращает список всех соответствующих частей строки. Присвоение списка в скалярном контексте преобразует это в количество элементов (здесь — количество совпадений шаблона) и присваивает это $count. Обратите внимание, что просто использование
$count = $string =~ /\d+/g; не сработает, так как поиск шаблона в скалярном контексте будет возвращать только true или false, а не счёт совпадений.
Последним элементом присвоения списка может быть массив или хэш:
($x, $y, @rest) = split;
my($x, $y, %rest) = @_; Вы можете разместить массив или хэш где угодно в списке, но первый из них в списке поглотит все значения, а всё, что после него, станет неопределённым. Это может быть полезно в my() или local().
Хэш можно инициализировать, используя литеральный список, содержащий пары элементов, которые будут интерпретироваться как ключ и значение:
# same as map assignment above
%map = ('red',0x00f,'blue',0x0f0,'green',0xf00); Хотя литеральные списки и именованные массивы часто взаимозаменяемы, это не так в случае хэшей. Просто потому, что вы можете индексировать значение списка, как обычный массив, не означает, что вы можете индексировать значение списка как хэш. Аналогично, хэши, включенные в качестве частей других списков (включая списки параметров и списки возвращаемых значений функций), всегда сглаживаются в пары ключ/значение. Вот почему иногда полезно использовать ссылки.
Часто более читабельно использовать оператор => между парами ключ/значение. Оператор => в основном просто более визуально выразительный синоним запятой, но он также обеспечивает интерпретацию левого операнда как строки, если это простое слово, которое будет допустимым простым идентификатором. => не приводит к цитированию составных идентификаторов, содержащих двойные двоеточия. Это делает его удобным для инициализации хэшей:
%map = (
red => 0x00f,
blue => 0x0f0,
green => 0xf00,
); или для инициализации ссылок на хэши, которые будут использоваться как записи:
$rec = {
witch => 'Mable the Merciless',
cat => 'Fluffy the Ferocious',
date => '10/31/1776',
}; или для использования вызова по имени параметра для сложных функций:
$field = $query->radio_group(
name => 'group_name',
values => ['eenie','meenie','minie'],
default => 'meenie',
linebreak => 'true',
labels => \%labels
); Обратите внимание, что просто потому, что хэш инициализирован в таком порядке, не значит, что он будет выводиться в том же порядке. См. "sort" в perlfunc для примеров, как организовать вывод в нужной последовательности.
Если ключ появляется более одного раза в списке инициализаторов хэша, используется последнее вхождение:
%circle = (
center => [5, 10],
center => [27, 9],
radius => 100,
color => [0xDF, 0xFF, 0x00],
radius => 54,
);
# same as
%circle = (
center => [27, 9],
color => [0xDF, 0xFF, 0x00],
radius => 54,
); Это можно использовать для предоставления настраиваемых по умолчанию значений конфигурации:
# values in %args take priority over %config_defaults
%config = (%config_defaults, %args); Индексы
Массив можно получить по одному скаляру за раз, указав знак доллара ($), затем имя массива (без ведущего @), а затем индекс в квадратных скобках. Например:
@myarray = (5, 50, 500, 5000);
print "The Third Element is", $myarray[2], "\n"; Индексы массива начинаются с 0. Отрицательный индекс извлекает своё значение с конца. В нашем примере, $myarray[-1] было бы 5000, а $myarray[-2] — 500.
Индексирование хэшей аналогично, только вместо квадратных скобок используются фигурные скобки. Например:
%scientists =
(
"Newton" => "Isaac",
"Einstein" => "Albert",
"Darwin" => "Charles",
"Feynman" => "Richard",
);
print "Darwin's First Name is ", $scientists{"Darwin"}, "\n"; Вы также можете индексировать список, чтобы получить один элемент из него:
$dir = (getpwnam("daemon"))[7]; Эмуляция многомерных массивов
Многомерные массивы можно эмулировать, индексируя хэш списком. Элементы списка соединяются с разделителем индекса (см. "$;" в perlvar).
$foo{$x,$y,$z} эквивалентно
$foo{join($;, $x, $y, $z)} По умолчанию разделитель индекса — «\034», такой же, как SUBSEP в awk.
Слайсы
Слайс обращается к нескольким элементам списка, массива или хэша одновременно, используя список индексов. Это удобнее, чем писать отдельные элементы как список отдельных скалярных значений.
($him, $her) = @folks[0,-1]; # array slice
@them = @folks[0 .. 3]; # array slice
($who, $home) = @ENV{"USER", "HOME"}; # hash slice
($uid, $dir) = (getpwnam("daemon"))[2,7]; # list slice Поскольку вы можете присваивать значения списку переменных, вы также можете присваивать значения слайсу массива или хэша.
@days[3..5] = qw/Wed Thu Fri/;
@colors{'red','blue','green'}
= (0xff0000, 0x0000ff, 0x00ff00);
@folks[0, -1] = @folks[-1, 0]; Предыдущие присвоения точно эквивалентны
($days[3], $days[4], $days[5]) = qw/Wed Thu Fri/;
($colors{'red'}, $colors{'blue'}, $colors{'green'})
= (0xff0000, 0x0000ff, 0x00ff00);
($folks[0], $folks[-1]) = ($folks[-1], $folks[0]); Поскольку изменение слайса изменяет исходный массив или хэш, конструктор foreach изменит некоторые — или даже все — значения массива или хэша.
foreach (@array[ 4 .. 10 ]) { s/peter/paul/ }
foreach (@hash{qw[key1 key2]}) {
s/^\s+//; # trim leading whitespace
s/\s+$//; # trim trailing whitespace
s/\b(\w)(\w*)\b/\u$1\L$2/g; # "titlecase" words
} Как особое исключение, когда вы создаёте слайс списка (но не массива или хэша), если список вычисляется как пустой, то извлечение слайса из этого пустого списка всегда даст, в свою очередь, пустой список. Таким образом:
@a = ()[0,1]; # @a has no elements
@b = (@a)[0,1]; # @b has no elements
@c = (sub{}->())[0,1]; # @c has no elements
@d = ('a','b')[0,1]; # @d has two elements
@e = (@d)[0,1,8,9]; # @e has four elements
@f = (@d)[8,9]; # @f has two elements Это упрощает написание циклов, которые завершаются, когда возвращается пустой список:
while ( ($home, $user) = (getpwent)[7,0] ) {
printf "%-8s %s\n", $user, $home;
} Как отмечалось ранее в этом документе, скалярное представление присвоения списка — это количество элементов в правой части присвоения. Пустой список не содержит элементов, поэтому, когда файл паролей исчерпан, результатом является 0, а не 2.
Слайсы в скалярном контексте возвращают последний элемент слайса.
@a = qw/first second third/;
%h = (first => 'A', second => 'B');
$t = @a[0, 1]; # $t is now 'second'
$u = @h{'first', 'second'}; # $u is now 'B' Если вы не понимаете, почему в слайсе хэша используется «@» вместо «%», подумайте об этом так. Тип скобок (квадратные или фигурные) определяет, массив или хэш рассматриваются. С другой стороны, ведущий символ («$» или «@») перед массивом или хэшем указывает, получаем ли мы одно значение (скаляр) или множество (список).
Слайсы хэша ключ/значение
Начиная с Perl 5.20, операция хэш-слайса с символом % является вариантом операции слайса, возвращающей список пар ключ/значение, а не только значений:
%h = (blonk => 2, foo => 3, squink => 5, bar => 8);
%subset = %h{'foo', 'bar'}; # key/value hash slice
# %subset is now (foo => 3, bar => 8)
%removed = delete %h{'foo', 'bar'};
# %removed is now (foo => 3, bar => 8)
# %h is now (blonk => 2, squink => 5) Однако результат такого слайса не может быть локализован или присвоен. В остальном они полностью совместимы со слайсами хэшей, использующими символ @.
Слайсы массива индекс/значение
Аналогично слайсам хэша ключ/значение (также представленным в Perl 5.20), синтаксис массива-слайса % возвращает список пар индекс/значение:
@a = "a".."z";
@list = %a[3,4,6];
# @list is now (3, "d", 4, "e", 6, "g")
@removed = delete %a[3,4,6]
# @removed is now (3, "d", 4, "e", 6, "g")
# @list[3,4,6] are now undef Обратите внимание, что вызов delete для значений массива категорически не рекомендуется.
Типоглобы и файловые дескрипторы
Perl использует внутренний тип, называемый типоглобом, для хранения всей записи таблицы символов. Префикс типа типоглоба — это *, поскольку он представляет все типы. Раньше это был предпочтительный способ передачи массивов и хэшей по ссылке в функцию, но теперь, когда у нас есть реальные ссылки, это редко необходимо.
Основное использование типоглобов в современном Perl — создание псевдонимов таблицы символов. Это присваивание:
*this = *that; делает $this псевдонимом для $that, @this псевдонимом для @that, %this псевдонимом для %that, &this псевдонимом для &that и т. д. Гораздо безопаснее использовать ссылку. Это:
local *Here::blue = \$There::green; временно делает $Here::blue псевдонимом для $There::green, но не делает @Here::blue псевдонимом для @There::green или %Here::blue псевдонимом для %There::green и т. д. См. "Таблицы символов" в perlmod для получения дополнительных примеров этого. Как бы странно это ни выглядело, это основа всей системы импорта/экспорта модулей.
Другое использование типоглобов — передача файловых дескрипторов в функцию или создание новых файловых дескрипторов. Если вам нужно использовать типоглоб для сохранения файлового дескриптора, сделайте это так:
$fh = *STDOUT; или, возможно, как реальная ссылка, например:
$fh = \*STDOUT; См. perlsub для примеров использования этих значений в качестве косвенных файловых дескрипторов в функциях.
Типглобы также являются способом создания локального файлового дескриптора с использованием оператора local(). Они существуют до выхода из своего блока, но могут быть переданы обратно. Например:
sub newopen {
my $path = shift;
local *FH; # not my!
open (FH, $path) or return undef;
return *FH;
}
$fh = newopen('/etc/passwd'); Теперь, когда у нас есть *foo{THING} обозначение, типглобы не так часто используются для манипуляций с файловыми дескрипторами, хотя они всё ещё необходимы для передачи новых файловых и каталожных дескрипторов в функции или из функций. Это потому, что *HANDLE{IO} работает только в том случае, если HANDLE уже использовался в качестве дескриптора. Другими словами, *FH необходимо для создания новых записей в таблице символов; *foo{THING} не может этого сделать. В случае сомнений, используйте *FH.
Все функции, способные создавать файловые дескрипторы (open(), opendir(), pipe(), socketpair(), sysopen(), socket() и accept()), автоматически создают анонимный файловый дескриптор, если переданный им дескриптор является неинициализированной скалярной переменной. Это позволяет использовать конструкции, такие как open(my $fh, ...) и open(local $fh,...), для создания файловых дескрипторов, которые будут удобно закрыты автоматически при выходе из области видимости, при условии отсутствия других ссылок на них. Это в значительной степени устраняет необходимость в типглобах при открытии файловых дескрипторов, которые необходимо передавать, как показано в следующем примере:
sub myopen {
open my $fh, "@_"
or die "Can't open '@_': $!";
return $fh;
}
{
my $f = myopen("</etc/motd");
print <$f>;
# $f implicitly closed here
} Обратите внимание, что если вместо этого используется инициализированная скалярная переменная, результат отличается: my $fh='zzz'; open($fh, ...) эквивалентно open( *{'zzz'}, ...). use strict 'refs' запрещает подобную практику.
Другой способ создания анонимных файловых дескрипторов — с помощью модуля Symbol или модуля IO::Handle и его аналогов. Эти модули обладают преимуществом, что не скрывают различные типы с одинаковым именем во время использования local(). См. конец "open" в perlfunc для примера.
ДРУГОЕ
См. perlvar для описания встроенных переменных Perl и обсуждения допустимых имён переменных. См. perlref, perlsub и "Таблицы символов" в perlmod для более подробного обсуждения типглобов и *foo{THING} синтаксиса.
© 1993–2023 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.38.0/perldata