Шрифт:
Интервал:
Закладка:
Каждый созданный дескриптор должен быть закрыт, то есть убран из памяти компьютера, по крайней мере до завершения скрипта. Делается это командой close. Конечно, интерпретатор сам заботится о закрытии всего открытого, но это очень хорошая привычка на будущее.
Мрачная команда die всего лишь означает выход из скрипта с кодом 0. При этом весь список сообщений, указанный в команде будет дан в диалоге. Эта команда в примере подсоединяется с помощью логической операции «или» ||. То есть на самом деле результирующая команда звучит так: «Открой для добавления файл rand.txt или, если не сможешь, вываливайся из скрипта…». Можно, например, указать die "Can not open file $file", но если ничего не давать в двойных кавычках, то в диалоге будет сообщена причина (сообщение о системной ошибке), взятая из системной переменной $! что является более информативным.
Функция rand(100) возвращает псевдослучайное число в диапазоне от 0 до 100, а функция int(), дополнительно берет от него только целую часть для вывода.
В нашем примере каждая строка вывода завершается "rn" (возврат каретки, перевод строки). Причем именно в таком порядке. Так было принято в MS DOS для файлового вывода и продолжает действовать в MS Windows. Это нужно запомнить.
Урок 3. Из файла на принтер
Поскольку, изучив предыдущие примеры, вы уже можете считаться продвинутым программистом, то этот пример немного усложним, добавив обратную сортировку на пути между чтением данных из файла и выводом их на принтер.
# Lesson 3
$file = \tempWrand.txt;
sub reverse {
$a < $b? 1: $a > $b? — 1: 0;
}
########### INPUT ###########
open(DATA, $file) || die ""
while (<DATA>) {
chop;
($item, $num) = split;
push(0data, dec($num));
}
close DATA;
#### SORT ####
@sdata = sort reverse @data;
########## OUTPUT ###########
open(LPT, ">LPT1") || die "Check out printer!";
foreach(@sdata) {
print LPT $_, "n";
}
close LPT;
Сортировка данных осуществляется командой sort. Эта команда действует на массивы переменных, то есть несколько переменных, оперирируемых как одно целое. Данная команда возвращает отсортированный массив, не затрагивая исходный. Имена массивов переменных предшествуются префиксом @, вместо $. С командой sort связана одна маленькая проблема — она сортирует числа как текст, то есть в таком порядке 0, 1, 10, 11, 12…19, 2, 20, 21…. С этим явлением вы наверное не раз встречались в MS Windows. В файле же rand.txt у нас хранятся числа, в текстовом виде, но все-таки числа. Для решения таких проблем команда sort имеет дополнительную возможность — она может использовать для сравнения пары данных внешнюю подпрограмму, имя которой дается сразу после имени команды. Сама подпрограмма sub reverse, в данном примере, находится в начале скрипта. Команда sort передает сравниваемые данные в подпрограмму как две переменных $а и $Ь, а не как массив переменных @_, это исключение нужно запомнить. Подпрограмма сравнения должна вернуть 1 если данное из $а нужно поместить дальше данного из переменной $Ь, если наоборот то -1, и 0 — если и так сойдет. Естественно, что в подпрограмму сравнения должны поступать числа, а не текст и сравниваться должны именно числа.
В данном примере подпрограмма сравнения обеспечивает именно обратную сортировку — меньшие числа продвигаются вперед. Само сравнение осуществляется с помощью пары условных операторов?. Условный оператор выполняет одно из двух действий в зависимости от того верно или нет утверждение до?. Его общий формат выглядит так test? expressionl: expression2. В качестве test может быть любое логическое выражение. Результат выполнения expressionl возвращается, если утверждение в test верно. В противном случае возвращается результат выполнения expression2.
Рассмотрим ввод данных из файла. В данном примере используется несколько упрощений для наиболее часто используемых действий, аналогично тому, как в делается в языке «С» (вместо х = х + n, используется х += n; вместо х = х + 1 используется просто х++ и т. п.), только QSL в этом направлении идет еще дальше. Конечно язык QSL, так же как и «С», содержит и стандартные конструкции, скрипты можно писать и на их основе.
Для ввода данных из файла в примере используется не команда, а оператор чтения < >. При его каждом вызове он возвращает символьную строку. Возвращаемая строка должна быть записана в какую-нибудь переменную, но в случае использования оператора чтения в операторе повторения блока while, и только тогда, оператор присваивает возвращаемое в системную переменную $_. Оператор while повторяет выполнение блока пока условие в круглых скобках верно, в данном случае до конца файла («Читай файл, пока считывается»).
Оператор < > считывает все символы строки из файла до n (код 10), как это принято в UNIX и встречается под MS Windows. Следовательно, оставшийся в конце строки r (код 13) является для нас лишним. Для его удаления использовалась команда chop, по умолчанию удаляющая последний символ, в переменной $_.
Каждая строка, данного файла имеет вначале номер строки, он нам не нужен. Выделить нужные данные можно с помощью команды разбиения строки split. Эта команда разделяет строку на составляющие, по умолчанию из переменной $_ и используя пробелы и табуляции как разделители. Возвращаемые командой данные должны быть записаны в массив переменных. Такой, но самодельный, мы ей и подсунули (в круглых скобках), хотя конечно имени у него никакого нет, но нам оно, в дальнейшем,