Начинаем пользоваться REXX

Автор: В.Казимирчик

Источник: RDM/2

Дата: 21 февраля 2000 г.

В этой статье будет рассматриваться использование classic REXX под OS/2 (как наиболее изученного мной и применяемого ежедневно - kzm).

Командные файлы REXX имеют расширение CMD - такое же, как и командные файлы OS/2. Отличаются эти два вида файлов тем, что у командных файлов REXX в первой строке обязательно должен быть проставлен комментарий, вот так:

   /* */

или так:

   /* REXX */

или так:

   /* Это я написАл! 8-)))))) */

То есть на содержимое комментария ограничений не накладывается.

Для того, чтобы потестировать REXX без написания командного файла, в комплект OS/2 входит rexxtry.cmd. Попробуем его запустить и "поиграться". Оцените понятность языка и простоту его освоения.

   rexxtry

Не знаю, русифицирован ли rexxtry в русской версии OS/2, но если нет, то несколько строк, выводимых на экран, означают "пробуй, помощь по "?", выход по exit".

Обрабатываем текст:

   Say 'Привет всем'

А теперь выведем не константу, а переменную:

   string = 'Привет всем'

   Say string

Разобьем строку на две части:

   string1 = word(string, 1)

   string2 = word(string, 2)

   Say string1 string2

Можно и так:

   Say string1 || ' ' || string2 || '!'

Как вы уже догадались, || - оператор конкатенации строк. Усложним предложение:

   string = string || ' осевикам'

   say string

Измерим количество слов в предложении:

    say words(string)

Теперь выведем часть предложения:

   Say substr(string, 3, 11)

 

Немного арифметики.

Следует помнить, что в REXX все переменные - символьные. Даже цифры. Потеря в производительности? Наверняка. Плюсы? Например, нет необходимости преобразовывать строку в число и т.д. А также - отсутствие потери точности, наблюдающееся при операциях с плавающей точкой. Примеры:

   Say 2*2 Say 1024 * '2'

Большие числа:

   say 10000000000000000000000 + 0.01

Получаем 1.0000000E+22

А теперь так:

   Numeric digits 25

   say 10000000000000000000000 + 0.01

Получаем 10000000000000000000000.01

 

Объединение команд

Несколько команд можно объединять в одну, разделив их знаком ";". Например, простейший цикл по выводу квадрата чисел от 1 до 10, который в cmd-файле удобно написать в 3 строки, для возможности использования в REXXTRY может быть представлен одной строкой:

   Do i = 1 To 10 ; Say i**2 ; End

Еще один пример цикла с условием:

   i = 0 ; Do while i < 10 ; i = i + 1 ; Say i ; End

 

Массивы

В REXX аналог массивов - т.н. "stem variables". Как они работают, видно на примере:

   string.1 = word(string, 1)

   string.2 = word(string, 2)

   string.3 = word(string, 3)

   string.0 = 3

Количество элементов размещено в string.0. В принципе, "индекс" элемента может быть не только цифрой, но и строкой, например, string.first, но тогда возникают сложности с учетом элементов (в classic REXX нет возможности определить все элементы стема, зная только его имя до точки, в object REXX, насколько я помню, такая возможность есть).

   Do i = 1 to string.0 ; Say string.i ; End

Кстати, переменная string и стем string. - не одно и то же. Переменная string в этом примере как была, так и осталась.

Присваиваем всем элементам одно и то же значение:

   string. = 'Сброс'

   string.0 = 3

   Do i = 1 to string.0 ; Say string.i ; End

 

Работа с файлами

Создаем новый файл и записываем в него нашу многострадальную переменную string (3 раза для верности):

   filename = 'file.tmp'

   Do i = 1 to 3 ; Call LineOut filename, string ; End

(если файл с именем file.tmp уже существовал, то в него будут дописаны 3 строки с содержимым переменной string)

Закрываем файл:

   Call Stream filename, 'c', 'close'

Определяем размер файла:

   nSize = stream(filename, 'c', 'query size')

   Say 'Файл' filename 'имеет размер' nSize 'байт'

И считываем его полностью в новую переменную:

   fileContent = charin(filename, , nSize)

Убеждаемся ;-), что содержимое переменной имеет ту же длину, что и файл:

   Say length(fileContent) nSize

Нет, наверное, лучше так:

   Say length(fileContent) = nSize

Полученный результат '1' означает 'True'. Настало время попробовать If.

   If length(fileContent) = nSize Then Say 'OK'; Else Say 'o.b.'

Команду OS/2 или внешнюю программу из-под REXX можно выполнить, написав командную строку в кавычках:

   'dir /p' 'del file.tmp'

На первый раз достаточно.

Выходим:

   Exit

Rexxtry также можно запускать с параметром - исполняемая строка. Например, вариант простейшего калькулятора:

   rexxtry say 2*2