Освоение MUMPS: основные операторы
Автор Райан Хейслер
Если вы еще не видели наше введение в MUMPS, также известное как M, пожалуйста, ознакомьтесь с ним здесь. В нем есть ссылки на ресурсы, которые мы использовали для изучения MUMPS, и на другие наши публикации о MUMPS. Мы в значительной степени полагались на документацию и эту презентацию MUMPS, чтобы изучить основные функции языка.
В M есть большинство операторов, которые мы привыкли ожидать от других языков программирования, а также несколько интересных, которые дают M преимущество. Многие операторы, с которыми вы знакомы, имеют разные символы в M, поэтому мы упомянем их, прежде чем углубляться в детали более необычных.
Примечание о примерах кода: мы рассмотрели такие команды, как write
, read
, do
и set
, в предыдущем посте. В этом посте мы использовали полное имя каждой команды во всех примерах. Однако соглашение M, как мы узнали, заключается в использовании сокращенной формы для команд. Этот пост и все последующие посты будут использовать сокращенную форму команд в примерах кода, например. w
вместо write
. Мы также добавили ,!
(перевод строки) в конце каждого write
в примерах кода, чтобы при их запуске каждый вывод был на отдельной строке.
Что отличается, а что совпадает?
Как и следовало ожидать, +
используется для сложения, -
— для вычитания, *
и /
— для умножения и деления, а **
— для возведения в степень. >
, <
, >=
и <=
ведут себя так же, как и в других местах. &
представляет логическое AND
.
Интересно, что в математике MUMPS строки, начинающиеся с числовых символов, обрабатываются как числа, даже если они содержат буквы, а строки, начинающиеся с нечисловых символов, обрабатываются как строки, даже если они содержат числа. Нечисловые строки всегда равны 0. Следующий код дает пример. Результат записывается в комментарии после каждой строки.
Официально M считает точку с запятой командой, но мы подумали, что это уместно обсудить здесь. ;
обозначает комментарий, поэтому M будет игнорировать все, что следует за ним. Обратите внимание, что он не обязателен в конце каждой строки. Поскольку пустые строки в M не допускаются, мы используем ;
для пустых строк, чтобы оставить себе немного пробела и сделать наш код более читаемым.
Точно так же в документах не упоминается ,!
, который используется после команды write
и ее аргумента для добавления к выходным данным символа новой строки. Например: write "Hello",!
выводит строку «Hello», за которой следует новая строка. Мы стараемся иметь привычку выполнять каждую команду write
с помощью ,!
.
Другие операторы могут выглядеть незнакомыми в M. #
— это символ «модуля», ’
— это символ логического NOT
, а !
— логическое OR
. В зависимости от контекста =
используется как для присваивания, так и для сравнения на равенство — в M нет ==
.
Наконец, _
предназначен для конкатенации строк. M будет преобразовывать числа в строки во время конкатенации, поэтому write 1_". "_12_"eggs"
выведет 1. 12 eggs
.
Оператор `\`
Ранее я упростил: /
для десятичного деления. При необходимости он вернет десятичные результаты, поэтому 1/4
равно 0.25
. С другой стороны, \
выполняет целочисленное деление. Вы можете передать ему десятичные числа, но оно всегда будет округляться до ближайшего целого числа (ведет себя как функция пола).
`[`
operator
Что-то, что мы в Menlo нашли полезным для нескольких языков, — это встроенный способ проверки, содержит ли строка подстроку. Это то, что [
делает для нас в M. Левый операнд — это строка для поиска, а правый операнд — подстрока.
Операторы `]` и `]]`
Официальная документация называет ]
оператором «следует», а ]]
— оператором «сортировки после», но не объясняет, что означают эти слова. Если мы попробуем их, мы увидим, что 4]3
и 4]]3
оцениваются как True, так в чем же разница?
]
будет оцениваться как истина, если левый операнд следует за правым операндом в последовательности кодирования символов M. По умолчанию это последовательность ASCII, поэтому таблица ASCII может помочь вам определить, каким будет результат сравнения с ]
. M также имеет встроенную функцию $ASCII
, которая сообщит вам значение ASCII переданного ей символа. По сути, B]A
— это сокращение от выражения $ASCII("B")>$ASCII("A")
. Вот еще несколько примеров
* Menlo использует реализацию Intersystems Caché M.
]]
, с другой стороны, оценивает, сортируется ли левый операнд после правого операнда в «последовательности сортировки нижнего индекса» ¹. Последовательность сопоставления индексов — это то, что M использует для сортировки индексов (дочерних узлов) массива. Возможно, вы использовали функцию $ORDER
(описанную в другом посте). $ORDER
возвращает следующий узел массива, используя последовательность сортировки нижнего индекса. Эта последовательность немного отличается от ASCII тем, что цифры идут первыми. После этого следуют значения ASCII. Некоторые примеры:
Порядок действий
За исключением круглых скобок, M оценивает операторы в строгом порядке слева направо. Это может привести к неожиданному поведению, если вы привыкли к языкам, которые определяют свой собственный порядок предпочтения для каждого оператора. Вот несколько математических примеров:
Операция слева направо особенно сложна с логическими операторами. В следующих примерах мы будем использовать 1
для представления «истина» и 0
для представления «ложь». Помните, что каждая строка заканчивается на ,!
. Восклицательный знак в символе новой строки не имеет отношения к логическому OR
.
M не использует Вычисление короткого замыкания при оценке логических операторов. В некоторых языках, если первое выражение логического AND
оценивается как ложное, второе выражение не будет оцениваться, поскольку все логическое выражение должно быть ложным. В M это не так. Оцениваются обе части логического выражения.
Это важно помнить, если вы решите использовать тег с побочными эффектами в качестве выражения, следующего за &
. Тег всегда будет выполняться, и всегда будут возникать побочные эффекты, как в следующем примере.
Этот код выводит 2 строки: «это побочный эффект» и «это напечатает». Несмотря на то, что первое выражение, которое вычисляет &
, ложно, оно все равно вызывает evalWithSideEffect
. В Menlo мы стараемся не писать подобный код, потому что некоторые языки обрабатывают оценку короткого замыкания иначе, чем другие.
Операторы M могут показаться странными программистам, привыкшим к более современным языкам, но при правильном использовании они могут делать все, что нам от них нужно. Они даже включают несколько удобных инструментов, которых нет в других языках, таких как \
и [
. В этом посте мы не упомянули один из операторов M: ?
, оператор сопоставления с образцом. Новичкам это может быть сложно понять, но это чрезвычайно мощно. Следите за нашим следующим постом о ?
и о том, почему вы не пропустите регулярные выражения при использовании M.
Сноски:
[1] — Определение последовательности сопоставления индексов и обсуждение ]
и ]]
см. на этой странице. Это характерно для реализации MUMPS в GT.M, но справедливо и для Caché.