User bio
404 bio not found
Member since Feb 2, 2016
Posts:
Replies:

The initial value of x=14 in the above ugly example happened because I ran it 3 times while I has debugging and modifying it.  As the comment says, I originally did quit y+3 but I had to change it to quit x+3 because the second execution of the quit statement got an <UNDEFINED> *y signal before it got to the <COMMAND> signal.

As mentioned above, ObjectScript was originally based on ANSI MUMPS.  However, that ANSI standard has been retired but I believe there still exists an ISO M language standard which is identical to the ANSI M[UMPS} standard.  ObjectScript still supports the ancient MUMPS/M standard but InterSystems no longer documents many of the legacy features of MUMPS/M.

There is no warning for a QUIT with expression statement in a FOR loop because it is possible that a QUIT expr could be legal in a FOR loop and that legality/illegality cannot not be detected until run-time.

Here is a messy example containing both legacy M and modern ObjectScript.  It contains a quit x+3 statement that is legal when first encountered and illegal when encountered the second time.

InterSystems supports ugly legacy M features so customers do not need to rewrite ancient code.  New code should not look like this ugly example as avoiding certain legacy features is strongly recommended.

USER>zp
foo(a,b) 
         for i=1:1:10 {
         set x=$$foo2(a)  zw x
         goto foo3
foo2(y)  
foo3     set z=a
         zw a,x,y,z
         zw "about to quit y+3"
         quit x+3
         }

USER>zw $$foo(5,9)                    
a=5
x=14
y=5
z=5
"about to quit y+3"
x=17
a=5
x=17
z=5
"about to quit y+3"

 quit x+3
   ^
<COMMAND>foo3+3^foo
USER 6f2>

Note that <COMMAND> was signaled 3 lines after label foo3 and then we interactively get a prompt from the debugger.

BTW: Evgeny might ask strange questions but the properties of legacy M/MUMPS can be much weirder.
 

Steven Hobbs · Nov 25, 2025 go to post

I am going to assume that local variable 'identifiers' contains an oref referencing either the %DynamicArray or the %DynamicObject class.  If the 'identifiers' value is an oref that references some other class then ignore everything else in this reply.

Let us assume 'identifiers' refers to a %DynamicArray object (although a reference to a %DynamicObject would involve a similar discussion.)  Each entry in the %DynamicArray is a JSON value.  Those entries have one the following types:  "null", "boolean", "number", "oref", "object", "array" or "string".  One these type strings will be returned in variable 'type' specifying which JSON value was converted to an ObjectScript value that was returned in argument variable 'value'.  The 'type' "array" means the returned 'value' is a nested %DynamicArray reference; the 'type' 'object' means the returned 'value' is a nested %DynamicObject reference; and the 'type' "oref" means the returned 'value' is some other ObjectScript class object reference.  All other 'type' string values will mean that 'value' does not contain an oref.

The statement 'set type = value.%Get("type") is only legal in ObjectScript when 'type' contains the "array", "object" or "oref" type strings.  All other type strings will cause 'value.%Get("type") to signal an <INVALID OREF> error.  Most likely you want 'value' to be a reference to a nested %DynamicObject containing a JSON entry using the key name "type".

[[ If 'value' contains the "array" type reference then 'value.%Get(arg)' would expect 'arg' to be a number rather than a string.  If 'value' contains an "oref" type reference then 'value' would be a different ObjectScript oref which must reference a class object containing a method named '%Get'. And other types for the 'value' argument would signal <INVALID OREF> since the 'value.%Get("type")' syntax requires 'value' to an oref and the other 'type' possibilities are not oref values. ]]

The other statement 'set text = type.%Get("text")' will always signal <INVALID OREF> since %GetNext always returns a string value in the 'type' variable passed as the third argument.

So, let's assume 'identifiers' contains a JSON array where every entry in the array is a JSON object containing information about an identifier.  In this case you would know the type of each array element so you could iterate calling %GetNext(.key,.value), although if you did call %GetNext(.key,.value,.type) then immediately after the %GetNext call you could test for a data error with:
    if type'="object" { do $$$ERROR($$$GeneralError,"Invalid identifier object") }

You could then look at 'value."type"' and 'value."text"' to  get the 'type' and textual name from the JSON object describing an identifier.  [[ You do not need the %Get method when you are using a string literal as the key name of a %DynamicObject entry. Using 'value.%Get(key)' is only needed when 'key' is a run-time key name expression. ]]

Certifications & Credly badges:
Steven has no Certifications & Credly badges yet.
Followers:
Following:
Steven has not followed anybody yet.