Глава 6.2. Основные понятия6.2.1. Типы данных и переменныеPERL имеет всего три встроенных типа данных: скаляры, массивы и ассоциативные массивы (hashes). Скаляры — это числа, строки и ссылки. Массивы — это упорядоченные списки значений, которые доступны по номеру в списке и нумеруются с нуля. Ассоциативные массивы — это неупорядоченные списки значений, которые индексируются строковыми ключами. Идентификаторы используются в PERLе в качестве имен переменных, подпрограмм, меток и т. п. Они могут начинаться с латинской буквы или символа "_" (подчеркивание) и должны состоять из латинских букв, цифр и подчеркиваний. Перед именем переменной всегда ставится специальный символ, который указывает на ее тип:
Приведем примеры образования имен переменных.
Каждый тип переменных имеет собственное пространство имен, поэтому мы можем использовать один и тот же идентификатор для скаляра, массива, ассоциативного массива и подпрограммы. Например, $name и @name — это разные переменные. Два идентификатора считаютс одинаковыми, когда они полностью совпадают; это означает, что name, Name и NAME являются различными идентификаторами. Особую группу переменных образуют т. н. специальные переменные, в которых хранится разнообразная служебная информация. Специальные переменные описываются в тексте по мере надобности в них; их полный перечень приведен в Приложении 22. 6.2.2. Зарезервированные словаСпецификация PERLа по непонятным автору причинам не содержит списка зарезервированных слов, поэтому при написании программ следует исходить из того, что имена всех описанных далее операторов и функций считаются зарезервированными. При этом нужно учитывать следующее. Поскольку имена переменных всегда начинаются со специального символа, зарезервированные имена в PERLе для переменных таковыми не являются. Они зарезервированы только по отношению к названиям меток и файлов, которые со специального символа не начинаются. Простейший способ избежать конфликтов — писать такие названия прописными буквами. 6.2.3. КонстантыКонстанты используются для задания постоянных значений. Ниже описаны правила формирования констант в зависимости от типа их значений. 6.2.3.1. Числовые константыЧисловые константы могут быть как целыми, так и плавающими. PERL не проводит между ними различия и, в действительности, хранит все числа как плавающие. Целые числа могут быть положительными, отрицательными и нулем. По системе счисления они могут быть десятичными, двоичными, восьмеричными и шестнадцатеричными:
Плавающие числа отличаются наличием или десятичной точки, или буквы e в любом регистре, задающей степень десяти в научной нотации, или того и другого. Примеры плавающих чисел:
6.2.3.2. Строковые константыPERL содержит два формата строковых констант. Первый формат имеет вид строки, заключенной в апострофы, например, 'текст'. Такие строки воспринимаются интерпретатором буквально, без анализа их содержимого. Вместо апострофов можно использовать формат q/текст/, причем вместо дробной черты допустим любой символ-разделитель или парные разделители: (), [], {}, <>. Примеры: print 'текст'; print q/текст/; print q#текст#; print q[текст]; Второй формат имеет вид строки, заключенной в кавычки, например, "текст". Такие строки анализируются интерпретатором, который заменяет в них имена переменных и escape-последовательности на соответствующие значения. Этот процесс называется интерполяцией. Вместо кавычек можно использовать формат qq/текст/, причем вместо дробной черты допустим любой символ-разделитель или парные разделители. Примеры: print "текст\n"; print qq/текст\n/; print qq*текст\n*; print qq{текст\n}; Здесь \n задает символ перевода строки. Такие обозначения называются escape-последовательностями и имеют вид \xXX, где XX — шестнадцатеричный код символа, или \0XXX, где XXX — восьмеричный код символа Unicode. Для задания кодов Unicode, больших 256, используется формат \x{XXXX}. Кроме того, несколько символов могут обозначаться специальными escape-последовательностями:
Следующие escape-последовательности управляют преобразованием символов строки:
Для того, чтобы преобразование символов правильно работало с русскими буквами, используйте директиву set locale, например: use locale; print "\Uабвгд\E\n"; Различие между двумя форматами строковых констант демонстрируется следующим примером: $price = '100 руб.'; print "Цена: $price\n"; print 'Цена: $price\n'; Эта программа выведет на экран строки:
Цена: 100 руб.
Цена: $price\n Еще один способ кодирования строк Unicode имеет вид: vXXX.YYY.ZZZ, где XXX, YYY и ZZZ — десятичные коды символов. Если такая конструкция содержит более одной точки, то символ v в начале можно опустить. Примеры: print v169; # выводит символ © print v102.111.111; # выводит строку "foo" print 102.111.111; # то же самое Для выполнения внешних программ или команд операционной системы используются строковые константы вида `команда`.
Вместо символа "`" можно использовать формат qx/команда/, причем вместо дробной черты допустим любой символ-разделитель
или парные разделители. Такая строковая константа возвращает в качестве результата все, что указанная команда выводит на стандартное
устройство вывода системы (stdout). Например, оператор 6.2.3.3. Специальные константыPERL поддерживает пять специальных констант:
Первые три константы обычно используются в целях диагностики, например: print "Ошибка в ".__FILE__.", строка ".__LINE__."\n"; Обратите внимание, что здесь использован оператор конкатенации строк ".", поскольку специальные константы внутри строки не распознаются интерпретатором. Константы __END__ и __DATA__ обозначают логический конец программы: все, что следует за ними в файле программы, будет проигнорировано. Различие между ними состоит в том, что текст после __DATA__ доступен для чтения из файла с именем packname::DATA, где packname — имя текущего пакета (см. п. 6.7.1). 6.2.4. Преобразования скалярных типовКак указывалось выше, числа и строки не являются в PERLе отдельными типами, а относятся к единому скалярному типу. Это, в частности, означает, что значения скалярных переменных по мере необходимости автоматически преобразуются в строку или число. Рассмотрим пример: $x = 2; $y = 4; $z = ($x.$y) / 2; print $z; Здесь оператор присваивания выполняет три неявных преобразования типа. Поскольку операция "." означает в PERLе конкатенацию строк, переменные $x и $y будут преобразованы в строки "2" и "4", которые дадут строку "24". Далее в операторе стоит деление на 2, поэтому полученная строка будет преобразована в число и поделена пополам. В результате данный пример выведет на экран значение 12. Автоматические преобразования обычно облегчают написание программ, но требуют от программиста внимания. Рассмотрим для примера сравнение строк. В зависимости от контекста PERL может сравнить их как строки или как числа, что приводит к разным результатам. Так, строки "1" и "01" различны, но при преобразовании в число становятся равными. По этой причине PERL содержит два набора операций сравнения: для чисел и для строк. PERL не поддерживает логических значений, но содержит логические операторы и операции. В контексте этих операторов и операций действует следующее соглашение: неопределенное значение undef считается ложным; число считается ложным, если оно равно нулю; строка считается ложной, если она пуста или равна "0". Все остальные скалярные значения считаются истинными. Скалярные переменные могут содержать, помимо чисел и строк, ссылки на другие переменные и объекты. Ссылки отличаются тем, что они являются строготипизированными указателями со встроенным счетчиком ссылок и деструктором объекта, вызываемым по обнулению этого счетчика. Важно помнить, что ссылочные переменные не подвержены автоматическому преобразованию типов. 6.2.5. СпискиОдним из важнейших механизмов PERLа являются списки. Список — это набор выражений, разделенных запятыми и обычно заключенный в круглые скобки. Значением списка является сам список; если контекст не требует списочного значения, то возвращается последний элемент списка (аналогично операции запятая в других языках программирования). Например, оператор @people = ('Анна', 'Борис', 'Виктор'); присвоит переменной @people массив из трех элементов, тогда как оператор $people = ('Анна', 'Борис', 'Виктор'); присвоит переменной $people строку 'Виктор'. PERL допускает использование запятой после последнего элемента списка, например: @people = ( 'Анна', 'Борис', 'Виктор', ); Если элементы списка сами являются списками, то они разворачиваются в единый список. Например, два следующих оператора эквивалентны: @newpeople = (@people, 'Георгий'); @newpeople = ('Анна', 'Борис', 'Виктор', 'Георгий'); Пустой список задается выражением (). Если все элементы списка являются строками, не содержащими пробелов (т. е. словами), то можно использовать конструкцию qw/слово слово.../, где вместо дробной черты допустим любой символ-разделитель или парные разделители: (), [], {}, <>. Примеры: @people = ('Анна', 'Борис', 'Виктор'); @people = qw/Анна Борис Виктор/; @people = qw[Анна Борис Виктор]; Списки могут использоваться не только в правой, но и в левой части оператора присваивания, если все элементы такого списка являются переменными: ($x, $y, $z) = (1, 2, 3); Для того, чтобы пропустить какие-либо значения присваиваемого списка, в соответствующих местах левого списка ставится undef, например оператор ($x, undef, $z) = (1, 2, 3); присвоит переменной $x значение 1 и переменной $z значение 3. Оператор присваивания списков возвращает длину присваиваемого списка. В следующем примере $a = (($x, $y) = (1, 2, 3)); переменная $a получит значение 3. Последним элементом списка в левой части оператор присваивания может быть массив или ассоциативный массив: ($girl, @guys) = ('Анна', 'Борис', 'Виктор', 'Георгий'); Если поместить массив или ассоциативный массив в любое другое место левого списка, то он поглотит все оставшиеся элементы присваиваемого списка, и следующие за ним элементы станут неопределенными. PERL поддерживает сокращенную форму списков, состоящих из последовательных значений, вида (значение..значение). Например, список (1..4) эквивалентен списку (1, 2, 3, 4), а список ('abc'..'abe') — списку ('abc', 'abd', 'abe'). 6.2.6. МассивыМассивы — это упорядоченные наборы значений, которые доступны по своему порядковому номеру. Элементы массива нумеруются с нуля, отрицательный номер элемента означает, что он отсчитывается от конца массива (элемент с номером -1 соответствует последнему элементу массива). Для доступа к элементу массива @array с номером n используется конструкция $array[n]: @numbers = (1, 2, 3, 4, 5); print $numbers[0]; # 1 print $numbers[1]; # 2 print $numbers[-1]; # 5 С каждым массивом @array связана переменная $#array, которую иногда не совсем точно называют длиной массива. На самом деле, она равна номеру последнего элемента массива. Мы можем не только читать значение этой переменной, но и изменять его, тем самым изменяя фактическую длину массива. Примеры: @numbers = (1, 2, 3, 4, 5); print $#numbers; # 4 $#numbers = 2; # @numbers = (1, 2, 3) $#numbers = 4; # @numbers = (1, 2, 3, undef, undef) В частности, для удаления всех элементов массива можно использовать следующие операторы, которые полностью эквивалентны: @array = (); $#array = -1; Для расширения массива до нужной длины можно также присвоить значение последнему (еще не существующему) элементу массива: @array = (); $array[3] = 3; # (undef, undef, undef, 3) Преобразование массива в скаляр возвращает длину массива, т. е. scalar(@array) = $#array + 1. Мы можем извлекать не только значения отдельных элементов массива, но и его подмассивы. Эта операция называется вырезкой (slice) и состоит в одновременном применении заданной операции к элементам массива, номера которых заданы списком. Пример: @people = ('Анна', 'Борис', 'Виктор', 'Георгий'); print @people[1, 3]; # ('Борис', 'Георгий') print @people[1..2]; # ('Борис', 'Виктор') ($him, $her) = @people[-1..0]; # $him = 'Георгий', $her = 'Анна' @people[2..4] = qw/Валентин Геннадий Дмитрий/; # теперь @people равен ('Анна', 'Борис', 'Валентин', 'Геннадий', 'Дмитрий') Для проверки понимания изложенного ответьте на вопрос: сколько элементов в массиве 6.2.7. Ассоциативные массивыАссоциативный массив — это неупорядоченный набор пар (ключ, значение), которые доступны по ключу. Для доступа к элементу массива %hash с ключом key используется конструкция $hash{key}. Существует два способа инициализации ассоциативного массива. Первый состоит в присвоении ему списка вида (ключ1, значение1, … ключn, значениеn), например: %fruits = ("зеленый", "яблоко", "оранжевый", "апельсин", "желтый", "банан"); print $fruits{"желтый"}; Эта программа выведет на экран слово банан. Второй способ инициализации ассоциативного массива использует операцию =>: %fruits = (красный => "яблоко", оранжевый => "апельсин", желтый => "банан"); Обратите внимание, что названия ключей здесь не заключены в кавычки. Дело в том, операция => по умолчанию считает, что ее левый операнд является строкой. Однако, если название ключа не является единым словом, нам придется использовать кавычки: %fruits = ("красно-зеленый" => "яблоко", оранжевый => "апельсин", желтый => "банан"); Для создания пустого ассоциативного массива используется пустой список (). Если мы хотим заранее задать размер массива, то можем использовать функцию keys: %colors = (); keys(%colors) = 1000; Размер ассоциативного массива всегда является степенью числа 2, поэтому фактический размер массива %colors будет равен 1024. Мы можем добавлять пары ключей и значений в ассоциативный массив как индивидуально, и с помощью вырезок: %colors = (red => 0xff0000, blue => 0x0000ff, green => 0x008000); $colors{'white'} = 0xffffff; @colors{'black', 'silver','gray'} = (0x000000, 0xc0c0c0, 0x808080); Эти конструкции требуют пояснения. Фигурные скобки здесь говорят о том, что мы обращаемся к ассоциативному массиву %colors, а символы % и @ указывают, что мы заносим в него скалярное значение и список соответственно. В скалярном контексте ассоциативный массив возвращает строку вида "m/n", где m — количество заполненных пар, а n —
количество выделенных пар в массиве. Поэтому мы можем использовать конструкцию 6.2.8. СсылкиСсылка — это указатель на переменную. PERL обеспечивает три способа создания ссылок. Первый способ состоит в применении к переменной операции \: $sref = \$scalar; # ссылка на скаляр $aref = \@array; # ссылка на массив $href = \%hash; # ссылка на ассоциативный массив Применение операции \ к списку возвращает массив ссылок, например оператор @list = \($a, @b, %c); эквивалентен оператору @list = (\$a, \@b, \%c); В частности, \(@array) возвращает массив ссылок на элементы @array. Аналогично и \(%hash) вернет массив ссылок на ключи и значения %hash с одним нюансом: возвращаются ссылки не на ключи исходного ассоциативного массива, а на их копии. Второй способ позволяет нам создавать ссылки на безымянные объекты. Ссылка на безымянный скаляр также создается операцией \: $nref = \10; # ссылка на число $sref = \"\n"; # ссылка на строку а ссылки на безымянные массивы и ассоциативные массивы создаются с помощью списков, заключенных в квадратные и фигурные скобки соответственно: $aref = [1, 2, 3]; $href = {red => 0xff0000, blue => 0x0000ff, green => 0x008000}; Еще один способ создания ссылок имеет синтаксис *name{THING}, где name — имя переменной, а THING — название ее типа: $sref = *x{SCALAR}; # ссылка на скаляр $x $aref = *x{ARRAY}; # ссылка на массив @x $href = *x{HASH}; # ссылка на ассоциативный массив %x Если переменной с заданным именем и заданного типа нет, то эта конструкция возвращает undef. Смысл конструкции *name описан в п. 6.2.10, возможные значения THING — в п. 6.7.1.2. Доступ к объекту, на который указывает ссылка $ref (разадресация ссылки) производится согласно следующему правилу: имя объекта эквивалентно выражению {$ref}. Это правило легко запомнить, но полученные с его помощью конструкции читать нелегко. Поэтому PERL допускает несколько сокращений, позволяющих обращаться к элементам разадресуемых объектов проще. Пусть, например, $s = "Проверка"; $ps = \$s; @a = (1, 2, 3); $pa = \@a; %h = {red => 0xff0000, blue => 0x0000ff, green => 0x008000}; $ph = \%h; Тогда следующие выражения эквивалентны:
Теперь мы можем привести пример использования ссылок. Рассмотрим следующий оператор: @a = ([1, 2, 3], [4, 5, 6], [7, 8, 9]); Он присваивает переменной @a массив, состоящий из трех ссылок на безымянные массивы. Фактически мы получили двумерный массив, к элементам которого можно обращаться так: $a[строка]->[столбец]. PERL позволяет нам опускать стрелку между индексами массива, т. е. обращение к элементу может иметь вид $a[строка][столбец], подобно обращению к элементам двумерных массивов в других языках программирования. 6.2.9. Символические ссылкиСсылки, рассмотренные в предыдущем разделе, выглядят вполне традиционно для программиста, знакомого с языками C/C++, Pascal и т. п. Однако, PERL содержит еще один вариант ссылок (т. н. символические ссылки), который ближе по возможностям к функции eval сценарных языков. Суть состоит в том, что любая скалярная переменная может интерпретироваться как указатель на переменную, имя которой она содержит. Пусть, например, переменная $name имеет строковое значение "abc". Тогда мы можем обращаться к $name как к ссылке на переменную с именем abc, например: $$name = 1; # $abc = 1 ${$name} = 2; # $abc = 2 ${$name x 2} = 3; # $abcabc = 3 $name->[0] = 4; # $abc[0] = 4 @$name = (); # @abc = () Это удивительно мощная, но опасная возможность; отсутствие скалярных типов приводит к тому, что любая скалярная переменная может служить ссылкой на свое содержимое. В итоге PERL считает корректной разадресацию любого скаляра, что может привести к очень интересным и трудноуловимым ошибкам исполнения. Поэтому PERL позволяет запретить использование символических ссылок в текущем блоке программы директивой use strict 'refs'; Во вложенном блоке мы можем вновь разрешить символические ссылки директивой no strict 'refs'; Локальные переменные, объявленные функцией my(), невидимы для символических ссылок. Например, сценарий $ref = "value"; $value = 10; { my $value = 20; print $$ref; } выведет на экран число 10, а не 20. 6.2.10. Ссылки на таблицу символовPERL использует для хранения ссылок на записи таблицы символов внутренний тип typeglob. Для указания на него используется форма *name. Основное назначение таких ссылок — создание синонимов для записей таблицы символов. Присваивание *this = *that; делает $this синонимом для $that, @this синонимом для @that, %this синонимом для %that и &this синонимом для &that. После этого любая операция с переменными this одновременно изменяет значение соответствующей переменной that, и наоборот. Пример: $a = 0; *b = *a; $a = 1; print $b; # выводит 1 $b = 2; print $a; # выводит 2 После появления в PERLе ссылок эта конструкция стала использоваться довольно редко. Тем не менее она продолжает употребляться в более безопасной форме следующего вида: local *my_x = \$x; Этот оператор временно делает переменную $my_x синонимом переменной $x, но не создает синонимов для @x и т. д. Еще одно полезное применение typeglob — это создание именованных констант, например, оператор *PI = \3.14159265358979; позволяет нам пользоваться значением переменной $PI, но запрещает его изменение. Подробнее о таблицах символов см. п. 6.7.1.2. 6.2.11. Описатели файловОписатели файлов (filehandles), строго говоря, не являются типом данных; это особый вид строковых констант. Однако, они во многом ведут себя так же, как переменные, поэтому мы описываем их в этой главе. Описатели файлов создаются встроенной функцией open() и обеспечивают ввод-вывод файлов, например: open INFO, "datafile" or die "Не могу открыть файл: $!"; Описатели файлов (как INFO в этом примере) принято записывать прописными буквами. PERL поддерживает три системных описателя файлов, которые создаются при запуске программы:
Для чтения данных из файла существует специальная операция <описатель>, в скалярном контексте возвращающая очередную запись файла или undef в конце файла или при ошибке чтения. Обычно записью является строка, но мы можем изменить символ конца записи, присвоив его специальной переменной $/. В любом случае возвращаемая строка содержит в конце разделитель записей. Мы можем присвоить результат этой операции любой переменной; если же операция вызвана без присваивания, то ее результат заносится в специальную переменную $_. Следующий пример читает строки из файла MYFILE.DAT и выводит их на консоль: open INFO, "myfile.dat" or die "Не могу открыть файл: $!"; while (<INFO>) { print; } В контексте списка эта операция считывает файл целиком и возвращает его содержимое как массив записей. Поэтому предыдущий пример можно записать так: open INFO, "myfile.dat" or die "Не могу открыть файл: $!"; @f = <INFO>; print @f; Операция <описатель> является сокращением для readline(*описатель). Существует особая "пустая операция" <>, которая читает либо стандартный файл ввода, либо последовательно все файлы, перечисленные в командной строке. При первом вызове операции <> PERL проверяет специальный массив @ARGV, содержащий список аргументов командной строки, и, если он пуст, заносит в $ARGV[0] строку "-", т. е. указатель на STDIN. Каждый последующий вызов <> возвращает очередную запись текущего файла, указанного в командной строке; если файл считан полностью, то окрывается следующий файл, указанный в командной строке, и возвращается его первая запись. Для проверки того, что все файлы считаны, используется встроенная функция eof(). Для вывода данных в файл обычно используется функция print(), например: print INFO "Моя строка"; Встроенные функции работы с файлами подробно описаны в гл. 6.11. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
HIVE: All information for read only. Please respect copyright! |
Advertising: |
|
![]() ![]() |