П2.4.1.2 Символьные ссылки
Мы рассмотрели, что происходит, если величина, используемая в качестве ссылки, не
была определена ранее. Что же происходит, если она уже определена и не является
жесткой ссылкой? В таком случае она обрабатывается как символьная ссылка. То есть
значение скаляра рассматривается как имя переменной, а не прямая ссылка на
переменную.
¯
$name = "foo";
$$name = 1; - то же самое, что $foo = 1;
${$name} = 2; - то же самое, что $foo = 2;
${$name x 2 } = 3; -то же самое, что $foofoo = 3;
$name->[0] = 4; -то же самое, что $foo[0] = 4;
@$name = (); - обнуляет массив @foo
&$name(); - вызывает &foo
П2.4.2 Регулярные выражения
Perl позволяет использовать регулярные выражения.
Для того чтобы пояснить, что же представляет из себя регулярное выражение
приведем несколько примеров:
/SWAP.*/ - соответствуют все слова начинающиеся со SWAP и заканчивающихся
произвольным набором символов. Точка обозначает произвольный символ, звездочка -
то, что символ, стоящий перед ней, входит в слово 0 и более раз. Все метасимволы,
которые будут описаны ниже, бозначают вхождение того, что стоит перед ними.
/\w*/ - соответствуют слова состоящие только из алфавитных, цифровых
символов и символа подчерк. \w - соответствует алфавитным, цифровым
символам и символу подчерк, звездочка - тому, что эти символы могут входить
произволное количество раз.
Здесь мы приведем
только основные метасимволы. Для более подробной информации смотрите
соответствующие страницы man по Perl.
¯
* соответствует 0 или более вхождений
+ соответствует 1 или более вхождений
? соответствует 1 или 0 вхождений
{n} соответствует ровно n вхождений
{n,} соответствует по крайней мере n вхождений
{n,m} соответствует по крайней мере n,
но не более m вхождений
Метасимвол * эквивалентен {0,} , + эквивалентен
{1,} и ? эквивалентен {0,1} . Ограничений на величину m и n
нет. Эта стандартная конструкция работает в ``жадном'' режиме, то есть:
регулярному выражению a.*b будет соответствовать всевозможный набор слов начинающихся
с символа a и кончающихся символом b , в том числе слова типа abcab . В таких
словах есть подпоследовательности символов, которые также удовлетворяют условиям
регулярного выражения. Если после каждого из описанных метасимволов поставить знак
? , то подобные последовательности будут опускаться.
Шаблоны обрабатываются как строка в двойных кавычках, поэтому приведенные ниже
последовательности также будут обрабатываться:
¯
\l - передвижение на символ вниз
\u - передвижение на символ вверх
А также все перечисленные ранее бакслэш-последовательности.
В Perl-е определены также:
¯
\w - соответствуют алфавитные и цифровые
символы а также символ подчерк
\$W - соответствуют все символы не входящие
во множество символов w
\s - символы пробела, табуляции, возврата каретки
\S - все символы не входящие во множество символов
s
\d - цифровые символы
\D - нецифровые символы
Обратите внимание, что \w отмечает только отдельные
символы, а не все слово. Чтобы отметить все слово нужно использовать \w+ .
Также определены следующие команды:
¯
\b - соответствуют границы слова
\B - соответствуют не-границы слова
\A - соответствуют только начало строки
\Z - соответствуют только конец строки
При использовании конструкции типа ( ... ), \<digit> подставляет
подстроку из скобок с номером digit . Можно использовать скобки для
отделения подшаблона. Если в скобках имеется более, чем 9 подстрок, то
переменные $10 , $11 , ... содержат соответствующие подстроки.
$+ возвращает то, чему соответствует последняя конструкция в скобках. $&
возвращает подставленную строку. $` возвращает все перед подставленной
строкой, $' возвращает все после подставленной строки.
$_ = 'abcdefghi';
/def/;
print "$`:$&:$'\n"; - напечатает abc:def:ghi
На этом мы закончим описание регулярных выражений, для более подробной
информации читайте manual page .
П2.4.3 Зарезервированные переменные
В Perl есть имена имеющие специальное значение. Многие из них аналогичны
зарезервированным именам в shell . Если вы хотите использовать длинные имена
переменных, в заголовке программы требуется сказать:
use English;
Многие переменные доступны только для чтения, то есть при попытке присвоения
такой переменной какого-либо значения напрямую или по ссылке происходит ошибка.
$_
В эту переменную по умолчанию происходит ввод, присваивание, в нее
складываются результаты поиска по заданному образцу.
while(<>){...}
или, что то же самое:
while($_= <>) {...}
$<digit>
Эта переменная была описана в предыдущем параграфе. Она
доступна только для чтения, так же как и переменные $& , $` , $' и $+ .
$.
Эта переменная содержит номер строки, которая была почитана
последней из файла, который был прочитан последним. Она также доступна только
для чтения.
$/
Содержит символ по которому разделяются вводимые записи. По умолчанию
содержит символ перевода строки. Она похожа на переменную RS из awk .
$|
По умолчанию имеет значение 0. Если содержит ненулевое значение,
то происходит сброс буферов каждый раз после осуществления вывода
(на печать, на экран и т.д.).
$,
Содержит символ-разделитель полей для оператора печати. Подобна
переменной OFS в awk .
$
Содержит символ-разделитель записей для оператора печати.
Подобна переменной ORS в awk . (Вы можете определить $ вместо того,
чтобы печатать n в конце печати.)
$"
Подобна переменной $, . Но используется при обращении к списку величин
в двойных кавычках (или другой строке, которая требует интерпретации). По
умолчанию содержит символ пробел.
$;
Содержит символ-разделитель для эмуляции многомерных хэшей. Если
ссылаться на такой элемент хэша как $foo{$a,$b,$c} то реально это будет
происходить так: $foo{join($;,$a,$b,$c)} . Не путайте с @foo{$a,$b,$c} ,
так как это тоже самое, что($foo{$a},$foo{$b},$foo{$c}) . По умолчанию
содержит значение \034 такое же как переменная SUBSEP в awk .
$#
Формат для печати чисел. Подобна переменной OFMT в awk . Первоначально
содержит значение %.20g.
$%
Содержит номер текущей выводимой страницы.
$=
Содержит длину текущей страницы (количество печатных срок), обычно
содержит значение 60.
$-
Содержит значение, определяющее количество оставшихся на странице строк,
например количество еще не напечатанных строк для печатного канала вывода.
$~
Содержит имя текущего формата сообщений. Обычно имя дескриптора файла.
$^
Содержит имя текущего формата заголовка страницы. Обычно содержит имя
дескриптора файла с добавлением в конце _TOP
$:
Содержит множество символов после которых вывод сроки может быть
прерван и начат снова после перевода строки.
$!
Если эта переменная используется в числовом контексте, то содержит
текущее значение errno (номер ошибки) со всеми обычными сообщениями. В строковом
контексте содержит соответствующее системное сообщение об ошибке.
$@
Содержит сообщение о синтаксической ошибке, допущенной во время
исполнения последней команды eval() . Если содержит значение 0, то команда
была исполнена корректно. Но заметьте, что сообщения не накапливаются в этой
переменной.
$$
Содержит идентификатор текущего процесса.
$<
Содержит идентификатор пользователя (UID), которому принадлежит текущий
процесс.
$>
Содержит эффективный UID текущего процесса.
$(
Содержит идентификатор группы (GID) пользователя, которому принадлежит
текущий процесс.
$)
Содержит эффективный GID текущего процесса.
$0
Содержит имя файла, в котором находится исполняемая программа.
$ARGV
Содержит имя текущего файла, из которого происходит чтение.
@ARGV
Содержит массив аргументов командной строки, которые были переданы
программе.
@INC
Содержит список точек входа в программу, в которых используются
конструкции do EXPR , require и use .
%INC
Содержит входы для каждого файла, который включается посредством
использования операторов do или require . Ключами являются имена файлов, а значениями
места их расположения.
%ENV
Содержит текущее окружение процесса. Изменением содержимого
хэша можно изменить окружение порожденного (дочернего) процесса.
%SIG
Этот хэш используется для установки обработчиков различных
сигналов. Например:
sub handler {
local($sig) = @_;
print "Caught a SIG$sig - shutting down\n";
close(LOG);
exit(0);
}
$SIG{'INT'} = 'handler';
$SIG{'QUIT'} = 'handler';
...
$SIG{'INT'} = 'DEFAULT';
$SIG{'QUIT'} = 'IGNORE';
П2.4.4 Встроенные функции
abs VALUE
Возвращает абсолютное значение аргумента.
accept NEWSOCKET, GENERICSOCKET
подобно системному вызову accept(2) ждет соединения.
Возвращает запакованный адрес, если соединение произошло успешно и FALSE в
противоположном случае.
atan2 Y,X
Возвращает arctg(Y/X) .
bind SOCKET, NAME
Привязывает сетевой адрес к сокету,
также как системный вызов bind в OS UNIX или любой другой
системе, поддерживающей BSD Sockets . Если привязка произошла
успешно, возвращает TRUE , в противном случае - FALSE . Переменная NAME должна
содержать запакованный адрес, соответствующего для сокета типа.
Тип адреса для разных видов сокетов определяется в терминах языка C структурой
sockaddr , которая представляет собой абстрактный тип, содержащий
все данные, необходимые для сокета.
binmode FILEHANDLE
Позволяет читать или писать файл с соответствующим
дескриптором в бинарном режиме.
bless REF, PACKAGE
Эта функция присоединяет объект на который указывает
ссылка REF , к пакету PACKAGE , если он определен, если же он опущен, то к текущему
пакету. Для удобства возвращает ссылку, так как bless() часто является последним
оператором в конструкторе.
caller EXPR
Возвращает контекст текущего вызова подпрограммы. В скалярном
контексте возвращает TRUE , если мы находимся внутри подпрограммы, eval() или
require() . FALSE в противоположном случае. В списковом контексте возвращает:
($package, $filename, $line) = caller;
С аргументом EXPR возвращает более сложную информацию, которая используется
отладчиком для печати карты стека. Значение EXPR отмечает глубину стека до
текущей записи.
($package, $filename, $line,
$subroutine, $hasargs, $wantargs) = caller($i);
chdir EXPR
Изменяет текущую директорию на указанную в EXPR , если это
возможно. Если EXPR опущено, то устанавливает в качестве текущей директории
домашнюю директорию. Возвращает TRUE в случае успеха и FALSE иначе.
chmod LIST
Изменяет права доступа к файлам указанным в LIST . Первым
аргументом должна быть маска доступа в цифровом формате. Возвращает число
файлов права доступа к которым были успешно сменены.
$cnt = chmod 0700 'foo','bar';
chmod 700 @executables;
chown LIST
Изменяет хозяина или группу, которой принадлежит список файлов.
Первыми двумя аргументами должны быть uid и gid. Возвращает количество успешных
изменений.
chr NUMBER
Возвращает символ, представленный номером NUMBER в наборе
символов. Например, chr(65) вернет A .
close FILEHANDLE
Закрывает файл с дескриптором FILEHANDLE . Для более подробной
информации читайте manual page .
open(OUTPUT '/usr/home/petrov');
...
close OUTPUT;
closedir DIRHANDLE
Закрывает каталог открытый вызовом opendir() .
connect SOCKET,NAME
Пытается соединиться с удаленным сокетом (по аналогии с системным вызовом).
Возвращает TRUE в случае успешного соединения и FALSE в противоположном случае.
Переменная NAME должна содержать запакованный адрес соответствующего данному
сокету типа.
cos EXPR
Возвращает косинус EXPR , выраженного в радианах. Если EXPR опущено,
возвращает косинус $_ .
dbmopen ASSOC, DBNAME, MODE
Связывает dbm(3) или ndbm(3) файл с
ассоциативным массивом. ASSOC - имя ассоциативного массива. DBNAME - имя базы данных
(без .dir или .pag расширения). Если база данных не существует, то она создается
с правами доступа указанными в MODE .
dbmopen(%HIST,'/usr/lib/news/history', 0600);
while (($key, $val) = each %HIST){
print $key, '=', unpack('L',$val),\n;}
dbmclose(%HIST);
dbmclose ASSOC
Прерывает связь между файлом и ассоциативным массивом.
defined EXPR
Возвращает TRUE или FALSE , в зависимости от того определено
значение EXPR или нет. Многие операции возвращают неопределенное значение в
случае конца файла, неинициализированной переменной, системной ошибки или при
подобной ситуации. Если речь идет о хэше, то defined покажет только определены ли
ли величины, ничего не говоря о существовании ключей. Для определения существования
ключей используется функция exists() .
delete EXPR
Стирает указанную величину. Возвращает удаленную величину
или значение не определено в случае, если удаление не произошло.
foreach $key (keys %array) {
delete $array{$key};
}
Но более быстро то же самое можно сделать используя функцию undef() .
die LIST
Вне eval() печатает значение LIST в STDERR и выходит из программы с
текущим значением $! . Если значение $! есть ноль, то принимает значение $? >> 8 .
Если значение $? >> 8 есть ноль, то принимает значение 255. Внутри eval()
сообщение об ошибке помещается в переменную $@ и eval() прерывается с
неопределенным значением.
open(FL, "/root/rm-rf") || die "Can't open file.\n";
do BLOCK
Функцией не является. Возвращает значение последней операции
внутри блока.
do EXPR
Использует величину EXPR как имя файла и далее запускает содержимое
этого файла, как программу на Perl. Обычно это используется для включения
библиотечных подпрограмм.
do 'stat.pl';
Это то же самое, что:
eval 'cat stat.pl';
Однако подключать библиотечные модули более удобно используя use и require .
each ASSOC_ARRAY
Возвращает массив из двух элементов, содержащий ключ
и значение из хэша, причем по очереди перебирает все пары ($key, $value) .
while (($key,$value) = each %ENV){
print " $key = $value \n";
}
eof FILEHANDLE
Возвращает 1, если следующее считывание возвращает конец
файла или если FILEHANDLE не был открыт. При опущении аргумента eof обрабатывает
последний файл, из которого происходило считывание. Но на практике эта функция
редко используется, так как в Perl-е операторы чтения возвращают неопределенное
значение в конце файла.
eval EXPR
EXPR выполняется как маленькая программа в контексте основной
программы. Определенные переменные и подпрограммы остаются определенными и в
дальнейшем. Возвращается значение, которое возникает при обработке последнего
выражения. Если EXPR опущено, то обрабатывается $_ .
exec LIST
Исполняет внешнюю программу и НИКОГДА не возвращает управление.
На самом деле (в UNIX ) производится системный вызов семейства exec , который
подменяет программу, исполняющуюся в рамках текущего процесса.
Если LIST представляет собой список из более, чем одного аргумента, то вызывается execvp(3)
с аргументами из LIST . Если аргумент только один, то он проверяется на метасимволы
shell . Если они присутствуют, то он далее передается /bin/sh -c для обработки.
Если же их нет, то аргумент передается напрямую execvp , который более эффективен.
exists EXPR
Возвращает TRUE , если в хэше есть ключи и даже в том случае,
когда значения VALUE не определены.
exit EXPR
Обрабатывает EXPR и осуществляет немедленный выход с полученной
величиной.
$ans = <STDIN>;
exit 0 if $ans =~ /^[Xx]/;
Если EXPR опущено, то осуществляет выход с нулевым статусом.
exp EXPR
Возвращает е (основание натурального логарифма e = 2.718281828...)
в степени EXPR . По умолчанию обрабатывается $_ .
fork
Делает системный вызов fork(2) . Возвращает pid (идентификатор
процесса) дочернего процесса родительскому процессу и 0 дочернему процессу.
Значение не определено в случае неуспешного завершения команды. Неуспех может
произойти, например, в случае установки в системе ограничения на количество
процессов данного пользователя. Вот небольшой пример использования этой
функции.
unless ($pid = fork) {
unless (fork) {
exec "what you really wanna do";
die "no exec";
some_perl_code_here;
exit 0;
}
exit 0;
}
waitpid($pid,0);
getc FILEHANDLE
Возвращает следующий символ из файла чтения,
присоединенный к FILEHANDLE или пустую строку в случае конца файла. Если
FILEHANDLE опущен, то считывание происходит из STDIN .
goto LABEL
Эта функция осуществляет переход на точку программы LABEL и
продолжает выполнение программы с этой точки. Точка не может находиться внутри
подпрограммы или foreach цикла, так как в этих случаях требуется предварительная
инициализация.
Использовать в качестве LABEL выражение не рекомендуется, хотя такая возможность
и предоставляется.
grep BLOCK, LIST
grep EXPR, LIST
Обрабатывает BLOCK или EXPR для каждого элемента LIST
и возвращает список элементов для которых значение выражения TRUE . В скалярном
контексте возвращает число элементов для которых EXPR TRUE .
hex EXPR
Возвращает десятичное значение EXPR , интерпретируемого как
шестнадцатеричная строка. По умолчанию обрабатывает переменную $_ .
kill LIST
Посылает сигнал списку процессов LIST , первым элементом списка
должен быть номер сигнала. Возвращает число процессов, которым сигнал был
послан успешно. В отличие от shell , если номер сигнала отрицателен, то он посылается
группе процессов.
int EXPR
Возвращает целую часть EXPR , если EXPR опущено, то
обрабатывает переменную $_ .
join EXPR,LIST
Соединяет в единую строку строки из LIST . При этом
в качестве разделителей между элементами LIST ставит значение EXPR . Например:
$_ = join( ':',$login,$passwd,
$uid,$gid,$gcos,$home,$shell);
keys ASSOC_ARRAY
Возвращает обычный массив, состоящий из ключей
ассоциативного массива ASSOC_ARRAY . В скалярном контексте возвращает число
ключей.
@keys = keys %ENV;
length EXPR
Возвращает длину EXPR в символах. По умолчанию обрабатывает
переменную $_ .
link OLDFILE,NEWFILE
Создает файл NEWFILE , присоединенный к файлу
OLDFILE . (В OS UNIX создание нескольких имен для одного файла) Возвращает 1
в случае успеха и 0 иначе.
listen SOCKET, QUEUESIZE
Делает то же самое, что и одноименный системный
вызов. Возвращает TRUE в случае успеха, FALSE иначе.
local EXPR
На самом деле гораздо эффективнее использовать функцию my .
Функция local делает перечисленные переменные локальными в блоке, подпрограмме,
eval или do . Если переменных более, чем одна, то они должны объединяться скобками.
sub RANGEVAL{
local($min,$max,$thunk) = @_;
local $result = '';
local $i;
for ($i = $min; $i < $max; $i++) {
$result = eval $thunk;
}
$result;
}
log EXPR
Возвращает натуральный логарифм EXPR , по умолчанию обрабатывает
переменную $_ .
map EXPR,LIST
Подставляет каждый элемент из списка LIST в EXPR (которое
может быть блоком) и возвращает список полученных после обработки величин.
@chars = map(chr, @nums);
mkdir FILENAME,MODE
Создает директорию с именем FILENAME и правами доступа
указанными в переменной MODE . В случае успеха возвращает 1, в противном случае
возвращает 0 и устанавливает значение переменной $!(errno) .
my EXPR
Эта функция (так же как и описанная ранее функция local ) делает
перечисленные переменные локальными в пределах блока, подпрограммы, eval или do.
Если список состоит более чем из одного элемента, то он должен быть заключен в
скобки. Все элементы в списке должны быть фактическими параметрами. В отличие от local,
переменные локализованные функцией my не видны снаружи блока, подпрограммы или
другой конструкции, внутри которой my употребляется.
next LABEL
Употребляется подобно continue оператору в C - запускает
следующую итерацию цикла.
line: while (<STDIN>) {
next line if /^#/;
...
}
oct EXPR
Возвращает десятичное значение EXPR , интерпретируемого как
строка в восьмеричном формате. (Если строка начинается с 0x , то интерпретируется,
как строка в шестнадцатеричном формате.)
open FILEHANDLE,EXPR
Открывает файл, имя которого описано в переменной
EXPR и привязывает его к FILEHANDLE . Если EXPR опущено, то переменная с таким
же именем как FILEHANDLE содержит имя файла. Если имя файла начинается со знака:
¯
< файл открывается на чтение.
> файл открывается на запись.
>> файл открывается для добавления.
| имя файла расценивается как команда,
с которой будет организован программный канал,
то есть вывод в дескриптор FILEHANDLE будет
передаваться на вход программе EXPR.
Если знак | указывается после имени команды, то вывод этой команды
будет ассоциирован с дескриптором FILEHANDLE , из которого будет производиться
чтение. Интересно, что
нельзя открыть двойной программный канал, то есть ассоциировать ввод и вывод
команды с дескриптором файла (что соответствовало бы системному вызову popen в
UNIX ).
В случае, когда имя файла оканчивается вертикальной чертой, оно расценивается
как имя команды, вывод которой будет интерпретироваться как ввод из файла
(аналог функции popen(3) ).
open(LOG, '>>/usr/spool/news/twitlog');
open DIRHANDLE,EXPR
Открывает директорию с именем EXPR , возвращает TRUE
в случае успеха.
ord EXPR
Возвращает числовое значение в таблице ASCII первого символа EXPR .
По умолчанию обрабатывает переменную $_ .
print FILEHANDLE,LIST
Печатает строку или несколько строк, разделенных
запятой. FILEHANDLE может быть именем скалярной переменной, содержащей дескриптор
файла. Если эта переменная опущена то печать идет в выбранный канал вывода.
Если переменная LIST тоже опущена, то печатает переменную $_ в STDOUT .
|