Ed de Moel

WindMills

M Computing, Volume 6, number 3, August 1998, pages 27-29

Two Steps Closer to Objects in M[UMPS]
by Ed de Moel

During the last week of June this year, the MDC convened a "special meeting". The "special" character of this meeting had to do with the desire to finalize the work on drafting the next version of the ANSI standard for M[UMPS]. At this meeting, the votes were limited to only those documents that were at that time at a status that was high enough to have a fair chance of ending up in this next issue of the standard.

The documents that are discussed below are additions to "X11.1", the M[UMPS] language standard. I hope to be able to report on features for "X11.7", the new language called Omega, in future columns.

User Defined ssvns

One of the documents that passed as an MDC Type A Extension at this meeting was the one titled "User Defined ssvns". The "ssvn", or "structured system variable", is an entity in the M[UMPS] language that looks like a global variable, and behaves like a property list. For instance,

^$G("^ABC","CHARACTER")

(with ^$G being the abbreviation for ^$GLOBAL) is a reference that identifies the "character set" property for the global variable that is named as the first "subscript".

The "ssvns" that were introduced in the 1995 version of the ANSI standard for M[UMPS] are ^$Character, ^$Device, ^$Global, ^$Job ^$Library, ^$Lock, ^$Routine and ^$System. The MWAPI standard added ^$Event and ^$Window.

Each of these variables can be used to inspect or redefine properties of the system structure to which they relate. As a side-effect of being accessed through a M[UMPS] oriented syntax, it is possible to apply the function $ORDER using the first subscript only, and thus find out which "objects" are the components of the structure in question:

        Set r=""
        For  Set r=$Order(^$R(r)) ...

will allow the M[UMPS] programmer to loop through the routine directory. Even though the value of $Data(^$R("name")) will typically be either 0 (when there is no routine named "name"), or 10 (when there is such a routine, and its properties will be accessible using references with more subscripts), the function $ORDER will still find all available routines.

So far, the use of ssvns has remained mostly limited by the amount of features that the implementors have made available. The introduction of ^$Job made the capability to

Kill ^$Job(number)

an obvious candidate for implementation (most likely restricted to users with sufficient privileges), but, so far, I don't know of any implementation that did make this feature available.

In this light, the addition of "user defined ssvns" may seem fairly academic. However, the capability to

        Set prop="Name"
        Set id= ... ; unique identifier
        Set ^$MyCust(id,prop)=x

opens the possibility to create logic "behind the scenes" that would not only assign a new value to the "name" property of my customer database, and also update any cross-references that are based on that name.

In other words, the code that is invoked "behind the scenes" to execute the SET command in this context would be the class library function that replaces the value of the "name" property, and that will take care of all "internal bookkeeping" that is inherent to such modifications.

What remains implementation-specific is the method that establishes the name of the routine that will be invoked when an action is undertaken that involves a "user defined ssvn". What has been standardized is the list of labels within that routine that will be called for the various actions:

ContextLabel
$DATA%DATA
$GET%GET
$ORDER%ORDER
$QUERY%QUERY
KILL%KILL
KSUBSCRIPT%KSUBSCRIPT
KVALUE%KVALUE
MERGE%MERGE
%MERGES
SET%SET
Evaluation in an expression%VALUE

The entry point %SET is also called when a value is assigned through other commands (such as READ and MERGE).

In the context of MERGE, the entry point MERGE is called when the reference to the ssvn occurs on the right hand side of the equal sign, and the entry point MERGES is called when the reference occurs on the left hand side.

So,

Set x=^$MyCust(id,prop)

will basically be executed as

Set x=$$%VALUE^...(id,prop)

and

Set ^$MyCust(id,prop)=x

will be executed as

Do %SET^...(name,x)

where the value of name is the canonic form of the name of the ssvn in question (with all values in its subscripts resolved).

This new tool offers an important step into the direction of support for object oriented programming. True encapsulation, however, is not yet part of this extension. It would be necessary to be able to protect certain global variables from any access other than through their "class libraries" and hopefully such features will be added in the not too distant future. Nonetheless, the addition to the standard of the basic mechanism for defining these class libraries is certainly a step that needs to be taken as well!

Object Usage

Another document that was approved as an MDC Type A extension at this meeting is entititled "Object Usage".

This document introduces a number of new concepts into the language of M[UMPS]. The first new concept is the notion that there are now two data types. The familiar string remains (of course) as the most obvious and default data type, the new data type is the "reference to an object". Other programming environments would call this data type "pointer to an object" or "handle for an object".

In order to find out what the data type is of an entity in M[UMPS], a new function is introduced:

$TYPE(expression-atom)

returns a string that identifies the data type of the expression atom that is passed as a parameter to this function. This string-value is currently either "MVAL" to identify the traditional string, or "OBJECT" to identify a reference to an object.

In order to create references to objects, a new command is introduced:

ASSIGN object=expression

In the context of this command, the entity on the right hand side of the equal sign must return a value that is a reference to an object, and the entity on the right hand side will usually be the name of a local variable.

The main difference between

SET variable=value

and

ASSIGN variable=value

is that the SET command will "coerce" the value on the right hand side to become a value of the traditional data type "string", whereas the ASSIGN command will perform no data type coercion, and will insist on finding a reference to an object on the right hand side of the equal sign.

In the context of the SET command, the term "data type coercion" is introduced. This term means that, if the data type of the value on the right hand side of the equal sign happens to be a reference to an object, something special will happen: the system will look for a "default property" and return the value of that default property. If the value of this "default property" once again is a reference to an object, the coercion process will re-iterate, until a value of the traditional string data type can be returned. (When, in this context, an object is encountered that does not have a "default property", an error will be reported.)

In order to check whether two references to objects are identical, a new operator is introduced. The expression

A==B

(two equal signs) is true if and only if both operands are references to objects, and both operands refer to the same object.

Finally, references to properties and methods are made accessible in a fashion that will be very familiar to those who have worked with objects in other languages: in a reference to a property or method, a period is used to separate the various components in the reference. For instance, assuming that the value of local variable Word is a reference to an instance of a popular word processor program:

Set Word.Application.Visible=1

would redefine the value of the property "Visible" of the object called "Application" within the object called "Word" (with MS-WordTM, this property controls the visibility of the window that displays the application; 1 is visible, 0 is invisible).

These additions are important building blocks that will make working with objects a lot more straightforward in M[UMPS]. Of course, a lot of work still remains to be done. The standardization of the ASSIGN command may be an important first step, but any functions that return references to objects still remain implementation specific.


Jacquard Systems ResearchEd de Moel is past chairman of the MDC and works with Jacquard Systems Research. His experience includes developing software for research in medicine and physics. Over the past ten years, Ed's has mostly focused on the production of tools for data management and analysis, and tools for the support of day-to-day operation of medical systems. Ed can be reached by e-mail.