Скриптовый язык OpenObjectRexx

 

Автор: Людоговский Александр

Дата: 19.01.2009

Источник: https://www.script-coding.com/ooRexx.html

 

Open Object Rexx (ooRexx) - Open Source проект, обеспечивающий свободную реализацию Object Rexx (он может поставляться свободно даже с коммерческим программным обеспечением). Object Rexx является расширением классического Rexx, это мощный, полноценный язык программирования с human-ориентированным синтаксисом. Язык доступен для платформ AIX, Linux (в виде rpm- и deb-пакетов), Mac OSX, Solaris, Windows(32 bit; 98, Me, NT4, 2000, 2003, XP). Интерпретатор Open Object Rexx позволяет писать программы как процедурно, так и с объектно-ориентированным подходом. Язык ooRexx удобен в использовании, прост в изучении и полностью совместим с классическим Rexx.


Отличительные особенности языков Rexx (REstructured eXtended eXecutor) в самом общем виде:

  • богатый набор встроенных функций и методов;
  • вы можете выполнить команды Windows или Unix/Linux и другие приложения из программы Rexx полностью аналогично тому, как это можно сделать в пакетном файле оболочки (если некоторая команда в пределах сценария не может быть опознана интерпретатором, она выполняется как команда оболочки; выполнение команды оболочки можно вызвать и явно); кроме того, в программе Rexx можно получить код возврата команды и использовать любой её вывод;
  • достаточно нестрогие синтаксические правила; одна команда может располагаться на нескольких строках, несколько команд могут располагаться на одной строке; язык регистронезависим; во многих случаях разрешается добавлять или опускать пробелы; ключевые слова зарезервированы только в контексте: например, вы можете иметь переменную с именем, совпадающим с именем встроенной функции;
  • язык обрабатывает все данные как объекты различных видов; переменная может содержать любой объект, и вы не должны объявлять переменные как строки или числа; арифметические операции над переменной всегда возможны, если у переменной есть очевидное числовое значение; мощные возможности обработки строк (мощный и удобный оператор parse); можно выполнять арифметические операции с любой строкой, которая представляет правильное число, включая экспоненциальный формат;
  • подробные сообщения об ошибках и отладка с помощью команды trace.

 

Языки Rexx в целом позиционируются для разработки программ любой сложности (от коротких программ и прототипов до трудоёмких больших проектов). Rexx может обеспечить макроязык для других приложений; стандартный API делает Rexx переносимым между различными интерпретаторами Rexx; использующая Rexx программа может добавить к нему свои функции и опеpатоpы, котоpые будут доступны только пpи pаботе Rexx в контексте этой пpогpаммы.

Первая версия языка Rex появилась во внутренней сети IBM в 1979 г. и была разработана Майком Колишоу (Mike Cowlishaw). К 1982 году язык оформился в его теперешнем виде и получил вторую букву "x". Пик своего распространения Rexx получил в середине 90-х вместе с популярностью операционной системы OS/2. Несмотря на такой почтенный возраст, на сегодняшний день Rexx остаётся живым и развивающимся языком и технологическим средством, и существует не один интерпретатор Rexx. Несколько ссылок:

 

Язык Rexx считается одним из "прародителей" современного языка Windows Power Shell.


Язык Open Object Rexx является расширением классического Rexx, включающим классы, объекты и методы. Основные возможности ooRexx:

  • поддержка ООП (наследование, полиморфизм, инкапсуляция); это не замещает функции классического Rexx и не препятствуют разработке и исполнению программ на классическом Rexx (вы решаете сами, когда использовать ООП);
  • полная совместимость с классическим Rexx; программы на классическом Rexx будут работать без изменения, ooRexx полностью совместим с более ранними версиями IBM интерпретаторов Rexx; ooRexx обеспечивает стандартный API Rexx для разработки внешних библиотек функций, написанных на Cи;
  • поддержка COM;
  • тесная интеграция с Windows Script Host;
  • встроенные возможности для работы со строками, двоичными и шестнадцатеричными данными, base64, ассоциативными массивами, чтение и запись текстовых и бинарных файлов;
  • встроенные расширения для работы с TCP/IP, FTP, математическими функциями, построения GUI;
  • поддержка других внешних dll-расширений;

На момент написания данной статьи дистрибутив (инсталлятор) ooRexx для Windows имеет размер порядка 11 Мб. Текущая версия - 3.2.0, в планах разработчиков - версия 4. Чтобы ускорить выполнение программ Rexx, процесс rxapi.exe может быть запущен как служба. В процессе инсталляции ooRexx под Windows предлагается установить службу rxapi и запустить её.

После установки вы получите подробную документацию в виде набора PDF-файлов в каталоге /doc (англ.), включая Programming Guide. Та же документация доступна онлайн. В каталоге /samples вы найдёте около сотни примеров скриптов на ooRexx.

Скрипт rexxtry.rex, который вы найдёте в каталоге установки ooRexx (ярлык для его вызова будет и в главном меню Windows), является мини-интерпретатором Rexx, в котором можно вводить команды по одной.

Утилита rexxc.exe, которую вы найдёте в каталоге установки ooRexx, позволяет распространять скрипты ooRexx без их исходного кода. Полученный с помощью неё файл не будет являться исполняемым файлом, но отладить и исправить исходный код будет уже нельзя (это будет не текстовый файл).

Замеченные неприятности: ooRexx по умолчанию довольно коряво работает с русским языком.

 

Hello, World!

 

Переменные в Rexx не имеют никакого типа данных и не объявляются. Вместо этого Rexx следит за переменными за вас: например, определяет по контексту, является ли переменная строкой или числом. Переменная, которая была обработана в данной команде как число, в следующей команде может быть обработана как строка.

Создайте файл с расширением .rex в кодировке cp866 и запустите его двойным щелчком:

 

   say 'Введите своё имя:' /* отображает сообщение */
   pull name /* считывает ответ */
   say "Привет," name"!" /* отображает сообщение */
   pause /* ожидание, чтобы окно сразу не захлопнулось */
exit 0 /* выход с кодом возврата 0 */

 

Скрипт выше запрашивает у пользователя его имя, а затем отображает индивидуализированное приветствие. Вообще, язык проектировался с таким расчётом, чтобы его синтаксис был максимально легко читаемым и приближённым к естественному языку - программы Rexx легко понимаются интуитивно, код почти не требует комментариев. Скрипт, приведённый выше, можно запустить и из командной строки:

 rexx myScript.rex

 

В последнем случае команда pause для ожидания в скрипте не потребуется.

Если необходимо выполнить скрипт в "тихом" режиме, не отображая окно интерпретатора, вместо rexx.exe, использованного только что выше, можно вызвать rexxhide.exe. Если rexxhide вызывается из уже существующего окна командного интерпретатора, никакой вывод не будет отображаться. Вообще, rexxhide.exe предназначен для запуска полностью неинтерактивных скриптов.

Можно прервать выполняющийся скрипт Rexx нажатием клавиш Ctrl+Break.

Скрипты Rexx составлены из выражений - команд Rexx. Команды Rexx включают обязательные глаголы управления (например, if, select, do, call, return), а также глаголы, уникальные для Rexx (например, parse, guard, expose). В целом, есть порядка 30 команд. Многие скрипты Rexx используют лишь небольшое подмножество команд. Широкое разнообразие встроенных функций дополняет этот набор команд. Есть много функций для работы со строками (например, substr, words, pos, subword). Другие функции выполняют потоковый ввод-вывод (например, charin, charout, linein, lineout), преобразования данных (например, x2b, x2c, d2x, c2d) и т.д. Встроенные функции доступны в реализациях Rexx на всех операционных системах. В дополнение к этим независимым от системы функциям Rexx включает также ряд функций, специфичных для Windows.

Пример использования встроенной функции Rexx:

 

myname = "Иванов Иван Иванович"
surname = word(myname, 3) /* получаем третье слово в строке */
say surname
pause

 

Пример создания пользовательской функции Rexx:

   i = 10
   say myroutine(20, 30)
   pause
exit

myroutine: /* описание пользовательской функции */
   arg j, k
return i + j + k

Пример объектно-ориентированного подхода. Скрипт выполняет ту же работу, что и самый первый пример выше (запрашивает имя пользователя и отображает индивидуализированное приветствие):

 

   cl = .MyClass~new /* создание экземпляра класса MyClass */
   say "Объект класса создан."
   cl~hello /* вызов метода класса */
   pause
exit

::class MyClass /* описание класса MyClass */

::method init /* описание метода класса */
   expose nm
   say "Введите имя:"
   pull nm
return

::method hello /* описание метода класса */
   expose nm
   say "Привет," nm"!"
return

 

Ещё один пример, отражающий некоторые особенности синтаксиса Rexx (к слову, довольно изящные):

 

x.1 = "раз"
x.2 = "два"
do k = 1 to 2
    say x.k
end
pause

y.1.2.3 = "значение"
say y.1.2.3
pause

z.oops = "ой"
say z.oops
pause

Пример работы в качестве COM-клиента:

 

strComputer = "."
objWMIService = .OLEObject~GetObject("winmgmts:\\"||strComputer||"\root\CIMV2")
do objItem over objWMIService~ExecQuery("Select * from Win32_BIOS")
    say "Caption:" objItem~Caption
    say "Current Language:" objItem~CurrentLanguage
    say "Manufacturer:" objItem~Manufacturer
    say "Version:" objItem~Version
end
pause

wsh = .OLEObject~new("WScript.Shell")
wsh~popup("Привет, WSH!")

Пример выше выводит информацию о BIOS компьютера с использованием WMI, а затем демонстрирует диалоговое окно, используя COM-сервер "WScript.Shell".

 

Интеграция с Windows Script Host

 

При установке под Windows язык ooRexx становится одним из языковых "движков" Windows Script Host.

Пример использования ooRexx в качестве языка клиентских сценариев в браузере, демонстрирует обработку событий. Сохраните в файле с расширением .hta и запустите двойным щелчком:

 

<HTML>
<HEAD>
<meta http-equiv="Content-Language" content="ru">
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<TITLE>События</TITLE>
<script language="Object Rexx" >
::Routine Display Public
Window~Alert(Arg(1))
Return 0
</script>
</HEAD>

<BODY>
<H1>Использование событий</H1>

<FONT COLOR="#0000ff">
<P onmouseout="alert('Cursor left paragraph')" LANGUAGE="Object Rexx">
Событие случается, когда курсор мыши покидает этот параграф.</P>
<P onmouseover="a = Display('Cursor is over paragraph')" LANGUAGE="Object Rexx">
Событие случается, когда курсор мыши попадает на этот параграф.</P>

<FONT COLOR="#000000">
<P>Следующий абзац реагирует на клик:</P>

<FONT COLOR="#0000ff">
<P onclick="call Display 'current time ' time()" LANGUAGE="Object Rexx">Нажми меня!</P>

</BODY>
</HTML>

 

На языке Object Rexx можно писать скрипты в формате WSF, а также COM-серверы в формате WSC. Сохраните пример в файл с расширением .wsf:

 

<?xml version="1.0" encoding='windows-1251'?>
<?job error="true" debug="true" ?>
<package id="wstest">
<job idid="RunByDefault">
<script language="JScript">function GetScriptEngineInfo(){
var s;
s = "";
s += ScriptEngine() + " Version ";
s += ScriptEngineMajorVersion() + ".";
s += ScriptEngineMinorVersion() + ".";
s += ScriptEngineBuildVersion();
return(s);
}
]]>
</job>
</package>

 

Запустите скрипт командой, подобной следующей:

 

cscript test.wsf

Скрипт выше выводит на консоль сведения об установленной версии Windows Script Host.

Код на Object Rexx можно выполнять из других языков, используя MSScriptControl. Пример на VBScript (сохраните в текстовый файл с расширением .vbs и запустите командой наподобие "cscript test.vbs"):

Set ScrptCtrl = CreateObject("MSScriptControl.ScriptControl")
ScrptCtrl.Language = "Object Rexx"
ScrptCtrl.Eval("say 'hello'")

Вы можете запускать скрипты на Object Rexx с помощью интерпретаторов cscript.exe или wscript.exe. Пример команды запуска:

 

cscript //e:"Object Rexx" test.rex

При этом будет автоматически доступен объект WScript, предоставляемый Windows Script Host, например:

 

WScript~Echo("hello")

Расширения Rexx

 

Язык Rexx не может непосредственно вызвать любую функцию любой dll-библиотеки. Однако, существуют dll-библиотеки функций Rexx, написанные специальным образом, которые можно использовать. В поставке ooRexx есть несколько таких мощных библиотек. Сценарий Rexx может использовать встроенную функцию RxFuncAdd(), чтобы зарегистрировать нужную функцию в такой dll, и затем вызвать эту функцию. Библиотека может иметь функцию, которая загружает разом все остальные функции этой же библиотеки.

Пример использования библиотеки rxmath.dll, входящей в поставку ooRexx:

call RxFuncAdd "MathLoadFuncs","rxmath","MathLoadFuncs" /* подключение rxmath.dll и её функции "MathLoadFuncs" */
call MathLoadFuncs /* подключение всех функций rxmath.dll */
say RxCalcSqrt(289) /* вычисление квадратного корня */
pause

 

Язык Rexx может быть использован как макроязык для других приложений, на котором можно писать различные расширения для этих приложений. Например, для автоматизации OpenOffice.org.

В поставку ooRexx входит библиотека OODialog для построения GUI (к слову, это не единственный инструмент для построения GUI на Rexx). В каталоге /samples вы найдёте довольно много примеров построения GUI на ooRexx, а здесь приведём пару скриншотов: