Скалярный тип

Любой язык предоставляет в распоряжение программиста набор базовых типов данных, а также некоторые механизмы создания новых типов данных. В языке Perl используется всего три базовых типа: скаляры, массивы скаляров и ассоциативные массивы, или хэш-массивы. Встроенного механизма создания новых типов данных, как в других языках программирования, в Perl не предусмотрено. Поэтому, например, создать структурный тип данных, предлагаемый большинством языков программирования, в Perl нельзя. Однако с помощью хэш-массивов, которых нет ни в одном языке программирования, и механизма ссылок создание подобных структурированных данных не представляет труда.
Мы, конечно, погорячились, сказав, что в Perl не предусмотрено механизмов создания новых типов данных. В соответствии с современной тенденцией развития методологии программирования Perl позволяет разрабатывать классы объектов и работать с ними в соответствии с обычным объектно-ориентированным подходом. Таким образом, в языке существует механизм создания новых типов, если рассматривать класс объектов как новый тип данных.
Тип данных определяет не только множество допустимых значений, но и допустимые операции над этим множеством данных, В связи с таким подходом к пониманию типа данных в этой главе будут рассмотрены и основные операции над базовыми типами данных, а также основной набор встроенных функций, предназначенных для работы с данными этих типов.

Скалярный тип

Скалярный тип данных включает в себя числовые и строковые данные, а также ссылки. В языке для чисел и строк предусмотрены соответствующие литералы, или буквальные константы, с помощью которых данные этих типов вводятся непосредственно в сценарий Perl. Ссылки определяются с помощью специальной операции \, примененной к имени переменной, и содержат адреса области памяти расположения переменных. В этом разделе мы не будем останавливаться на ссылках, они являются важным механизмом создания сложных типов данных и поэтому им в нашем учебном пособии посвящена отдельная глава.

Числовые и строковые литералы

С помощью числовых литералов задаются целые и вещественные десятичные числа, а также восьмеричные, шестнадцатеричные и двоичные константы.
Литералы целых чисел представляются последовательностью цифр без пробелов, не начинающейся с нуля, с необязательным предшествующим символом + или - для задания знака числа, причем для положительных чисел знак может быть опушен:
345. +345.  -345
Литералы вещественных чисел полностью совпадают с записью подобных чисел в математике: целая часть числа представляется целым литералом, за которым после точки следует дробная часть числа, представленная последовательностью десятичных цифр. Если целая часть равна нулю, то ее можно опустить. Подобное представление вещественных чисел часто называют представлением с фиксированной дробной частью:
23.6709, +23.6709.  -0.560,  -.56
Для вещественных чисел с плавающей точкой можно использовать и экспоненциальную форму записи
[целая часть].[дробная часть][Е|е][+|-][экспонента]
которая означает, что мантиссу числа [целая часть], [дробная часть] следует умножить на 10 в степени экспонента:
10.67Е+09. 10.67е9, 10.67е-09.  -.06е+3
Для отделения триад разрядов в целой и дробной частях вещественного числа допускается использовать символ подчеркивания: 3_000_001.000_001 (эквивалентно 3000001.000001)
Интерпретатор языка Perl представляет все числа (и целые, и вещественные) в формате чисел с плавающей точкой удвоенной точности. Это означает, что реально нельзя задать больше пятнадцати значащих цифр мантиссы, а экспонента ограничена диапазоном от -323 до +309. Интерпретатор не будет генерировать ошибку, если мантисса превосходит 15 цифр, а экспонента 3 цифры, но при отображении таких чисел мантисса будет приведена к пятнадцати значащим цифрам. Если экспонента меньше нижнего предела, то будет выводиться 0, а если больше верхнего предела, то используется специальный символ 1.#INF, обозначающий бесконечно большое число. Подобный алгоритм представления очень больших и очень маленьких чисел не приводит к возникновению ошибок, соответственно, переполнения и исчезновения порядка, свойственных многим языкам программирования. Если задать целое число с числом значащих цифр больше 15, то при выводе оно будет отображаться как вещественное в экспоненциальной форме.
Литералы для восьмеричных и шестнадцатеричных констант полностью совпадают с записью этих чисел в языке С: последовательность десятичных чисел, начинающаяся с 0, представляет восьмеричное число, а шестнадцатеричные числа начинаются с префикса 0х, за которым следует последовательность шестнадцатеричных цифр(0..9, A...F):
010 (эквивалентно десятичному 8)
0xlAbB (эквивалентно десятичному 6643)
В Perl 5.6 были введены двоичные, или бинарные, константы, представляющие собой последовательности нулей и единиц, начинающиеся префиксом 0b100 (эквивалентно десятичному 4).
ВНИМАНИЕ. При задании восьмеричных чисел использовать цифры от 0 до 7, для двоичных использовать только 0 и 1, а в шестнадцатеричных константах прописные и строчные буквы, используемые для соответствующих шестнадцатеричных цифр, эквивалентны. Это единственный случай в Perl, когда прописные и строчные буквы трактуются одинаково. Однако в префиксе шестнадцатеричных и двоичной константы не допускается использовать прописные буквы Х и В соответственно.
Строковые литералы, или строки, в языке Perl представлены последовательностью символов, заключенных в одинарные ', двойные " или обратные ` кавычки. Все эти три типа строк по-разному интерпретируются в сценарии Perl. Первые два строковых литерала используются аналогично их применению в операционной системе UNIX: в строках, ограниченных одинарными кавычками, нельзя использовать управляющие последовательности, тогда как в строках, ограниченных двойными кавычками, управляющие последовательности интерпретируются в соответствии с их назначением. Строки в обратных кавычках не являются строками Perl в том смысле, что строки должны содержать информацию, которая может быть обработана с помощью каких-либо строковых операций. Они просто являются компактной формой записи операции выполнения команды операционной системы.
Прежде чем перейти к подробному описанию строковых литералов и работе с ними, следует остановиться на понятии управляющей последовательности, которое взято из языка программирования С. Управляющая последовательность — это комбинация обратной наклонной черты и следующих за ней определенных символов, трактуемая операционной системой как единое целое и определяющая некоторые специальные действия. Так, переход на новую строку представляется как \n.
В табл. 3.1 представлены все управляющие последовательности, которые можно использовать в строках языка Perl.

Таблица 3.1. Управляющие последовательности языка Perl.

Управляющая последовательность Значение
\a Звонок
\b Возврат на шаг
\e Символ ESC
\f Перевод формата
\n Переход на новую строку
\r Возврат каретки
\t Горизонтальная табуляция
\v Вертикальная табуляция
\$ Знак доллара
\@ Коммерческое AT
\0nnn Восьмеричный код символа
\xnn Шестнадцатеричный код символа
\cn Эмулирует нажатие комбинации клавиш Ctrl+n, например \cZ соответствует Ctrl+Z
\l Переводит следующий символ в нижний регистр
\u Переводит следующий символ в верхний регистр
\L Переводит следующую за ней последовательность символов, ограниченную управляющей последовательностью \Е, в нижний регистр
\Q В следующей за ней последовательности символов, ограниченной управляющей последовательностью \Е, перед каждым неалфавитно-цифровым символом вставляет обратную дробную черту
\U Переводит следующую за ней последовательность символов, ограниченную управляющей последовательностью \Е, в верхний регистр
\E Ограничивает действие управляющих последовательностей \L \Q и \U
\\ Обратная наклонная черта
\" Двойная кавычка
\' Одинарная кавычка

В строках, ограниченных одинарными кавычками, все символы представляют самих себя, за исключением двух управляющих последовательностей \' и \\, которые трактуются соответственно как одинарная кавычка и одна обратная наклонная черта. Значит, в таких строках нельзя использовать весь арсенал управляющих последовательностей. Можно, однако, создавать многострочные литералы. Для этого при задании строки в одинарных кавычках следует использовать клавишу Enter, если необходимо перейти на новую строку. Приведем пример, демонстрирующий создание многострочного строкового литерала в одинарных кавычках:
'Это литерал,
заданный на 
нескольких строках'
Строки в двойных кавычках интерпретируют управляющие последовательности, а также поддерживают подстановку значений скалярных переменных и массивов скаляров. Более подробно подстановка значений скалярных переменных рассматривается далее в этом же подразделе, а массивов скаляров — в следующем разделе «Массивы скаляров» данной главы.
Строки в двойных кавычках удобно использовать для структурированного вывода информации, используя управляющие последовательности перехода на новую строку, табуляции и т. п., а также для вставки значений скалярных переменных. Например, следующая строка
"\Uline\E\t#1\n\LLINE\U\t#2"
будет отображена функцией print в виде
LINE  #1 
line  #2
Так же как и в случае со строками в одинарных кавычках, при задании в тексте программы строкового литерала в двойных кавычках можно определять многострочные литералы, используя клавишу Enter для перехода на новую строку. Предыдущий строковый литерал можно определить и так:
"\Uline\E\t#1\n\LLINE\U\t#2"
Однако в этом случае между двумя выводимыми строками будет добавлена пустая строка, так как в строковый литерал после нажатия клавиши Enter при задании литерала вставляется символ перехода на новую строку;
LINE   #1
line   #2
Помещение строк в обратных кавычках в сценарий Perl, как отмечалось ранее, представляет удобный способ выполнения команд операционной системы или другой программы и получения в сценарии их экранного вывода. Встретив строку в обратных кавычках, интерпретатор передает ее на обработку операционной системе и возвращает информацию, отображаемую этой командой на экране монитора, в виде строкового литерала, который можно сохранить в скалярной переменной и использовать в дальнейшем в сценарии Perl.
Содержимое строки в обратных кавычках должно быть правильной командой операционной системы, в которой выполняется сценарий. Если имя команды не соответствует ни одной допустимой команде операционной системы, то результатом выполнения операции заключения в обратные кавычки будет отображенное на экране сообщение о неправильном имени команды.
Завершая разговор о строковых литералах, следует сделать важное замечание, относящееся к последней версии 5.6 языка Perl. В ней реализована поддержка Unicode формата UTF-8 (самими разработчиками этой версии поддержка Unicode считается самым важным ее отличием от предыдущих версий языка). Это означает, что Perl при работе с символами «думает» в терминах символов Unicode, а не в байтах, как в предыдущих версиях. Следовательно, появилась возможность использовать символы, для представления которых требуется несколько байтов памяти. Для их задания в строках, ограниченных двойными кавычками, нужно использовать управляющую последовательность \х{ }, в фигурных скобках которой задается код Unicode символа:
$glis = "\x{395}\x{3CD}\x{3B1}\x{3B3}\x{3B3}\x{3B5}\x{3BB}\x{3CA}\x{3B1}";
При этом следует в начале сценария обязательно задать специальную прагму:
use utf8;
Основное предназначение этой прагмы — сообщить интерпретатору, что в исходном тексте программы используются символы Unicode. Для переключения в «старый» режим работы с символами, расположенными побайтно, используйте прагму
use byte: 
Отметим, что Perl 5.6 теперь внутренне сохраняет все строки в формате Unicode.

Скалярные переменные

Все обрабатываемые в программе данные хранятся в некоторой области оперативной памяти компьютера, определяемой своим адресом. Языки высокого уровня для удобства ссылок к данным в программе реализуют специальный механизм символических имен — переменные. Каждая переменная имеет имя, представленное ее идентификатором, и в программе с помощью специальных синтаксических конструкций объявляется, какие типы данных она может содержать. Таким образом, использование переменных в языке — это всего лишь удобный способ обращения к области памяти.
В Perl, как уже отмечалось, нет специальных операторов объявления используемых переменных — любая переменная объявляется в том месте, где впервые используется в программе. Тип хранимых в переменной данных определяется префиксом, задаваемым перед идентификатором переменной. Для переменных, в которых могут храниться скалярные данные, предусмотрен префикс $. Например, следующие переменные являются переменными скалярного типа, или просто скалярными переменными:
$myVar, $first, $file
В скалярной переменной можно хранить одно скалярное значение: число, строку или ссылку, причем не существует способа определить, какой именно тип скалярных данных содержится в ней в каждый конкретный момент. При использовании скалярных переменных в операциях хранимые в них данные автоматически преобразуются из одного скалярного типа в другой. Например, в арифметических операциях строка преобразуется в число (в предположении, что она содержит строку, которая может быть преобразована в числовое значение), в строковых операциях наоборот — числовые значения переменных преобразуются в строковые.
Важное свойство скалярной переменной заключается в том, что ее значение можно подставлять в строки, заданные в двойных кавычках, причем числовое значение будет преобразовано в строковое. Это означает, что в строке можно указать имя скалярной переменной и ее значение будет вставлено в строку в то место, где задано ее имя. Подобную операцию будем в дальнейшем для краткости называть подстановкой переменной. (Забегая вперед, скажем, что операцию подстановки «поддерживает» и переменная, представляющая массив скаляров.) Например, следующая последовательность операторов
$year = 2001;
$cost = "\$37";
$message = "В $year году книга стоила $cost";
print $message;
отобразит на экране монитора строку
В 2001 году книга стоила $37
При подстановке переменной в строку важно, чтобы интерпретатор смог правильно выделить идентификатор скалярной переменной. Как только в строке встречается символ $, интерпретатор начинает формировать идентификатор имени переменной, добавляя следующие за ним символы, пока не встретится пробел, управляющая последовательность или символ, который не может использоваться в идентификаторе имени переменной, например символ национального алфавита, отличного от латинского (в частности, русского). Причем между префиксом $ скалярной переменной и ее идентификатором может стоять произвольное число пробелов. Следующий фрагмент программы
$year = 2000;
$titul = "\"Самоучитель Perl\"";
$message = "Книга $titul: год издания $ уеаr г.";
print $message;
напечатает строку
Книга "Самоучитель Perl": год издания 2000 г.
При подстановке переменной в строку можно явно указать ее идентификатор, заключив его в фигурные скобки {...}:
$message = "Книга ${titul}: год издания $(year)г.";
Задавая в качестве значения скалярной переменной строку в одинарных кавычках, содержащую единственное слово, не равное какому-либо ключевому слову Perl, кавычки можно опускать:
$date = уеаr2001; # Эквивалентно $date = 'year2001';
Синтаксический анализатор Perl выделяет из текста программы слова (не заключенные в какие-либо кавычки последовательности алфавитно-цифровых символов) и определяет их принадлежность множеству ключевых слов. Если встретившееся слово таковым не является, то оно интерпретируется как строка в одинарных кавычках. Такие слова в тексте программы называются простыми словами (barewords).
ВНИМАНИЕ. В простых словах можно использовать только символы латинского алфавита, наличие символов национального алфавита, например кириллицы, приведет к ошибке интерпретации.
При присваивании значений скалярным переменным можно использовать специальные литералы языка Perl: __LINE__, __FILE__ и __PACKAGE__. По сути, они являются самостоятельными лексемами и представляют соответственно номер текущей строки в файле программы, имя файла программы, которое задается при запуске интерпретатора pert, и имя пакета. Следующий фрагмент программы
$file = __FILE__;
$pack = __PACKAGE_;
$line = __LINE__+2;
print "Пакет: $pack\n";
print "Печать из строки номер $line\n файла: $file\n";
распечатает имя пакета, номер строки, содержащей оператор печати, и имя файла программы, если интерпретатор запускался из каталога, содержащего файл программы ex03-01.pl, с помощью команды perl ex03-01.pl:
Пакет: main
Печать из строки номер 6
файла: ex03-01.pl
Кроме рассмотренных двух специальных лексем язык Perl предоставляет еще две: __DATA__ и __END__. Они используются в качестве указателей логического конца программы до достижения физического конца содержащего ее файла. Это означает, что любая информация, расположенная в файле после этих специальных литералов, не обрабатывается интерпретатором. В сценарии ее можно получить, прочитав из файла с дескриптором PACKNAMES::DATA, где PACKNAMES является именем пакета, в котором используется эта лексема. При использовании в сценарии верхнего уровня имя его пакета main можно опустить. После чтения информации из файла с дескриптором PACKNAMES::DATA он остается открытым, и при необходимости его следует явно закрыть функцией close.
Лексема __END__ оставлена для совместимости с ранее разработанными сценариями до включения в язык лексемы __DATA__ и действует аналогично ей только для сценариев верхнего уровня. В пакетах она также означает логический конец текста сценария, но прочитать данные, расположенные в файле за ней, не представляется возможным. В листинге 3.1 представлен код сценария верхнего уровня, использующего лексему__DATA__. В цикле while читаются строки, расположенные за лексемой __DATA__, пока не будет достигнут физический конец файла.
Листинг 3.1. Специальная лексема __DATA__
#!perl-w
print "Текст после специального литерала __DАТА__\n\n";
while ($after = <DATA>) {
  print $after;
}
__DATA__
Произвольный текст,
который не интерпретируется,
но может быть прочитан.
Результат выполнения сценария из листинга 3.1:
Текст после специального литерала _DATA_

Произвольный текст,
который не интерпретируется,
но может быть прочитан.

Стандартные функции обработки скаляров

Когда мы в программе скалярной переменной присваиваем двоичный, восьмеричный или шестнадцатеричный литерал, он автоматически воспринимается Perl как правильное число, и при последующем выводе на печать или использовании такой переменной в выражении ее содержимое трактуется как правильное число. Однако если указанные числа были получены при чтении из файла или введены пользователем с клавиатуры, то их автоматического преобразования в правильные числа не происходит. Они воспринимаются Perl как последовательности символов, а не двоичные, восьмеричные или шестнадцатеричные числа. Для преобразования строки, содержащей такие последовательности символов, в правильные числа следует воспользоваться стандартными функциями oct( ) и hex( ).
Функция oct( ) преобразует восьмеричные числа, представленные в виде строки как с начальным нулем "0570", так и без него "570". Более того, она также преобразовывает и двоичные, и шестнадцатеричные числа, причем в качестве префикса можно использовать не только "0b" или "0х", но и просто "b" и "x":
print oct("0570"l;      # Напечатает десятичное 376
print oct("570");       # Напечатает десятичное 376
print oct("0xAf");      # Напечатает десятичное 175
print oct("xAf");       # Напечатает десятичное 175
print oct("0b00ll00l"); # Напечатает десятичное 25
print oct("b001100l");  # Напечатает десятичное 25
Функция hex( ) работает только с шестнадцатеричным представлением чисел с префиксами "х" и "0х" или вообще без них:
print oct("0xAf");	# Напечатает	десятичное	175
print oct("xAf");	# Напечатает	десятичное	175
print oct("Af");	# Напечатает	десятичное	175
Для вычисления значений основных математических функций в стандартную библиотеку Perl включены следующие функции:
Со строками в Perl можно выполнять разнообразные преобразования с помощью стандартных функций выделения подстроки substr( ), разбиения строки split( ), перевода содержимого строки в верхний uc( ) или нижний ( ) регистр и других, которые будут рассмотрены в главе, посвященной работе со строками. Здесь же мы только остановимся на функции reverse( ), которая позволяет осуществить обратную перестановку символов в строке. Если результат выполнения этой функции присвоить скалярной переменной, то содержимым этой переменной будет содержимое строки-аргумента с измененным на противоположный порядком символов. (Забегая вперед, уточним, что функция reverse( ) в скалярном контексте возвращает содержимое строки-аргумента в противоположном порядке.)
$string = "Прямой порядок";
$reverse = reverse($string); # $reverse = "кодяроп йомярП"

Следующая страница Содержание главы


Реклама