Spec-Zone.ru › Perl 5.28

perldata

СОДЕРЖАНИЕ

  • ИМЯ
  • ОПИСАНИЕ
    • Имена переменных
    • Разбор идентификаторов
    • Контекст
    • Скалярные значения
    • Конструкторы скалярных значений
      • Специальные числа с плавающей точкой: бесконечность (Inf) и не число (NaN)
      • Строки версий
      • Специальные литералы
      • Голые слова
      • Вставка массивов
    • Конструкторы списков значений
    • Индексы
    • Эмуляция многомерных массивов
    • Срезы
      • Срезы хешей ключ/значение
      • Срезы массивов индекс/значение
    • Глобальные переменные типов и файловые дескрипторы
  • СМОТРИТЕ ТАКЖЕ

ИМЯ

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, в то время как обратное — случаи, работающие в предыдущих версиях, но не определённые здесь, — вероятно, не будут работать в новых версиях. Важное замечание: нижеследующее относится только к идентификаторам голых слов, как они встречаются в исходном коде Perl, а не к идентификаторам, введённым через символические ссылки, которые имеют намного меньше ограничений. Если работа выполняется под влиянием 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):

  1. Знак, за которым следуют только цифры, соответствующие \p{POSIX_Digit}, например $0, $1, или $10000.

  2. Знак, за которым следует один символ, соответствующий свойству \p{POSIX_Punct}, например $! или %+, за исключением символа "{", который не работает.

  3. Знак, за которым следует символ ^ и любой из символов [][A-Z^_?\], например $^V или $^].

  4. Аналогично предыдущему, знак, за которым следует текст голых слов в фигурных скобках, где первый символ — символ «^». Следующий символ — любой из символов [][A-Z^_?\], за которым следуют буквенные символы ASCII. Пример: ${^GLOBAL_PHASE}.

  5. Знак, за которым следует любой одиночный символ в диапазоне [\xA1-\xAC\xAE-\xFF] при отсутствии "use utf8". (При "use utf8", применяются обычные правила идентификаторов, описанные ранее в этом разделе.) Использование неграфических символов (управляющих символов C1, символа ПРОБЕЛ НЕРУШИМЫЙ и символа МЯГКАЯ ТИРЕ) запрещено с версии 5.26.0. Использование других символов не рекомендуется, так как они все зарезервированы для специального значения в Perl, и в настоящее время ни один из них не имеет специального значения, хотя это может измениться без предварительного уведомления.

    Обратите внимание, что это подразумевает, что существуют идентификаторы, допустимые только в "use utf8", и наоборот, например, идентификатор $état допустим в "use utf8", но в противном случае считается одинарной символьной переменной $é за которой следует голое слово "tat", комбинация которых является синтаксической ошибкой.

  6. Это комбинация предыдущих двух форм. Она допустима только при отсутствии "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. Однако это не длина массива; это индекс последнего элемента, который отличается, так как обычно есть 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)
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'}++.

Специальные значения с плавающей точкой: бесконечность (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.

Файловый дескриптор 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];

Список может быть присвоен только в том случае, если каждый элемент списка сам по себе является допустимым для присвоения:

($a, $b, $c) = (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, а не счёт совпадений.

Последний элемент присвоения списка может быть массивом или хешем:

($a, $b, @rest) = split;
my($a, $b, %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{$a,$b,$c}

эквивалентно

$foo{join($;, $a, $b, $c)}

По умолчанию разделителем индексов является "\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 и т. д. См. "Таблицы символов" в 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,...), для создания дескрипторов файлов, которые будут удобно закрываться автоматически при завершении области видимости, при условии отсутствия других ссылок на них. Это в значительной степени устраняет необходимость в typeglob при открытии дескрипторов файлов, которые необходимо передавать, как в следующем примере:

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 для примера.

SEE ALSO

См. perlvar для описания встроенных переменных Perl и обсуждения допустимых имен переменных. См. perlref, perlsub и "Таблицы символов" в perlmod для более подробного обсуждения typeglob и *foo{THING} синтаксиса.

© 1993–2020 Larry Wall and others
Licensed under the GNU General Public License version 1 or later, or the Artistic License.
The Perl logo is a trademark of the Perl Foundation.
https://perldoc.perl.org/5.28.3/perldata

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API