M Web Magazine 007 (June 5, 1998 - September 4, 1998)

M Tutorial (part 3/5)

 

The only difference between this program and GLB008 is that we are not outputting ARR(SUB1). One question our reviewers raised was why SUB2 and SUB3 have been initialized only once with a null value when in reality they iterate many times. Since null is returned by $ORDER either when there are no more entries or to start from the beginning there is no need to reinitialize these subscripts as they are already set to null.

The structures we created up to now followed a very systematic sequence. Let’s change this. In the structure listed above, we don’t know which subscripts contain data and those that do not.

GLB011Þ;Program demonstrates arrays and globals - Chris Bonnici - Mar 1998
Þ;M Web Magazine @ http://geocities.datacellar.net/SiliconValley/7041/mwm.html
Þ;You are using this program at your own risk
Þ;
ÞN ARR,I,SUB1,SUB2,SUB3
ÞF I=1:1:5 D
Þ.I $R(10)#2=0 S ARR(I)="LEVEL 1:"_I
Þ.I $R(10)#2=0 S ARR(I,"A")="LEVEL 2:"_I
Þ.I $R(10)#2=0 S ARR(I,"A","DATA")="LEVEL 3:"_I
Þ.Q
Þ; $DATA returns:
Þ; 0 if it is not defined
Þ; 1 if it is defined, has data but has no descendants
Þ; 10 if it is defined, has no data but has descendants
Þ; 11 if it is defined, has data and has descendants
ÞW #
ÞS (SUB1,SUB2,SUB3)=""
10ÞS SUB1=$O(ARR(SUB1)) Q:SUB1=""
Þ; check for data
ÞI $D(ARR(SUB1))#10=1 W !,SUB1," = ",ARR(SUB1)
20ÞS SUB2=$O(ARR(SUB1,SUB2)) G:SUB2="" 10
ÞI $D(ARR(SUB1,SUB2))#10=1 W !,?20,SUB2," = ",ARR(SUB1,SUB2)
30ÞS SUB3=$O(ARR(SUB1,SUB2,SUB3)) G:SUB3="" 20
ÞI $D(ARR(SUB1,SUB2,SUB3))#10=1 W !,?40,SUB3," = ",ARR(SUB1,SUB2,SUB3)
ÞW !
ÞG 30

Run this program a few times. Using the random function we can’t really predict what will contain data and what will simply be a subscript enroute to data. Last time we formally introduced the $DATA intrinsic function. Today we take a closer look at what it does.

Returned Value

Defined

Data

Descendants

0

No

No

No

1

Yes

Yes

No

10

Yes

No

Yes

11

Yes

Yes

Yes

In GLB011 we wanted to know whether there was data at the node we were processing. Rather than placing multiple comparisons in out code, we took #10 (modulus 10) $D’s return.

Returned Value

Returned Value # 10

Defined

Data

Descendants

0

0

No

No

No

1

1

Yes

Yes

No

10

0

Yes

No

Yes

11

1

Yes

Yes

Yes

GLB012Þ;Program demonstrates arrays and globals - Chris Bonnici - Mar 1998
Þ;M Web Magazine @ http://geocities.datacellar.net/SiliconValley/7041/mwm.html
Þ;You are using this program at your own risk
Þ;
ÞN ARR,I,SUB1,SUB2,SUB3
ÞF I=1:1:5 D
Þ.I $R(10)#2=0 S ARR(I)="LEVEL 1:"_I
Þ.I $R(10)#2=0 S ARR(I,"A")="LEVEL 2:"_I
Þ.I $R(10)#2=0 S ARR(I,"A","DATA")="LEVEL 3:"_I
Þ.Q
ÞW #
ÞS (SUB1,SUB2,SUB3)=""
10ÞS SUB1=$O(ARR(SUB1)) Q:SUB1=""
ÞW !,SUB1," = ",$G(ARR(SUB1),"<na>")
20ÞS SUB2=$O(ARR(SUB1,SUB2)) G:SUB2="" 10
ÞW !,?20,SUB2," = ",$G(ARR(SUB1,SUB2),"<na>")
30ÞS SUB3=$O(ARR(SUB1,SUB2,SUB3)) G:SUB3="" 20
ÞW !,?40,SUB3," = ",$G(ARR(SUB1,SUB2,SUB3),"<na>")
ÞW !
ÞG 30

GLB012 uses the $GET function to test for data within the global. If it exists the contents are displayed, otherwise the phase <na> will be outputted.

While we have used the term array, it should be pointed out that this must not be looked upon as an array in other languages. It is far more flexible and dynamic. If you are familiar with the Windows 95/NT registry you will observe that it follows a very similar structure to how this data store is organised.

 

The Global.

In the tutorial page (at the time called Teach You, Teach Me) of MWM001 (way back in 1996) we said "To run the program, type, at the command line, DO ^SimpInt. (observe the ^ before SimpInt--it is an indication that the routine is saved on secondary storage, your hard disk)."

All the arrays we created previously were located in memory, meaning that once we leave MSM, nothing remains. In order to store them within the database, precede the name using the ^ symbol.

GLB013 ;Program demonstrates arrays and globals - Chris Bonnici - Mar 1998
;M Web Magazine @ http://geocities.datacellar.net/SiliconValley/7041/mwm.html
;You are using this program at your own risk
;
N I
F I=1:1:100 S ^DISK(I)=I,MEM(I)=I
F I=1:1:100 W !,^DISK(I),?40,MEM(I)
K
F I=1:1:100 W !,^DISK(I),?40,MEM(I)
Q

GLB013 demonstrates the creation of a global and an array. The KILL command normally kills all memory variables and so when trying to output the contents MEM the second time the program will stop with an <UNDEF>ined error.

mwmtryit.gif (2244 bytes) Modify GLB013 so that it sets up a multi-subscript global and array. Then exit MSM and try displaying their contents. (Hint use $D so as to avoid the <UNDEF> error).

 

KILL (revisited)

We already spoke about this command in MWM, but now we must delve into how it works with such structures. Firstly, if one wants to kill a global, simply insert the ^ symbol, e.g. K ^DISK.

There might be a situation in which you do not want to delete everything, but rather wish to erase a branch. In this case, you have to provide the relevant information.

Command What Gets erased
K ^GLB ^GLB("A")
^GLB("A",1,"U")
^GLB("B",1)
^GLB("B",1,"T")
^GLB("C",1)
K ^GLB("A") ^GLB("A")
^GLB("A",1,"U")
K ^GLB("A",1) ^GLB("A",1,"U")
K ^GLB("A",1,"U") ^GLB("A",1,"U")
K ^GLB("B") ^GLB("B",1)
^GLB("B",1,"T")
K ^GLB("B",1) ^GLB("B",1)
^GLB("B",1,"T")
K ^GLB("B",1,"T") ^GLB("B",1,"T")
K ^GLB("C") ^GLB("C",1)
K ^GLB("C",1) ^GLB("C",1)

Killing a branch will kill the data with it and all dependants.

 

Continued...

E&OE

1