Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
MUMPS СУБД. Практика применения и опыт программирования.pdf
Скачиваний:
0
Добавлен:
07.09.2026
Размер:
2 Мб
Скачать
1.10. ПЕРЕДАЧА ПАРАМЕТРОВ 131
Общие правила и возможности MUMPS систем по работе с огромны­ми данными на ограниченных ресурсах позволяют строить прикладные системы большого или, можно сказать, сверхбольшого объема.
Исполняемый байткод кешируется и используется по необходимости, и MUMPS системе обычно не требуется хранить в оперативной памя­ти весь объем кода приложения. Именно то обстоятельство, что сами рутины используются системой выполнения только по необходимости, и позволяет строить большие прикладные системы, объем программного кода которых может превосходить как объем оперативной памяти, так и размер адресуемого пространства памяти.
Для редактирования исходного текста рутин большинство современ­ных MUMPS систем имеют либо собственные средства редактирова­ния, либо могут быть использованы сторонние редакторы. Это могут быть графические оконные программы с MDI интерфейсом, консольные с псевдографикой включая доступ по telnet, или редакторы с WEB ин­терфейсом.
В случае если MUMPS система хранит исходный текст во внешних файлах, также могут быть использованы текстовые редакторы общего назначения, сохраняющие файлы в каталогах файловой системы или в каталогах FTP.
Поскольку исполняющие среды MUMPS систем являются система­ми позднего связывания, для компиляции рутин нет необходимости в каких-либо объявлениях, что другая рутина и тем более какая-то из ме­ток в ней существует. В отличие от языков компилирующего типа, где необходимо связывание имен подпрограмм с предварительным описани­ем их прототипа, в MUMPS это не требуется. В техническом отношении можно компилировать и импортировать рутины в любом порядке. Более того, можно выполнять рутину, если она обращается к еще несуществу­ющей рутине или метке, в этом случае исполняющая система просто сгенерирует соответствующую ошибку и управление будет передано на обработчик ошибок.

1.10 Передача параметров

При вызове метки как подпрограммы ей могут быть переданы парамет­ры. Для языка MUMPS можно передать параметры любой метке, код вызова транслируется совершенно независимо от вызываемого кода. Бу­дет ли на самом деле метка принимать параметры, это определяется разработчиком, описывающим метку.
Для вызывающей стороны параметры являются фактическими, для
132 ГЛАВА 1. СРЕДА ИСПОЛНЕНИЯ
вызываемой - формальными. Синтаксически формальные параметры сле­дуют в круглых скобках сразу после имени метки один за другим и описаны также как локальные переменные. При вызове подпрограммы формальные параметры сопоставляются фактическим. В контексте вы­полнения команды, следующей после метки, эти формальные параметры для этого контекста уже являются именами локальных переменных.
При этом, что интересно, ничто не мешает передать управление на строку, непосредственно следующую после строки с меткой, но в этом случае в контексте процесса не будет производиться сопоставление с формальными аргументами, и локальные переменные с теми же именами будут иметь иное значение и область видимости, то есть будет иной контекст этих переменных.
Стандарт языка определяет следующие варианты передачи фактиче­ских параметров:
1. По значению
2. По ссылке на локальную переменную
3. Опускание параметра
При этом формальные параметры могут быть либо именами локаль­ных переменных, либо опущены. В случае если параметр опущен, с ним ничего не сопоставляется, даже если было что-то передано. При ука­зании имени локальной переменой с ней сопоставляется соответственно способу передачи:
1. Локальная переменная принимает переданное значение.
2. Локальная переменная становится синонимом переменной, пере­данной по ссылке, и указывает на нее на ее уровне стека. Все операции с такой локальной переменной автоматически заменяют­ся на операции с переданной по ссылке переменной.
3. Локальная переменная принимает неопределенное значение.
При покидании уровня стека локальные переменные формальных па­раметров автоматически уничтожаются, а при передаче по ссылке все выполненные изменения с переданной переменной остаются.
Положим для примера, что имеется метка с параметрами:
label(a,b,c)
1.10. ПЕРЕДАЧА ПАРАМЕТРОВ 133
Для передачи параметра по значению нужно указать значение. Это может быть произвольное вычисляемое выражение. Перед вызовом вы­ражение вычисляется и значение передается.
do label(1+2,3+4,5+6) do label($h,$$func(789),^DATA)
Для передачи параметра по ссылке нужно указать точку с последу­ющим корневым именем передаваемой локальной переменной. Передача имени с индексом не допускается.
new local1 s local1(1)=$h new local2 s local1(2)=$h new local3 s local1(3)=$h do label(.local1,.local2,.local3)
Для вызова с опусканием параметра в его позици ничего не пишется:
do label(,,) do label(,) do label()
Если указано фактических параметров меньше чем метка принима­ет формальных, остальные формальные параметры также принимают неопределенное значение, как если бы было указано правильное число формальных параметров, но они были бы опущены.
Язык MUMPS отличает в фактическом параметре точку как специ­фикатор передачи по ссылке и точку как начало спецификации числа. Во втором случае передается параметр по значению.
Эти три способа передачи параметров являются стандартными и под­держиваются всеми современными реализациями MUMPS систем. При этом производители могут дополнительно поддерживать другие способы передачи параметров. В частности, системы MiniM и Cach´e поддержи­вают дополнительно 2 способа передачи параметров:
1. Автоматическое присваивание
2. Неопределенное количество параметров
Если используется передача параметра с автоматическим присваива­нием, то можно указать, какое значение в этом случае ему необходимо автоматически присвоить. Синтаксически указывается имя формального параметра, символ присваивания = и следующая за ним константа.
Пусть есть такая подпрограмма:
134 ГЛАВА 1. СРЕДА ИСПОЛНЕНИЯ
LABEL(v=123)
q v
Её можно вызвать как
$$LABEL() ; 1 $$LABEL(2) ; 2 $$LABEL(3,8) ; 3
Здесь в первом случае не передаётся фактический параметр и пере­менная v принимает неопределённое значение, которой автоматически присваивается значение 123.
Во втором случае переменной v присваивается значение 2 и значение, указанное как значение по умолчанию, игнорируется. В третьем случае переменной v значение сопоставляется, но для второго параметра метка ничего не принимает, поэтому MUMPS система в этом случае генери­рует ошибку.
Для того, чтобы метка могла принять неопределённое количество параметров, её последний формальный параметр специфицируется тремя точками:
LABEL(p1,params...)
В этом случае, при сопоставлении фактических параметров формаль­ным, игнорируется передача локальных переменных по ссылке и прини­маются только значения. Значение переменной, указанной тремя точка­ми (в примере params), принимает значение количества принятых фак­тических параметров, начиная с этой позиции. Принимаемые значения записываются в индексы переменной (в примере это params), начиная с индекса 1 и так далее в порядке следования. Если, начиная с этой позиции, не было фактических параметров, то формальная переменная принимает неопределённое значение. Если были пропуски фактических параметров, то соответствующие узлы формальной переменной не созда­ются и имеют неопределённое значение.
Например, пусть есть подпрограмма:
LABEL(params...)
zw params q params
Тогда при её вызове получаем:
1.11. НЕОПРЕДЕЛЕННЫЕ ЗНАЧЕНИЯ 135
USER>w $$LABEL^test(1) params=1 params(1)=1 1 USER>w $$LABEL^test(1,2) params=2 params(1)=1 params(2)=2 2 USER>w $$LABEL^test("we",2) params=2 params(1)="we" params(2)=2 2 USER>w $$LABEL^test(,2) params=2 params(2)=2 2
Разработчикам, конечно, следует учитывать, что автоматическое при­сваивание значений и приём неопределённого количества параметров не входят с стандарт языка MUMPS, что их использование может создать препятствие при переносе программ на другую MUMPS систему.
Для всех методов передачи параметров их правила применимы к пере­даче параметров подпрограмме, когда вызываемый код создает контекст, принадлежащий тому же самому процессу. В случае если параметры пе­редаются новому процессу, вызовом команды JOB, то передать можно лишь параметры по значению. При попытке передать параметр по ссылке команда JOB генерирует ошибку. Передаваемые значения MUMPS си­стемой передаются специальным внутренним образом новому процессу.

1.11 Неопределенные значения

В языке MUMPS локальная или глобальная переменная может иметь или не иметь присвоенное значение. Если значение не было присвоено, то такая переменная не хранится и имеет неопределенное значение. При попытке чтения ее значения процесс генерирует ошибку о неопределен­ном значении.
В других языках для использования переменной требуется ее объ­явить. В этом случае под переменную отводится определенная память. До явного ей присваивания или выполнения кода инициализации объек­та значение переменной по умолчанию может быть либо произвольным (мусор в памяти), либо проинициализировано заранее нулевыми значе-
136 ГЛАВА 1. СРЕДА ИСПОЛНЕНИЯ
ниями или указанной константой. В этом случае поведение определяет­ся настройками соответствующего транслятора и среды исполнения или соглашениями используемого языка. В частности, отдельные компиля­торы при трансляции отладочных версий инициализируют переменные, не инициализированные явно, нулевыми байтами, но при трансляции релизных версий уже этот код не вставляется и переменная содержит мусор.
В языке MUMPS в переменной не может быть произвольного значе­ния, поскольку до использования переменная не существует и не хранит­ся. Обращение к переменным производится по именам и по этому имени исполняющая система определяет есть ли такая переменная и какое у нее значение. При этом до присваивания переменной не существует, и переменные создаются при первом им присваивании.
Во многих случаях разработчикам необходимо определять, существу­ет ли переменная или нет и зачастую считать, что переменная имеет значение по умолчанию. Для этого в языке есть несколько функций, которые оперируют как определенными, так и неопределенными пере­менными. К ним относятся:
1. $DATA - возвращает индикатор, имеет ли переменная и ее дочер­ние переменные значения.
2. $GET - возвращает для переменной ее значение, или если она име­ет неопределенное значение то возвращает значение по умолчанию.
3. $INCREMENT - может увеличить на указанную величину неопре­деленную переменную, автоматически создав ее.
4. $LISTBUILD - может использовать неопределенную переменную для конструирования элемента списка, создав элемент имеющий неопределенное значение.
5. $BITLOGIC - расширенная функция, может использовать неопре­деленные переменные, считая их эквивалентом последовательности битовых нулей.
Функция $DATA возвращает индикатор существует ли указанная пе­ременная и существуют ли ее дочерние переменные, хотя бы одна. Функ­ция является основной для проверки переменной на неопределенность. Функция возвращает одновременно два индикатора в виде двух десятич­ных знаков, старший для дочерних и младший для самой переменной. Их можно выделить арифметическими операциями явно.
1.11. НЕОПРЕДЕЛЕННЫЕ ЗНАЧЕНИЯ 137
Проверка на то, что имя существует, независимо от существования
дочерних:
$DATA(varname)#2
и проверка существования дочерних, независимо от существования са­мой переменной:
$DATA(varname)\10
Функция $GET принимает имя переменной и возвращает ее значе­ние, если переменная была определена. Если переменная не была опре­делена, то функция возвращает пустую строку или указанное значение по умолчанию. Это поведение функции $GET определено стандартом и им пользуются разработчики, если необходимо использовать значе­ние по умолчанию для переменной, если ее значение может оказаться неопределенным и это не является ошибкой.
Что интересно, существовала такая реализация MUMPS системы (StarMUMPS), в которой любая неопределенная локальная переменная имела значение пустая строка и к любой из них можно было обратить­ся на чтение, не получив ошибку о неопределенном значении. Можно сказать, что создание такой отдельной реализации MUMPS системы действительно могло быть оправдано если необходимо было выполнять приложения, трактующие неопределенное значение именно как пустую строку. Хотя, со стороны интерпретатора, значение пустая строка ничем особым не отличается от любого другого значения.
Аналогичное реликтовое поведение в угоду прикладным системам до сих пор встречается и в СУБД отличных от MUMPS, в частности в SQL системе Oracle не выполняется различение между данными равными пустой строке и зарезервированным значением языка NULL. Вероятно, когда-то давно это решение съэкономило время при разработке какой­то из прикладных систем, и в настоящее время этот рудимент в целях совместимости до сих пор поддерживается, хотя большинство других SQL систем не содержат такой ошибки.
В современных MUMPS системах отношение к неопределенным зна­чениям строгое и четко регламентируется стандартом, либо строго опи­сано для расширенных функций. В тех случаях когда MUMPS система поддерживает опциональную настройку на нестандартное поведение в отношении неопределенных значений и пустых строк, тем не менее на­стройки по умолчанию всегда соответствуют стандартному поведению.
Функция $INCREMENT может увеличить на указанное значение (по умолчанию на 1) в том числе и неопределенную переменную. В этом
138 ГЛАВА 1. СРЕДА ИСПОЛНЕНИЯ
случае функция считает, что переменная имела значение, эквивалентное
0. Функция $LISTBUILD (расширенная, не входящая в стандарт) мо-
жет принимать в качестве параметра имя неопределенной переменной, в этом случае функция конструирует элемент списка в соответствующей позиции, имеющий неопределенное значение в смысле элемента списка. В какой-то степени эта функция также может быть использована, таким образом, как альтернатива функции $DATA.
Функция $BITLOGIC может оперировать именами неопределенных
переменных, в этом случае она считает что переменная эквивалентна битовой строке нулевой длины и при логических операциях условно до­полняет ее нулями до длины, необходимой для операции с другой пе­ременной. В частности, битовая операция ИЛИ с неопределенной пере­менной возвращает исходное значение.
Такое определение функции $BITLOGIC очень практично для выпол-
нения массовых битовых операций над строками битовых индексов, по­скольку отпадает необходимость использовать дополнительный код про­верки определено ли значение битовой строки в индексе.
Что интересно, в языке MUMPS неопределенные значения можно не
только проверять и использовать, но также передавать как параметры пользовательским функциям. Причем, таких способов даже два:
1. Передать по ссылке неопределенную локальную переменную.
2. Опустить фактический параметр чтобы формальный параметр при­нял неопределенное значение.
Если мы передает по ссылке локальную переменную, имеющую неопре-
деленное значение, например:
kill accum set result=$$calc(.accum) ...
calc(acc)
... q ret
то при сопоставлении фактического параметра формальному произво­дится конструирование локальной переменной (в данном случае acc) в виде синонима другой переменной, на другом уровне (в данном случае accum). Если исходная переменная имела неопределенное значение, то и формальный параметр будет иметь также неопределенное значение.
1.12. ШАБЛОНЫ 139
Второй способ - это опускание соответствующего фактического па­раметра вместо указания ссылки на переменную или вычисляемого зна­чения:
set result=$$calc() ...
calc(acc)
... q ret
В этом случае фактическому параметру также будет сопоставлено неопределенное значение.
При этом, в языке MUMPS нельзя вычислить значение, имеющее неопределенное значение, поскольку неопределенные значения могут иметь только переменные, если они не были присвоены. Но можно сделать так, чтобы переменная получила неопределенное значение, для этого ее необ­ходимо удалить:
s var="string" ; переменная var имеет значение kill var ; переменная var не имеет значения
либо применить команду new, побочно присваивающую переменной неопре­деленное значение, но только начиная с текущего уровня стека:
s var="string" ; переменная var имеет значение new var ; переменная var не имеет значения

1.12 Шаблоны

Шаблонами (pattern) в языке MUMPS называются правила, описываю­щие символы, входящие в строку, для проверки соответствует или нет строка такой последовательности.
Синтаксически оператор проверки по шаблону записывается так:
expr?pattern
Оператор возвращает значение 1 если строка соответствует шаблону и 0 если нет, причем к оператору можно применить отрицание оператора:
expr’?pattern
140 ГЛАВА 1. СРЕДА ИСПОЛНЕНИЯ
что эквивалентно отрицанию логического значения результата
’(expr?pattern)
С точки зрения синтаксиса, последовательность, описывающая шаб­лон оценивается транслятором MUMPS на этапе трансляции. При этом те же самые действия могут быть выполнены косвенно, если шаблон задать в виде значения вычисляемого выражения и использовать кос­венность шаблонов:
s pattern=... expr?@pattern
В этом случае оценивать шаблон MUMPS система будет на этапе выполнения кода.
Структурно шаблон представляет собой последовательность из одного или нескольких следующих подряд правил. Каждое из правил называ­ется атомарным шаблоном. Каждый из атомарных шаблонов состоит из указания числа повторов и одной из конструкций, что именно должно повторяться:
1. Код обозначающий принадлежность символа к группе символов.
2. Строка задающая последовательность символов явно.
3. Альтернатива, задающая перечисление атомарных шаблонов и озна­чающая операцию ИЛИ.
Рассмотрим каждое из этих определений более подробно. Для указания числа повторов можно указывать один из следующих
вариантов в виде комбинации из чисел:
count Точно указанное воличество. . Любое количество, включая ноль по-
второв.
min . Минимум min раз, максимум не
ограничен. . max Максимум max раз, начиная с нуля. min . max От min до max раз включительно.
Задание кода или класса символов производится указанием символа,
соответствующего классу символов: