Глава 11

Первое знакомство
с ARexx'ом

Встроенный в версии ОС 2 и 3 язык программирования ARexx заслуживает отдельной толстой книжки. Не претендуя на исчерпывающее его описание, попробуем рассказать об основных моментах использования языка в Амигах.

Для начала представим себе такую ситуацию. У нас есть анимационный файл, в котором, ну, скажем 100 кадров. Мы хотим изменить формат каждого из кадров. Есть программа AdPro, которая позволяет делать с любым из кадров все, что угодно. Так что теперь, повторять 100 раз подряд одну и ту же операцию, каждый раз загружая и записывая очередной кадр? А если мы к тому же хотим плавно изменять палитру, постепенно затемняя кадры?

Или, допустим, у нас одновременно работают база данных и текстовый редактор. Неужели же для того чтобы "перегнать" некоторый текст из редактора в базу, надо сначала записывать файл, находясь в редакторе, потом переходить в базу, а оттуда загружать его?

Те, кто работал на IBM PC, зачастую как "Отче наш" знают текстовый редактор MultiEdit. Этот редактор имеет свой собственный макроязык, который позволяет легко автоматизировать и конфигурировать редактор по своему усмотрению. Разумеется, PC - не Амига; другой РС-шный редактор уже будет иметь СВОЙ макроязык, третий - свой и т.д. Да и попытку одновременного запуска MultiEdit вместе с CorelDraw и Excel, к тому же с возможностью параллельного и независимого обмена данными и командами между ними при помощи единого универсального макроязыка, оставляем в качестве домашнего задания для пытливого читателя.

Но вернемся к Амиге. Представьте ситуацию, когда вся многозадачная компьютерная система имеет мощнейший универсальный макроязык, интерпретатор которого работает на "заднем плане" абсолютно независимо от других происходящих в системе процессов... Этот интерпретатор определяет, имеют ли встречаемые им в командном файле конструкции отношение к нему лично. Если да - обрабатывает их сам, если нет - посылает их своему текущему "хозяину", который сам должен разобраться, что за команду ему подсунули. Хозяина можно менять в любой момент - им может быть не только любая из работающих прикладных программ, имеющих ARexx-интерфейс, но и вся операционная система Амиги.

Этот макроязык называется ARexx. "Стартером" для его интерпретатора является небольшая программа каталога System, которая называется Rexxmast. Существуют также компиляторы ARexx-программ, специально предназначенные для тех программистов, которые "попав" в ARexx, "выскочить" из него уже не могут. По мощности этот язык ни в чем не уступает скажем, такому гиганту, как С (разве что по скорости исполнения - скомпилированные ARexx-программы все-таки работают медленнее С-шных). Пусть вас не удивляет размер программы Rexxmast - чуть больше двух килобайт. Это просто сервер процесса, открывающий порт ARexx-a. Вся сила спрятана в ARexx-овских библиотеках, открываемых только тогда, когда нужно (никаких там сотен килобайт памяти ARexx от системы не отъедает, невзирая на свои просто абсолютные возможности; в среднем расходуется около 40 Кб для работы интерпретатора). Rexxmast лучше всего запускать из файла S:User-startup, вставив туда строчку:

System/Rexxmast >NIL:

Можно также перенести иконку программы RexxMast из каталога System в каталог WBStartup, после чего запуск Rexxmast также будет происходить автоматически. Однако в этом случае каждый раз после старта системы будет вылетать окошко, напоминающее об авторских правах на ARexx.

После своего запуска сервер ARexx-a открывает связной порт и "ложится спать", не отнимая далее у системы драгоценного процессорного времени. Разбудить сервер может любая попытка послать сообщение в открытый им порт, после чего будут предприняты немедленные действия, определяемые характером этого сообщения. Следует заметить, что связные порты не являются прерогативой ARexx-a - на них построена вся ОС Амиги, ARexx в данном случае "всего лишь" пользуется возможностями ОС.

Все программы, использующие ARexx, должны включать в себя некоторые средства для связи с его интерпретатором. Для этого требуются крайне незначительные добавки к программам, встроить которые не представляет особого труда. Предельного же уменьшения размеров дополнительного кода можно добиться, использовав разделяемые библиотеки (например, easyrexx.library), которыми одновременно может пользоваться любое число программ для реализации требуемых ARexx-возможностей.

Язык Rexx разработал Майк Кулешов для mainframe-компьютеров фирмы IBM в начале 80-х годов. Автором амиговской версии является Вильям Хейз (первая буква "А" названия амиговской версии языка означает "Amiga"). ARexx встраивается в систему, начиная со второй версии ОС. Для более старых ОС - он может быть установлен "вручную" - первые версии ARexx появились еще в 1987 году.

Итак, подытожим, что такое ARexx:

    1. Универсальный язык программирования.
    2. Средство межпрограммного общения.
    3. Универсальный системный макроязык.

Число программ, так или иначе использующих ARexx, непрерывно увеличивается. Практически все новые неигровые программы имеют собственный ARexx-порт. В феврале 1994 года таких программ было 370, сейчас (июнь 95-го) - около тысячи.

ОС 2 и 3 имеют специальный каталог Rexxc, где находятся базовые программы, так или иначе обслуживающие ARexx-функции системы. Все эти программы являются обычными исполняемыми файлами - командами ОС. Наиболее важной из них является RX, позволяющая исполнять программы, написанные на ARexx-e. Ее параметром может быть:

    1. Имя текстового ARexx-файла, который будет интерпретироваться подобно тому, как ОС интерпретирует командные файлы Амиги. Пример использования:
      rx  Make.rexx
      Исполнится файл Make.rexx, содержащий текст ARexx-программы.


    2. Некоторая командная строка, содержащая одно или несколько утверждений ARexx-a. Отдельные утверждения в этом случае отделяются друг от друга символом ";".

Другие программы каталога Rexxc используются в следующих случаях:

НI посылает "стоп-сигнал" всем работающим ARexx-программам (таким образом, можно например "выскочить" из зациклившейся программы во время ее отладки).

RXC полностью прекращает работу ARexx-сервера системы после окончания работы последней из ARexx-программ.

RXSET позволяет менять значения глобальных переменных ARexx-a в так называемом клип-списке.

ТСС, ТСО, ТЕ, TS управляют отладочным режимом исполнения ARexx-программ, когда последовательно выводится информация обо всем, что происходит во время их работы.

WaitForPort после запуска ожидает открытия некоторой программой своего связного порта в течение 10-ти секунд. В случае неудачи возвращает уровень ошибки 5 (WARN). Если на момент исполнения программа WaitForPort порт уже открыт, она немедленно возвращает ноль. Обычно используется в тех случаях, когда ARexx-программа хочет выяснить, является ли активной некоторая программа.

Применение WaitForPort попробуем объяснить на примере. Допустим, мы хотим, чтобы Амига сказала с помощью русификатора по русски "Здравствуйте", причем мы заранее не знаем, работает ли в системе русификатор или нет. Вот текст соответствующей ARexx-программы с комментариями:

/*  Первая  строчка любой ARexx-программы всегда содержит 
комментарий */

if ~show('PORTS', 'Rusifier.port') then        /* Порт */
                           /* русификатора уже открыт? */
  do
     address command    /* Нет, хозяин теперь ОС Амиги */
     rusifier                /* Запускаем русификатор, */
                             /* если он есть в системе */
     'WaitForPort Rusifier.port'      /* Ждем открытия */
                              /* порта русификатора... */
     if rc = 5 then                      /* Дождались? */
     do
       say 'Не могу запустить русификатор...'  /* Нет, */
                                   /* не  дождались... */
       exit                  /* Конец работы программы */
     end
  end 
address 'Rusifier.port'     /* Русификатор  работает! */
                                  /* Он теперь хозяин */
'SPEAK Здравствуйте!'    /* Посылаем ему нашу команду */

Поскольку ARexx, "по умолчанию", - интерпретируемый язык, то нет необходимости писать отдельные программные файлы, чтобы заставить его исполнить какое-либо элементарное действие. Если мы, например, знаем что русификатор работает, то можно просто набрать в shell-окне:

rx "address 'Rusifier.port'; 'SPEAK Здравствуйте!'"

и результат будет тем же самым. Вот что произошло в этом случае:

Столь многословное описание дано с той целью, чтобы вы смогли прочувствовать общие механизмы работы ARexx-a в многозадачном окружении. Сам интерпретатор, разумеется, может исполнять любое число ARexx-программ одновременно.

Интерпретаторы вообще (а интерпретатор ARexx-a в частности), делают свое дело (исполняют программы), прямо скажем, не быстро. Впрочем, можно говорить о чистом эффекте "ARexx-торможения" только в случае работы больших интерпретируемых ARexx-программ, которые мало обращаются к системным библиотекам и все действия (особенно циклические) выполняют, используя "исконные" ARexx-утверждения.

Для справки: на модели А4000/040 (25 мгц) пустой цикл вида

do 100000
end

выполняется около 8 секунд (разумеется, в режиме интерпретации).

Для того, чтобы программировать на ARexx-e, не обязательно быть программистом. Образно говоря, ARexx - это рояль, на котором чаще всего играют одним пальцем. Элементарные действия и выполняются элементарно просто - даже неподготовленному пользователю достаточно нескольких минут, чтобы уже что-то получилось. 99% существующих ARexx-программ имеют в длину менее 99-ти строчек и отлаживаются в течение максимум 99-ти секунд (конечно, если вы не задумали или вам не заказали нечто эпохальное - например, автору этой книги однажды на полном серьезе предложили написать программу, воспринимающую с голоса турецкий язык и мгновенно говорящую то же самое по-грузински).

Автор, будучи сам апологетом языка Forth, но работающий исключительно на С (к сожалению. Forth на Амиге как-то не прижился), отнюдь не призывает создавать большие проекты с помощью ARexx-компиляторов. В конце концов, это дело вкуса.

Одно из основных отличий ARexx-a от других языков программирования заключается в том, что переменные ARexx-a не имеют типа; никаких предварительных описаний переменных нет. Значение переменной можно использовать в качестве числа, или строки символов - как вам угодно. Например, пусть значением переменной "s" будет строка "123":

s = '1231'   /* Апострофы указывают  границы  строки  */

Комментарии заключаются, как и в языке "С" между /* ... */. Поскольку и нам, и ARexx-y ясно, что 123 является числом, то ничто не мешает исполнить:

у = s + 2

А теперь вспомним, что '123' - строка и исполним:

say left(s,1) ==> 1

Здесь и далее по тексту символы "==>" означают, что часть строки справа от них является результатом работы части строки слева от них. Оператор say выводит значение некоторого выражения, (аналог PRINT языка BASIC), функция left(s,n) возвращает подстроку строки "s" длиной "n" символов, чье начало совпадает с началом исходной строки.

Многим пуританам от программирования подобная свобода обращения с переменными покажется не слишком симпатичной, однако ARexx работает именно так, хотим мы этого или нет.


Сайт создан в системе uCoz