Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
MUMPS СУБД. Практика применения и опыт программирования.pdf
Скачиваний:
0
Добавлен:
07.09.2026
Размер:
2 Мб
Скачать
1.4. ЧИСЛА И СТРОКИ 71
ходимости. Арифметические и строковые операции могут выполняться над значениями любых переменных и над результатами любых выраже­ний.
Дополнительно к порядку приведения чисел действует правило полу­чения булевского значения для различных условий и постусловий. Для получения булевского значения, равного или 0 или 1, система приводит аргумент сначала к числу, потом сравнивает его с нулем. Если получи­лось число равное 0, то результат 0, иначе (при любом другом) результат равен 1. В частности, операция логического отрицания приводит свой аргумент к булевской величине явно. Неявно к ней приводят операции условных операторов, постусловий, соответствия шаблону, вычисление значения бита.
Что интересно, двойное применение оператора логического отрица­ния к аргументу приводит арумент не к инвертированному, а к прямому булевскому виду. Первый оператор приводит к булевскому, но инверти­рованному, второй еще раз инвертирует для получения прямого:
USER>w ’’12 1 USER>w ’’"string" 0 USER>w ’’"12 с половиной" 1
Такая операция двойного логического отрицания используется как операция булевского нормирования - в силу того, что оператор отрица­ния возвращает строго предопределенные значения, нормирование также получает строго определенные значения - 0 или 1, которые можно ис­пользовать и в арифметических и в строковых операциях.
Прямым эквивалентом операции приведения к булевской величине является операция явного приведения к числу и сравнение с нулем:
USER>w +12’=0 1 USER>w +"string"’=0 0 USER>w +"12 с половиной"’=0 1
В отличие от других языков, в языке MUMPS число не всегда явля­ется самостоятельной лексемой, рассматриваемой только как синтакси­ческое число. Интерпретатор не только использует последовательности
72 ГЛАВА 1. СРЕДА ИСПОЛНЕНИЯ
цифр по контексту операции, но и анализирует исходный код по контек­сту команды и операции. В частности, последовательность цифр являет­ся синтаксически корректным именем метки, например при выполнении команд
goto 123 do 123
лексема 123 означает не число как значение, а допустимое имя метки.
Что интересно, допускается также вариант очень похожий на сложе-
ние:
goto 123+4
В этом случае числом здесь является лексема 4, означающая сме­щение от метки с именем 123, а знак + синтаксически означает запись смещения относительно метки. Так, в коде
do 123+4+5
лексемы 4 и 5 вычисляются как числа и программа вызывает подпро­грамму с метки 123 со смещением 9 (сумма 4 и 5).
В большинстве случаев, конечно, разработчики на MUMPS не стре­мятся злоупотреблять особенностями синтаксиса, чтобы не сделать код совершенно нечитабельным.
Другим случаем использования последовательностей цифр является задание числа повторов для шаблонов, например
USER>w "a12"?1.2A1N1E 1
Здесь спецификацией шаблона является полная последовательность символов "1.2A1N1E", причем последовательность "1.2" не означает число
1.2, а указывает число повторов (означает от 1 до 2 включительно).

1.5 Функции

Стандарт языка MUMPS предусматривает поддержку определенного на­бора системных функций. Системные функции - это встроенные в яд­ро интерпретатора операции обращения к данным, по преобразованию строк, или выполняющие служебные действия.
1.5. ФУНКЦИИ 73
Синтаксически системные функции задаются именем, перед которым указывается один символ $. Также как имена команд, имена систем­ных функций используются в любом регистре и могут сокращаться до аббревиатуры, за редким исключением это первая буква имени.
Если после имени функции не ставится пара скобок с аргументами, то синтаксически это соответствует системным переменным, например если пишется функция $PIECE в сокращенной форме ($P) без скобок, это воспринимается транслятором как системная переменная. В частно­сти, системная переменная $P действительно существует, ее полное имя $PRINCIPAL.
В действительности многие системные переменные очень похожи на функции без аргументов. Есть системные переменные, которые не из­меняются все время жизни для всех процессов, например $SYSTEM. Есть системные переменные, зависящие от процесса, но не изменяющие значения, например $JOB. При этом есть системные переменные, ко­торые могут изменять свое значение регулярно, например $HOROLOG. Такие переменные уже большинством программистов воспринимаются как функции, вычисляющие значение независимо от аргумента. Но в языке MUMPS исторически принято различать переменные и функции, и если функция не требует аргументов, то это переменная.
Более того, в терминологии языка закрепилось и различие между пользовательскими функциями и пользовательскими переменными. Фак­тически же между ними нет разницы, пользовательские переменные это то же самое что и пользовательские функции, если их можно вызвать без аргументов и без скобок.
В круглых скобках после имени функции через запятую перечис­ляются аргументы функции. В отношении аргументов для стандартных системных функций в языке есть соглашение что если аргумент не ука­зывается, то его позиция не выделяется. Например, нельзя написать опускание аргумента так:
$piece(str,,3)
Часть функций допускает опускание аргументов с конца, в частности вместо
$piece(str,"~",)
нужно писать
$piece(str,"~")
74 ГЛАВА 1. СРЕДА ИСПОЛНЕНИЯ
Некоторые реализации MUMPS систем поддерживают расширенные нестандартные системные функции, допускающие опускание аргумента, в частности, функция $LB() при опускании аргумента конструирует в списке в этой позиции специальный элемент списка с зарезервирован­ным неопределенным значением.
Все системные функции определены так, что они возвращают неко­торое значение, поэтому, даже если результат возврата не важен, его в любом случае необходимо использовать, по крайней мере присвоить вре­менной переменной или использовать результат как аргумент команды if.
Весь набор системных функций можно разделить на несколько групп по назначению функций:
1. Функции доступа к данным
2. Функции имен
3. Строковые функции
4. Служебные функции
Функции доступа к данным возвращают информацию о наличии зна­чения переменных и наличии их индексов. К таким относятся функции:
1. $DATA - вернуть индикатор существования переменной и ее ин­дексов.
2. $GET - вернуть значение переменной или значение по умолчанию если переменная не существует.
3. $ORDER - вернуть следующее значение индекса на том же уровне.
4. $QUERY - вернуть следующее имя переменной независимо от уров­ня индексов.

1.5.1 $DATA

Функция $DATA ($D) принимает в аргументе имя переменной, локаль­ной или глобальной, и возвращает одно из следующих значений:
1. 0 - ни эта переменная, ни ее дочерние не существуют
2. 1 - переменная существует, но дочерних не имеет
1.5. ФУНКЦИИ 75
3. 10 - переменная не существует, но дочерние (по меньшей мере один дочерний элемент) есть
4. 11 - и эта переменная и ее дочерние (по меньшей мере один) суще­ствуют
Возвращаемое значение строго определено стандартом и может быть использовано в арифметических операциях, что разработчики и исполь­зуют при необходимости. В частности, проверка на то что имя существу­ет независимо от существования дочерних:
$DATA(varname)#2
и проверка существования дочерних независимо от существования самой переменной:
$DATA(varname)\10
Функция $DATA в некоторых реализациях MUMPS пожет быть при­менена также к структурным системным переменным. Например, в этом случае можно проверить существование процесса:
$DATA(^$JOB(jobnumber))
Но в этом случае необходимо сверить с документацией на использу­емую MUMPS систему, поддерживается ли такой функционал.
У функции $DATA имеется побочный эффект - при обращении к глобальной переменной независимо от существования или несущество­вания ее или ее дочерних переменных функция взводит индикатор го­лой ссылки в значение, равное имени переменной, к которой обратилась. Эта особенность также может быть использована разработчиками, если необходимо присвоить индикатору голой ссылки определенное имя, но используемая реализация MUMPS системы или ее версия не поддержи­вает прямое присваивание системной переменной $ZREFERENCE.
Существуют реализации MUMPS систем, поддерживающие нестан­дартную двухаргументную форму функции $DATA - в качестве второго аргумента необходимо указать имя переменной. В этом случае если пере­менная из первого аргумента имеет значение, то функция одновременно присвоит это значение второй переменной:
USER>s a=123
USER>w $d(a,value) 1
76 ГЛАВА 1. СРЕДА ИСПОЛНЕНИЯ
USER>w
a=123 value=123
Этот функционал является нестандартным и поведение индикатора голой ссылки в случае использования во втором аргументе глобальной переменной необходимо сверять с документацией на используемую вер­сию MUMPS системы. Наиболее ожидаемым поведением в этом случае может быть присваивание второй переменной после получения индика­тора существования и присваивание индикатору голой ссылки именно второго имени.

1.5.2 $GET

Функция $GET ($G) возвращает значение для указанной переменной. Функция имеет две формы вызова - одноаргументную и двухаргумент­ную:
$GET(varname) $GET(varname,defvalue)
Если переменная с заданным именем имеет значение, то оно возвра­щается независимо от формы функции и ее второго аргумента. Если эта переменная не имеет значения, то в первом случае для нее возвращается пустая строка, а во втором случае - значение указанное как значение по умолчанию, defvalue.
Также как и функция $DATA, функция $GET имеет побочный эф­фект - при обращении к глобальной переменной вне зависимости от ее существования функция $GET взводит индикатор голой ссылки в зна­чение, равное имени глобальной переменной.
Традиционным применением функции $GET является код, не исполь­зующий предварительную инициализацию
f i=1:1:12 s total=$get(total)+i
не проверяющий существование переменной
f i=1:1:12 s total=$get(total)+$get(^gbl(i))
или обращающийся к параметрам функции которые могут получить неопре­деленное значение
func(param)
s param=$get(param,0) ...
1.5. ФУНКЦИИ 77

1.5.3 $ORDER

Функция $ORDER ($O) возвращает следующее значение индекса в по­рядке их существования у переменной или пустую строку если следую­щего индекса не существует.
Для функции необходимо передать локальное или глобальное имя, указав нужное число индексов. Функция будет возвращать следующий индекс (если он существует) на уровне последнего указанного индекса.
USER>s a(1)=1
USER>s a(2)=1
USER>s a(3)=1
USER>s a(4)=1
USER>s a(2,1)=1
USER>s a(2,2)=1
USER>s a(3,1)=1
USER>s a(4,1)=1
USER>s n=""
USER>f s n=$o(a(n)) q:n="" w n,! 1 2 3 4
Функция возвращает значение индекса в обоих вариантах - если су­ществует такая переменная или если существуют ее дочерние перемен­ные. Нужно понимать, что если функция $ORDER вернула следующий индекс, то этот индекс означает следующий в понимании переменной как дерева, но само значение не обязано существовать.
У функции $ORDER существует две формы - одноаргументная и двухаргументная. Одноаргументная форма возвращает следующий ин­декс в порядке возрастания. Двухаргументная форма принимает вторым аргументом индикатор направления, который может принимать только одно из следующих значений:
1. 1 - перечислить по возрастанию
78 ГЛАВА 1. СРЕДА ИСПОЛНЕНИЯ
2. -1 - перечислить по убыванию
Любые другие значения в настоящее время зарезервированы для бу-
дущего использования и их использование должно генерировать ошибку.
Существуют реализации MUMPS систем, которые поддерживают при­менение функции $ORDER также и к структурной системной перемен­ной. Этот функционал относится к нестандартному, поэтому такую воз­можность нужно проверить в документации. Если поддерживается, то, например, можно перечислить имеющиеся в MUMPS системе процессы
s job="" f s job=$o(^$J(job)) q:job="" w job,!
или открытые устройства
s dev="" f s dev=$o(^$D(dev)) q:dev="" w dev,!
Существуют реализации MUMPS систем, поддерживающие нестан­дартную трехаргументную форму функции $ORDER. В этом случае в качестве третьего аргумента указывается переменная, которой необхо­димо присвоить значение переменной если оно существовало. Если зна­чения с точно таким именем не существовало, то возвращается только значение индекса, но присваивание не производится. Например, такой функционал поддерживается Cach´e:
USER>s a(1)=1,a(2,1)=21,a(3)=3,a(4)=4
USER>s n="" f s n=$o(a(n),1,v) q:n="" w v,! 1 1 3 4
USER>s n="" f s n=$o(a(n),1,v) q:n="" w n,! 1 2 3 4
Здесь видно, что для индекса a(2) его значение возвращается, но присваивание не выполняется.
В отношении функции $ORDER побочный эффект взведения инди­катора голой ссылки в случае обращения к глобалу определен более сложно - если следующее значение индекса существует, то индикатор голой ссылки взводится в это значение. Если не существует, то в то
1.5. ФУНКЦИИ 79
имя, к которому обратились первоначально. Таким образом, побочный результат зависит от того, существуют данные или нет, в отличие от функций $DATA и $GET.
Первоначально в стандарте языка MUMPS функции $ORDER не бы­ло, она появилась только в 1984-м году, и в этой редакции была принята одноаргументная форма. Двухаргументная форма, с возможностью про­хода по убыванию, появилась лишь в стандарте языка 1995-го года. В настоящее время все современные реализации MUMPS систем поддер­живают эту функцию в полной мере.
В техническом отношении реализация функции $ORDER, в особен­ности реализация прохода назад, или в направлении обратном компрес­сии ключей, относится к наиболее сложным для выполнения на блоках B* - деревьев. Существуют также СУБД, в которых для аналогичных к функции $ORDER операций в документации делаются отдельные ого­ворки о необходимости применения опций asc или desc для индексов во избежание существенного падения производительности, включая ре­комендацию строить оба варианта индексов для случая если выборка с сортировкой по индексу критична для прикладной системы.
Современные MUMPS системы выполняют функцию $ORDER как в прямом направлении сортировки, так и в обратном, с примерно сопо­ставимой производительностью. Насколько показывает опыт применения $ORDER в различных MUMPS системах, если падение производитель­ности и можно определить, то оно ни разу не оказалось заметным либо существенным.

1.5.4 $NEXT

До введения в стандарт языка функции $ORDER в языке использова­лась функция $NEXT, в одноаргументной форме. В стандарте 1990-го года эта функция была объявлена нерекомендованной к применению, и в стандарте 1995-го года отсутствует. В настоящее время существуют ре­ализации MUMPS систем, которые не поддерживают функцию $NEXT и которые поддерживают для совместимости.
Функция $NEXT может вернуть следующее значение индекса толь­ко по возрастанию и в случае, если следующее значение индекса не существует, то функция возвращает значение -1.
Для числовых индексов такое поведение неудобно тем, что для слу­чая если функция вернула значение -1 необходимо различать, является ли это значение следующим существующим или это индикатор несуще­ствования, с помощью функции $DATA.
80 ГЛАВА 1. СРЕДА ИСПОЛНЕНИЯ
Последующее определение функции $ORDER уже учитывало тот факт, что в MUMPS системах по умолчанию значения индексов рав­ные пустой строке (пустые индексы) не разрешены. В случае же, если в настройках MUMPS системы пустые индексы разрешены, то такую операцию по дополнительной проверке также необходимо выполнять. Большинство прикладных систем, как существующих так и разраба­тываемых, опираются на соглашение о настройках по умолчанию и о неиспользовании пустых индексов.

1.5.5 $QUERY

Функция $QUERY ($Q) принимает имя переменной и возвращает сле­дующее существующее для этой переменной имя в порядке сортировки.
Особенность функции в том, что ей можно указать в аргументе имя, но нельзя принять само имя как значение. Поэтому функция возвращает строку с именем переменной. В случае если следующего имени функция не нашла, она возвращает пустую строку.
Такое соглашение о возврате значения приводит к использованию косвенности имени при итерациях. Если начальное значение имени мо­жет быть указано явно как имя переменной, то последующая итерация уже должна использовать строку с именем. Чтобы перевести строку в само имя, используется косвенность. Примерный типовой код примене­ния функции $QUERY:
USER>s a(1)=1,a(2,2)=22,a(3,3,3)=333,a(4)=4
USER>s name=$na(a)
USER>f s name=$q(@name) q:name="" w name,! a(1) a(2,2) a(3,3,3) a(4)
В отличие от функции $ORDER функция $QUERY не рассматривает переменную как дерево, а использует как набор сортированных записей вида ключ - значение, но ключ может быть произвольным и составным.
Если функция $QUERY используется в одноаргументной форме, то она перечисляет переменную в направлении возрастания индексов в по­рядке их сортировки.
Функция $QUERY поддерживает так же, как и функция $ORDER, двухаргументную форму. Второй аргумент задает направление перечис­ления имен - если аргумент вычислен как значение 1, то функция пе-