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 ...) Кроме того, подпрограммы обозначаются начальным символом '&', хотя это необязательно, если это недвусмысленно, так же как слово «do» часто избыточно в английском языке. Элементы таблицы символов могут быть обозначены начальным символом '*', но вам это пока не нужно (если вообще когда-нибудь :-).
Каждый тип переменных имеет своё пространство имён, как и несколько идентификаторов, не являющихся переменными. Это означает, что вы можете без опасения использовать одно и то же имя для скалярной переменной, массива или хэша — или, что важно, для дескриптора файла, дескриптора каталога, имени подпрограммы, имени формата или метки. Это означает, что $foo и @foo — это две разные переменные. Это также означает, что $foo[1] является частью @foo, а не частью $foo. Это может показаться немного странным, но это нормально, потому что это странно.
Поскольку ссылки на переменные всегда начинаются с '$', '@' или '%', «зарезервированные» слова фактически не зарезервированы в отношении имён переменных. Они зарезервированы в отношении меток и дескрипторов файлов, которые не имеют начального специального символа. У вас не может быть дескриптор файла с именем «log», например. Подсказка: вы могли бы сказать open(LOG,'logfile') вместо open(log,'logfile'). Использование дескрипторов файлов с заглавными буквами также улучшает читабельность и защищает вас от конфликтов с будущими зарезервированными словами. Регистр важен — "FOO", "Foo" и "foo" — это разные имена. Имена, начинающиеся с буквы или символа подчёркивания, также могут содержать цифры и символы подчёркивания.
Можно заменить такое буквенно-цифровое имя выражением, которое возвращает ссылку на соответствующий тип. Для описания этого см. perlref.
Имена, начинающиеся с цифры, могут содержать только другие цифры. Имена, не начинающиеся с буквы, символа подчёркивания, цифры или символа возведения в степень, ограничены одним символом, например, $% или $$. (Большинство этих имён из одного символа имеют предопределённое значение для Perl. Например, $$ — это текущий идентификатор процесса. И все такие имена зарезервированы для возможного использования Perl.)
Разбор идентификаторов
До Perl 5.18 правила того, что такое допустимый идентификатор, были немного расплывчатыми. Однако, как общее правило, всё, что определено здесь, должно работать в предыдущих версиях Perl, а обратное — крайние случаи, которые работают в предыдущих версиях, но не определены здесь — вероятно, не будут работать в более новых версиях. Важное замечание: следующее относится только к идентификаторам bareword, найденным в исходном коде Perl, а не к идентификаторам, введённым через символические ссылки, которые имеют гораздо меньше ограничений. Если работает pragma use utf8;, применяются следующие правила:
/ (?[ ( \p{Word} & \p{XID_Start} ) + [_] ])
(?[ ( \p{Word} & \p{XID_Continue} ) ]) * /x То есть, символ «начала» следует за любым количеством символов «продолжения». Perl требует, чтобы каждый символ в идентификаторе также соответствовал \w (это предотвращает некоторые проблемные случаи); и Perl дополнительно допускает имена идентификаторов, начинающиеся с символа подчёркивания.
Если не под управлением use utf8, исходный код обрабатывается как ASCII + 128 дополнительных общих символов, и идентификаторы должны соответствовать
/ (?aa) (?!\d) \w+ /x То есть, любой буквенный символ в ASCII-диапазоне, при условии, что первый символ не является цифрой.
В Perl есть два разделителя пакетов: двойное двоеточие (::) и одинарная кавычка ('). Обычные идентификаторы могут начинаться или заканчиваться двойным двоеточием и могут содержать несколько частей, разделённых двойными двоеточиями. Одинарные кавычки имеют аналогичные правила, но с исключением, что они не допустимы в конце идентификатора: то есть, $'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, ПРОБЕЛ NO-BREAK и МЯГКАЯ ТИРЕ) запрещено начиная с версии 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 или командную строку 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. Однако это не длина массива; это индекс последнего элемента, который имеет другое значение, так как обычно есть 0-й элемент. Присваивание $#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 для создания символов, таких как перевод строки, табуляция и т. д., а также некоторых более экзотических форм. См. "Quote and Quote-like Operators" в 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'}++.
Специальные числа с плавающей точкой: бесконечность (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}". Это полезно для представления строк Unicode и для сравнения версий "номеров" с помощью операторов сравнения строк, 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__ имеет неопределённое значение. (Но пустая package; больше не поддерживается начиная с версии 5.10.) Вне подпрограммы __SUB__ имеет неопределённое значение. __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 если указано "use English;"), по умолчанию пробел. Следующие варианты эквивалентны:
$temp = join($", @ARGV);
system "echo $temp";
system "echo @ARGV"; В шаблонах поиска (которые также подвергаются подстановке с двойными кавычками) существует неудачная неоднозначность: Должен ли /$foo[bar]/ интерпретироваться как /${foo}[bar]/ (где [bar] – это класс символов для регулярного выражения) или как /${foo[bar]}/ (где [bar] – это индекс для массива @foo)? Если @foo не существует, то это, очевидно, класс символов. Если @foo существует, Perl делает хорошее предположение о [bar], и почти всегда угадывает правильно. Если он ошибается, или если вы просто параноик, вы можете принудительно установить правильную интерпретацию с фигурными скобками, как описано выше.
Если вы ищете информацию о том, как использовать здесь-документы, которые раньше были здесь, то они перемещены в "Quote and Quote-like Operators" в 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/(\w+)/\u\L$1/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 и т. д. См. "Symbol Tables" в 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,...), для создания дескрипторов файлов, которые удобно будут закрыты автоматически по завершении области видимости, при условии отсутствия других ссылок на них. Это в значительной степени устраняет необходимость использования typeglobs при открытии дескрипторов файлов, которые необходимо передавать, как показано в следующем примере:
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 для получения дополнительной информации о typeglobs и синтаксисе *foo{THING}.
© 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.34.0/perldata