Replies:

You might consider using the %Library.DynamicObject and %Library.DynamicArray classes which are built into ObjectScript.  ObjectScript supports JSON constructors for %DynamicObject, {...}, and for %DynamicArray, [...].  a %DynamicObject/Array can contain both JSON values and ObjectScript values.   There is also a %FromJSON(x) which reads JSON objects/arrays when x is a %Stream or a FileNme or an ObjectScript %String containing JSON syntax.  Here is an example from a recent IRIS release:


USER>zload foo

USER>zprint
foo()    {
            set DynObj = {
            "notanumber":"28001",
            "aboolean":true,
            "anumber":12345,
            "adecimal":1.2,
            "adate":"01/01/2023",
            "adate2":"01-01-2023",
            "anull":null,
            "anull2":null,
            "anull3":null
            }
            write DynObj.%ToJSON(),!,!

            set DynObj.Bool1 = 1    ; Set without type
            do DynObj.%Set("Bool2",1,"boolean") ; Set with type
            set DynObj.old1 = "abc"   ; Set without type
            do DynObj.%Set("new1","abc","null") ; Set with type
            set DynObj.old2 = ""   ; Set without type
            do DynObj.%Set("new2","","null") ; Set with type
            write DynObj.%ToJSON()
}        

USER>do ^foo()
{"notanumber":"28001","aboolean":true,"anumber":12345,"adecimal":1.2,"adate":"01/01/2023","adate2":"01-01-2023","anull":null,"anull2":null,"anull3":null}

{"notanumber":"28001","aboolean":true,"anumber":12345,"adecimal":1.2,"adate":"01/01/2023","adate2":"01-01-2023","anull":null,"anull2":null,"anull3":null,"Bool1":1,"Bool2":true,"old1":"abc","new1":"abc","old2":"","new2":null}

Your can use ordinary ObjectScript assignment to assign ObjectScript values to entries in a %DynamicObject/Array.  You can use the %Set(key,value,type) method to assign ObjectScript values into an object with an optional type parameter controlling which JSON value to which to convert the ObjectScript value.  I.e., type "boolean" converts ObjectScript numeric expressions into JSON false/true values and type "null" converts an ObjectScript %String into a JSON string *except* that the empty string is converted to the JSON null value.  (Note:  some older implementations of %Set with type "null" only accepted "" as the value while new implementations accept any string expression as the value.)

The JSON constructor operators in ObjectScript, besides accepting JSON literals as values, can also accept an ObjectScript expression enclosed in round parentheses. 

E.g.,  SET DynObj2 = { "Pi":3.14159, "2Pi":(2*$ZPI) }

When asking about a 'ROUTINE' you may be asking about the difference between a 'Routine', 'Procedure', 'Subroutine', 'Function', 'Label', 'Class' and 'Method'

A 'Routine' is a source code file with name like 'myroutine.mac'.  Source code can also be a 'Method' which is found in a 'Class' file with a name like 'myclass.cls"

A Routine file can contain Procedures, Subroutines, Functions and Labels.  See https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=GCOS_usercode#GCOS_usercode_overview for some InterSystems documentation.

You can call a subroutine with the statement 'DO MySubroutine^myroutine(arg)'; You can call a function with the expression '$$MyFunction^myroutine(arg)';  You can call the procedure 'MyProcedure^myroutine(arg)' using either the syntax for a subroutine call or function call depending on whether you need the value returned by the procedure; and, You can Goto the source code following a label with the statement 'GO MyLabel^myroutine'.  If you reference a subroutine/function/procedure/label inside a Routine file (e.g. myroutine.mac) and that subroutine/function/procedure/label access (e.g.$$MyFunction^myroutine(arg)) is referencing a name defined in the same Routine file then you do not have to specify the ^Routine name in the call syntax (e.g. $$MyFunction(arg)).

The local variables used inside a subroutine or function are 'public' variables and those named variables are shared with all other subroutines and functions.  You can use the NEW command inside a subroutine or function to temporarily create new public variables without modifying previous instances of public variables with the same names.

The local variables used inside a procedure are private variables.  The private variables are only available inside the procedure.  Those names do not conflict with variables used by any caller of the procedure.  Those names are not available in any code called by the procedure although it is possible to pass either the private variable or the value of the private variable as an argument when calling out of a procedure.  The declaration of a procedure can optionally include a list of public variables.  Names in public list reference the public variable when they are accessed by code in the procedure.  You can use the NEW command with an argument that is a public variable within a procedure.  A label defined inside a procedure is also private and it cannot be referenced by any GO command outside that procedure.

Methods defined in a class file default to being a procedure with private variables and private labels.  However, it is possible to specify that a method is a subroutine or function.   Also, a method procedure declaration can optionally include a list of global variables.

The %GlobalBinaryStream class is deprecated and newly written code should instead use %Stream.GlobalBinary.  Of course, existing code that is not needing modification can continue using %Library.GlobalBinaryStream.
.  

Followers:
Steven has no followers yet.
Following:
Steven has not followed anybody yet.
Global Masters badges:
Steven has no Global Masters badges yet.