Интернет-журнал "Домашняя лаборатория", 2007 №5
Шрифт:
Последняя команда print выводит значение, возвращаемое функцией квадратного корня из числа sqrt. Вообще говоря, можно писать print($i) и sqrt $i, это кто как привык. То же самое можно сказать об использовании подавляющего большинства команд.
В QSL последовательность (группа) команд может быть интерпретирована как одна команда (блок), если эта группа команд заключена в фигурные скобки. Блок может иметь присваиваемое имя, в этом случае он называется подпрограммой. В данном примере подпрограмм нет, но есть блок. В частном случае блок или подпрограмма может содержать только одну команду.
Еще в этом примере есть оператор циклического повторения в форме for(EXPR1;EXPR2;EXPR3) BLOCK. В переводе на обычный
Урок 2. Вывод в файл
Скрипт Lesson 2 выводит в файл rand.txt 1000 случайных чисел в диапазоне от 0 до 100. Заодно вы можете проверить насколько распределение псевдослучайных чисел, генерируемых в QSL, соответствует равномерному распределению.
# Lesson 2
$file = "rand.txt";
srand;
open (DATA, "»\\temp\\$file") || die """";
for($i=0; $i<1000; $i++) {
print DATA $i, "\t", int(rand(100)), "\r\n";
}
close DATA;
До выполнения работы по выводу, скрипт осуществляет некоторые подготовительные мероприятия. Первым делом он записывает название файла в переменную $file. Это удобно тем, что в реальном скрипте название файла может использоваться несколько раз, если использовать вместо названия переменную с ним, то, в случае необходимости, смену названия можно сделать только в одном месте по тексту скрипта. QSL включает в себя также ряд средств для взаимодействия с пользователем — название файла можно вводить и в диалогах вызываемых командами ask, аореn.
Второе мероприятие заключается в выборе начального значения псевдослучайной последовательности чисел командой srand. Эта команда без аргумента, в качестве его использует значение возвращаемое командой time, то есть значение счетчика секунд с момента начала компьютерной эры (1 января 1970 года, ровно в полночь).
Вывод данных в файл осуществляет та же самая команда print, но с одним существенным дополнением. Для того чтобы сделать вывод в какой-нибудь файл или устройство, нужно указывать дескриптор для этого файла или устройства. Обратите внимание, что в команде print дескриптор указан сразу после имени команды и не отделяется запятой (не входит в список). Дескриптор файла на самом деле содержит всю необходимую информацию о файле или устройстве и должен быть предварительно создан командой open. В QSL заложен только один постоянный дескриптор CONSOLE, он просто используется командой print по умолчанию, поэтому не указывается, но дескриптор по умолчанию может быть изменен.
Рассмотрим использование команды open в этом примере. DATA — это имя, выбранное для дескриптора. Рекомендуется использовать для имен дескрипторов буквы верхнего регистра, это улучшает читабельность скриптов и предотвращает конфликты с зарезервированными словами (именами команд). Через запятую указано имя файла, который нужно связать с дескриптором. Несколько деталей относительно имени файла в данном примере. Имя файла дано в двойных кавычках. Двойные кавычки, в отличие от одинарных ('), являются интерпретируемыми, то есть переменная $file будет заменена ее содержимым. Поскольку слеш \ задействован для управляющих символов, то для разделения директорий на пути к файлу используется \\, который преобразуется при выполнении к нормальному разделителю. Таким образом, в команде open был дан полный путь к файлу \temp\rand.txt. Конечно, директория temp
Каждый созданный дескриптор должен быть закрыт, то есть убран из памяти компьютера, по крайней мере до завершения скрипта. Делается это командой close. Конечно, интерпретатор сам заботится о закрытии всего открытого, но это очень хорошая привычка на будущее.
Мрачная команда die всего лишь означает выход из скрипта с кодом 0. При этом весь список сообщений, указанный в команде будет дан в диалоге. Эта команда в примере подсоединяется с помощью логической операции «или» ||. То есть на самом деле результирующая команда звучит так: «Открой для добавления файл rand.txt или, если не сможешь, вываливайся из скрипта…». Можно, например, указать die "Can not open file $file", но если ничего не давать в двойных кавычках, то в диалоге будет сообщена причина (сообщение о системной ошибке), взятая из системной переменной $! что является более информативным.
Функция rand(100) возвращает псевдослучайное число в диапазоне от 0 до 100, а функция int, дополнительно берет от него только целую часть для вывода.
В нашем примере каждая строка вывода завершается "\r\n" (возврат каретки, перевод строки). Причем именно в таком порядке. Так было принято в 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 — если и так сойдет. Естественно, что в подпрограмму сравнения должны поступать числа, а не текст и сравниваться должны именно числа.