Using Caché ObjectScript
Commands
[Back] [Next]
   
Server:docs2
Instance:LATEST
User:UnknownUser
 
-
Go to:
Search:    

The command is the basic unit of code in Caché ObjectScript programming. All of the execution tasks in Caché ObjectScript are performed by commands. Every command consists of a command keyword followed by (in most cases) one or more command arguments.

This chapter describes the following aspects of Caché ObjectScript commands:
The chapter then briefly describes the following groups of Caché ObjectScript commands:
This is not a complete list of Caché ObjectScript commands. These and many other Caché ObjectScript commands are described in detail in the Caché ObjectScript Reference.
Command Keywords
In Caché ObjectScript all command statements are explicit; every executable line of Caché ObjectScript code must begin with a command keyword. For example, to assign a value to a variable, you must specify the SET keyword, followed by the arguments for the variable and the value to be assigned.
A command always begins with a keyword. Consider the following:
   WRITE "Hello"
 
The word “WRITE” is the command keyword. It specifies the action to perform. The WRITE command does exactly what its name implies: it writes to the principal device whatever you specify as its argument. In this case, WRITE writes the string “Hello”.
Caché ObjectScript command names are not case-sensitive. Most command names can be represented by an abbreviated form. Therefore, “WRITE”, “Write”, “write”, “W”, and “w” are all valid forms of the WRITE command. For a list of command abbreviations, see Table of Abbreviations in the Caché ObjectScript Reference.
Command keywords are not reserved words. It is therefore possible to use a command keyword as a user-assigned name for a variable, label, or other identifier.
In a Caché ObjectScript program, the first command on a code line must be indented; the command keyword cannot appear in column 1. When issuing a command from the Terminal command line prompt, or from an XECUTE command, no indent is required (indent is permitted).
An executable line of code can contain one or more commands, each with their own command keyword. Multiple commands on a line are separated by one or more spaces. One or more commands may follow a label on the same line; the label and the command are separated by one or more spaces.
In Caché ObjectScript no end-of-command or end-of-line delimiter is required or permitted. You can specify an in-line comment following a command, indicating that the rest of the command line is a comment. A blank space is required between the end of a command and comment syntax, with the exception of ##; and /* comment */ syntax. A /* comment */ multiline comment can be specified within a command as well as at the end of one.
Command Arguments
Following a command keyword, there can be zero, one, or multiple arguments that specify the object(s) or the scope of the command. If a command takes one or more arguments, you must include exactly one space between the command keyword and the first argument. For example:
 SET x = 2
Spaces can appear within arguments or between arguments, so long as the first character of the first argument is separated from the command itself by exactly one space (as appears above). Thus the following are all valid:
  SET a = 1
  SET b=2
  SET c=3,d=4
  SET e= 5   ,  f =6
  SET g         
      =            7
  WRITE a,b,c,d,e,f,g
 
If a command takes a postconditional expression, there must be no spaces between the command keyword and the postconditional, and there must be exactly one space between the postconditional and the beginning of the first argument. Thus, the following are all valid forms of the QUIT command:
 QUIT x+y
 QUIT x + y
 QUIT:x<0
 QUIT:x<0 x+y
 QUIT:x<0 x + y
No spaces are required between arguments, but multiple blank spaces can be used between arguments. These blank spaces have no effect on the execution of the command. Line breaks, tabs, and comments can also be included within or between command arguments with no effect on the execution of the command. For further details, refer to White Space in the “Syntax Rules” chapter of this manual.
Multiple Arguments
Many commands allow you to specify multiple independent arguments. The delimiter for command arguments is the comma “,”. That is, you specify multiple arguments to a single command as a comma-separated list following the command. For example:
   SET x=2,y=4,z=6
This command uses three arguments to assign values to the three specified variables. In this case, these multiple arguments are repetitive; that is, the command is applied independently to each argument in the order specified. Internally, Caché parses this as three separate SET commands. When debugging, each of these multiple arguments is a separate step.
In the command syntax provided in the command reference pages, arguments that can be repeated are followed by a comma and ellipsis: ,.... The comma is a required delimiter character for the argument, and the ellipsis (...) indicates that an unspecified number of repetitive arguments can be specified.
Repetitive arguments are executed in strict left-to-right order. Therefore, the following command is valid:
   SET x=2,y=x+1,z=y+x
but the following command is not valid:
   SET y=x+1,x=2,z=y+x
Because execution is performed independently on each repetitive argument, in the order specified, valid arguments are executed until the first invalid argument is encountered. In the following example, SET x assigns a value to x, SET y generates an <UNDEFINED> error, and because SET z is not evaluated, the <DIVIDE> (divide-by-zero) error is not detected:
   KILL x,y,z
   SET x=2,y=z,z=5/0
   WRITE "x is:",x
Arguments with Parameters and Postconditionals
Some command arguments accept parameters (not to be confused with function parameters). If a given argument can take parameters, the delimiter for the parameters is the colon “:”).
The following sample command shows the comma used as the argument delimiter and the colon used as the parameter delimiter. In this example, there are two arguments, with four parameters for each argument.
 VIEW X:y:z:a,B:a:y:z
For a few commands (DO, XECUTE, and GOTO), a colon following an argument specifies a postconditional expression that determines whether or not that argument should be executed.
Argumentless Commands
Commands that do not take an argument are referred to as argumentless commands. A postconditional expression appended to the keyword is not considered an argument.
There are a small number of commands that are always argumentless. For example, HALT, CONTINUE, TRY, TSTART, and TCOMMIT are argumentless commands.
Several commands are optionally argumentless. For example, BREAK, CATCH, DO, FOR, GOTO, KILL, LOCK, NEW, QUIT, RETURN, TROLLBACK, WRITE, and ZWRITE all have argumentless syntactic forms. In such cases, the argumentless command may have a slightly different meaning than the same command with an argument.
If you use an argumentless command at the end of the line, trailing spaces are not required. If you use an argumentless command on the same code line as other commands, you must place two (or more) spaces between the argumentless command and any command that follows it. For example:
 QUIT:x=10  WRITE "not 10 yet"
In this case, QUIT is an argumentless command with a postconditional expression, and a minimum of two spaces is required between it and the next command.
Argumentless Commands and Curly Braces
Argumentless commands when used with command blocks delimited by curly braces do not have whitespace restrictions:
Command Postconditional Expressions
When you specify a Caché ObjectScript command, you can append to it a postconditional.
A postconditional is an optional expression that is appended to a command or (in some cases) a command argument that controls whether Caché executes that command or command argument. If the postconditional expression evaluates to TRUE (defined as nonzero), Caché executes the command or the command argument. If the postconditional expression evaluates to FALSE (defined as zero), Caché does not execute the command or command argument, and execution continues with the next command or command argument.
All Caché ObjectScript commands can take a postconditional expression, except the flow-of-control commands (IF, ELSEIF, and ELSE; FOR, WHILE, and DO WHILE) and the block structure error handling commands (TRY, THROW, CATCH).
The Caché ObjectScript commands DO and XECUTE can append postconditional expressions both to the command keyword and to their command arguments. A postconditional expression is always optional; for example, some of the command’s arguments may have an appended postconditional while its other arguments do not.
If both a command keyword and one or more of that command’s arguments specify a postconditionals, the keyword postconditional is evaluated first. Only if this keyword postconditional evaluates to TRUE are the command argument postconditionals evaluated. If a command keyword postconditional evaluates to FALSE, the command is not executed and program execution continues with the next command. If a command argument postconditional evaluates to FALSE, the argument is not executed and execution of the command continues with the next argument in left-to-right sequence.
Postconditional Syntax
To add a postconditional to a command, place a colon (:) and an expression immediately after the command keyword, so that the syntax for a command with a postconditional expression is:
Command:pc
where Command is the command keyword, the colon is a required literal character, and pc can be any valid expression.
A command postconditional must follow these syntax rules:
Note that a postconditional expression is not technically a command argument (though in the ObjectScript reference pages the explanation of the postconditional is presented as part of the Arguments section). A postconditional is always optional.
Evaluation of Postconditionals
Caché evaluates a postconditional expression as either True or False. Most commonly these are represented by 1 and 0, which are the recommended values. However, Caché performs postconditional evaluation on any value, evaluating it as False if it evaluates to 0 (zero), and True if it evaluates to a nonzero value.
For example, the following WRITE command’s action depends on the value of the variable count:
 SET count = 4
 WRITE:count<5 "count is less than 5.",!
 SET count = 6
 WRITE:count>5 "count is greater than 5.",!
 
Multiple Commands on a Line
A single line of Caché ObjectScript source code may contain multiple commands and their arguments. They are executed in strict left-to-right order, and are functionally identical to commands appearing on separate lines. A command with arguments must be separated from the command following it by one space character. An argumentless command must be separated from the command following it by two space characters. A label can be followed by one or more commands on the same line. A comment can follow one or more commands on the same line.
For the maximum length of a line of source code refer to the General System Limits appendix to the Caché Programming Orientation Guide. Note that if you are using Caché Studio to write or edit source code, this limit may differ.
Variable Assignment Commands
To provide the necessary functionality for variable management, ObjectScript provides the following commands:
SET
The SET command assigns values to variables. It can assign a value to a single variable or to multiple variables at once.
To most basic syntax of SET is:
 SET variable = expression
This sets the value of a single variable. It also involves several steps:
To set the value for each of multiple variables, use the following syntax:
 SET variable1 = expression1, variable2 = expression2, variable3 = expression3
To set multiple variables equal to a single expression use the following syntax:
 SET (variable1,variable2,variable3)= expression
For example, to set the value of the Gender property of an instance of the Person class use the following code:
 SET person.Gender = "Female"
where person is the object reference to the relevant instance of the Person class.
You can also set the Gender property of multiple Person objects at the same time:
 SET (per1.Gender, per2.Gender, per3.Gender) = "Male"
where per1, per2, and per3 are object references to three different instances of the Person class.
You can use SET to invoke a method that returns a value. When invoking methods, SET allows you to set a variable, global reference, or property equal to the return value of a method. The form of the argument depends on whether the method is an instance or a class method. To invoke a class method, use the following construction:
 SET retval = ##class(PackageName.ClassName).ClassMethodName()
Where ClassMethodName() is the name of the class method that you wish to invoke, ClassName is the name of the class containing the method, and PackageName is the name of the package containing the class. The method’s return value is assigned to the retval local variable. The ##class() construction is a required literal part of the code.
To invoke an instance method, you need only have a handle to the locally instantiated object:
 SET retval = InstanceName.InstanceMethodName()
Where InstanceMethodName() is the name of the instance method that you wish to invoke, and InstanceName is the name of the instance containing the method. The method’s return value is assigned to the retval local variable.
For further details, refer to the SET command in the Caché ObjectScript Reference.
KILL
The KILL command deletes variables from memory and can be used to delete them from disk. Its basic form is:
 KILL expression
where expression is one or more variables to delete. The simplest forms of KILL, then, are:
 KILL x
 KILL x,y,z
A special form of KILL, called an “exclusive KILL”, deletes all local variables except those specified. To use an exclusive KILL, place its argument in parentheses. For example, if you have variables x, y, and z, you can delete y, z, and any other local variables except x by invoking:
 KILL (x)
Without any arguments, KILL deletes all local variables.
For further details, refer to the KILL command in the Caché ObjectScript Reference.
NEW
The NEW command creates a new local variable context. This means that it preserves the existing local variable value in the old context, then initiates a new context in which the local variable is not assigned a value. In an application that uses procedures, use NEW to initialize variables for the entire application or a major subsystem of the application.
The following syntax forms are supported:
 NEW          // initiate new context for all local variables
 NEW x        // initiate new context for the specified local variable
 NEW x,y,z    // initiate new context for the listed local variables
 NEW (y)      // initiate new context for all local variables except the specified variable
 NEW (y,z)    // initiate new context for all local variables except the listed variables
For further details, refer to the NEW command in the Caché ObjectScript Reference.
Code Execution Context Commands
The following commands are used to support the execution of groups of commands:
Invoking Code
This section describes commands used for invoking the execution of one or more commands:
DO
To invoke a routine, procedure, or method in ObjectScript, use the DO command. The basic syntax of DO is:
 DO ^CodeToInvoke
where CodeToInvoke can be a Caché system routine or a user-defined routine. The caret character “^” must appear immediately before the name of the routine.
You can run procedures within a routine by referring to the label of the line (also called a tag) where the procedure begins within the routine. The label appears immediately before the caret. For example,
 SET %X = 484
 DO INT^%SQROOT
 WRITE %Y
 
This code sets the value of the %X system variable to 484; it then uses DO to invoke the INT procedure of the Caché system routine %SQROOT, which calculates the square root of the value in %X and stores it in %Y. The code then displays the value of %Y using the WRITE command.
When invoking methods, DO takes as a single argument the entire expression that specifies the method. The form of the argument depends on whether the method is an instance or a class method. To invoke a class method, use the following construction:
 DO ##class(PackageName.ClassName).ClassMethodName()
where ClassMethodName() is the name of the class method that you wish to invoke, ClassName is the name of the class containing the method, and PackageName is the name of the package containing the class. The ##class() construction is a required literal part of the code.
To invoke an instance method, you need only have a handle to the locally instantiated object:
 DO InstanceName.InstanceMethodName()
where InstanceMethodName() is the name of the instance method that you wish to invoke, and InstanceName is the name of the instance containing the method.
For further details, refer to the DO command in the Caché ObjectScript Reference.
JOB
While DO runs code in the foreground, JOB runs it in the background. This occurs independently of the current process, usually without user interaction. A jobbed process inherits all system defaults, except those explicitly specified.
For further details, refer to the JOB command in the Caché ObjectScript Reference.
XECUTE
The XECUTE command runs one or more Caché ObjectScript commands; it does this by evaluating the expression that it receives as an argument (and its argument must evaluate to a string containing one or more Caché ObjectScript commands). In effect, each XECUTE argument is like a one-line subroutine called by a DO command and terminated when the end of the argument is reached or a QUIT command is encountered. After Caché executes the argument, it returns control to the point immediately after the XECUTE argument.
For further details, refer to the XECUTE command in the Caché ObjectScript Reference.
QUIT and RETURN
The QUIT and RETURN commands both terminate execution of a code block, including a method. Without an argument, they simply exit the code from which they were invoked. With an argument, they use the argument as a return value. QUIT exits the current context, exiting to the enclosing context. RETURN exits the current program to the place where the program was invoked.
The following table shows how to choose whether to use QUIT RETURN:
Location QUIT RETURN
Routine code (not block structured) Exits routine, returns to the calling routine (if any). Exits routine, returns to the calling routine (if any).
TRY or CATCH block Exits TRY / CATCH block structure pair to next code in routine. If issued from a nested TRY or CATCH block, exits one level to the enclosing TRY or CATCH block. Exits routine, returns to the calling routine (if any).
DO or XECUTE Exits routine, returns to the calling routine (if any). Exits routine, returns to the calling routine (if any).
IF Exits routine, returns to the calling routine (if any). However, if nested in a FOR, WHILE, or DO WHILE loop, exits that block structure and continues with the next line after the code block. Exits routine, returns to the calling routine (if any).
FOR, WHILE, DO WHILE Exits the block structure and continues with the next line after the code block. If issued from a nested block, exits one level to the enclosing block. Exits routine, returns to the calling routine (if any).
For further details, refer to the QUIT and RETURN commands in the Caché ObjectScript Reference.
Flow Control Commands
In order to establish the logic of any code, there must be flow control; conditional executing or bypassing blocks of code, or repeatedly executing a block of code. To that end, ObjectScript supports the following commands:
Conditional Execution
To conditionally execute a block of code, based on boolean (true/false) test, you can use the IF command. (You can perform conditional execution of individual Caché ObjectScript commands by using a postconditional expression.)
IF takes an expression as an argument and evaluates that expression as true or false. If true, then the block of code that follows the expression is executed; if false, the block of code is not executed. Most commonly these are represented by 1 and 0, which are the recommended values. However, Caché performs conditional execution on any value, evaluating it as False if it evaluates to 0 (zero), and True if it evaluates to a nonzero value. For further details, refer to the Operators and Expressions chapter of this manual.
You can specify multiple IF boolean test expressions as a comma-separated list. These tests are evaluated in left-to-right order as a series of logical AND tests. Therefore, an IF evaluates as true when all of its test expressions evaluate as true. An IF evaluates as false when the one of its test expressions evaluates as false; the remaining test expressions are not evaluated.
The code usually appears in a code block containing multiple commands. Code blocks are simply one or more lines of code contained in curly braces; there can be line breaks before and within the code blocks. Consider the following:
IF, ELSEIF, and ELSE
The IF construct allows you to evaluate multiple conditions, and to specify what code is run based on the conditions. A construct, as opposed to a simple command, consists of a combination of one or more command keywords, their conditional expressions and code blocks. The IF construct consists of:
The following is an example of the IF construct:
 READ "Enter the number of equal-length sides in the polygon: ",x
   IF x=1 {WRITE !,"It's so far away that it looks like a point"} 
   ELSEIF x=2 {WRITE !,"I think that's a line, not a polygon"}
   ELSEIF x=3 {WRITE !,"It's an equalateral triangle"}
   ELSEIF x=4 {WRITE !,"It's a square"}
   ELSE {WRITE !,"It's a polygon with ",x," number of sides" }
 WRITE !,"Finished the IF test"
For further details, refer to the IF command in the Caché ObjectScript Reference.
FOR
You use the FOR construct to repeat sections of code. You can create a FOR loop based on numeric or string values.
Typically, FOR executes a code block zero or more times based on the value of a numeric control variable that is incremented or decremented at the beginning of each loop through the code. When the control variable reaches its end value, control exits the FOR loop; if there is no end value, the loop executes until it encounters a QUIT command. When control exits the loop, the control variable maintains its value from the last loop executed.
The form of a numeric FOR loop is:
 FOR ControlVariable = StartValue:IncrementAmount:EndValue {
         // code block content
 }
All values can be positive or negative; spaces are permitted but not required around the equals sign and the colons. The code block following the FOR will repeat for each value assigned to the variable.
For example, the following FOR loop will execute five times:
 WRITE "The first five multiples of 3 are:",!
 FOR multiple = 3:3:15 {
    WRITE multiple,!
 }
 
You can also use a variable to determine the end value. In the example below, a variable specifies how many iterations of the loop occur:
 SET howmany = 4
 WRITE "The first ",howmany," multiples of 3 are "
 FOR multiple = 1:1:howmany {
     WRITE (multiple*3),", "
     IF multiple = (howmany - 1) {
         WRITE "and "
     }
     IF multiple = howmany {
         WRITE "and that's it!"
     }
 }
 QUIT
 
Because this example uses multiple, the control variable, to determine the multiples of 3, it displays the expression multiple*3. It also uses the IF command to insert “and” before the last multiple.
Note:
The IF command in this example provides an excellent example of the implications of order of precedence in ObjectScript (order of precedence is always left to right with no hierarchy among operators). If the IF expression were simply “multiple = howmany - 1”, without any parentheses or parenthesized as a whole, then the first part of the expression, “multiple = howmany”, would be evaluated to its value of False (0); the expression as a whole would then be equal to “0 - 1”, which is -1, which means that the expression will evaluate as true (and insert “and ” for every case except the final iteration through the loop).
The argument of FOR can also be a variable set to a list of values; in this case, the code block will repeat for each item in the list assigned to the variable.
 FOR b = "John", "Paul", "George", "Ringo" {
    WRITE !, "Was ", b, " the leader? "
  READ choice
 }
You can specify the numeric form of FOR without an ending value by placing a QUIT within the code block that triggers under particular circumstances and thereby terminates the FOR. This approach provides a counter of how many iterations have occurred and allows you to control the FOR using a condition that is not based on the counter’s value. For example, the following loop uses its counter to inform the user how many guesses were made:
    FOR i = 1:1 {
    READ !, "Capital of MA? ", a
    IF a = "Boston" {
        WRITE "...did it in ", i, " tries"
        QUIT
        }
    }
If you have no need for a counter, you can use the argumentless FOR:
    FOR  {
        READ !, "Know what? ", wh
        QUIT:(wh = "No!")
        WRITE "   That's what!"
    }
For further details, refer to the FOR command in the Caché ObjectScript Reference.
WHILE and DO WHILE
Two related flow control commands are WHILE and DO WHILE commands, each of which loops over a code block and terminates based on a condition. The two commands differ in when they evaluate the condition: WHILE evaluates the condition before the entire code block and DO WHILE evaluates the condition after the block. As with FOR, a QUIT within the code block terminates the loop.
The syntax for the two commands is:
 DO {code} WHILE condition
 WHILE condition {code}
The following example displays values in the Fibonacci sequence up to a user-specified value twice — first using DO WHILE and then using WHILE:
fibonacci() PUBLIC { // generate Fibonacci sequences 
    READ !, "Generate Fibonacci sequence up to where? ", upto
    SET t1 = 1, t2 = 1, fib = 1
    WRITE !
    DO {
        WRITE fib,"  "  set fib = t1 + t2, t1 = t2, t2 = fib
    }
    WHILE ( fib '> upto )

    SET t1 = 1, t2 = 1, fib = 1
    WRITE !
    WHILE ( fib '> upto ) {
        WRITE fib,"  " 
        SET fib = t1 + t2, t1 = t2, t2 = fib
    }
 }
The distinction between WHILE, DO WHILE, and FOR is that WHILE necessarily tests the control expression’s value before executing the loop, DO WHILE necessarily tests the value after executing the loop, and FOR can test it anywhere within the loop. This means that if you have two parts to a code block, where execution of the second depends on evaluating the expression, the FOR construct is best suited; otherwise, the choice depends on whether expression evaluation should precede or follow the code block.
For further details, refer to the WHILE command and the DO WHILE command in the Caché ObjectScript Reference.
I/O Commands
ObjectScript input/output commands provide the basic functionality for getting data in and out of Caché. These are:
Display (Write) Commands
Caché ObjectScript supports four commands to display (write) literals and variable values to the current output device:
Argumentless Display Commands
Display Commands with Arguments
The following tables list the features of the argumented forms of the four commands. All four commands can take a single argument or a comma-separated list of arguments. All four commands can take as an argument a local, global, or process-private variable, a literal, an expression, or a special variable:
The following tables also list the %Library.Utility.FormatString() method default return values. The FormatString() method is most similar to ZZWRITE, except that it does not list %val= as part of the return value, and it returns only the object reference (OREF) identifier. FormatString() allows you to set a variable to a return value in ZWRITE / ZZWRITE format.
Display Formatting
  WRITE ZWRITE ZZDUMP ZZWRITE FormatString()
Each value on a separate line? NO YES YES (16 characters per line) YES One input value only
Variable names identified? NO YES NO Represented by %val= NO
Undefined variable results in <UNDEFINED> error? YES NO (skipped, variable name not returned) YES YES YES
All four commands evaluate expressions and return numbers in canonical form.
How Values are Displayed
  WRITE ZWRITE ZZDUMP ZZWRITE FormatString()
Hexadecimal representation? NO NO YES NO NO
Strings quoted to distinguish from numerics? NO YES NO YES (a string literal is returned as %val="value") YES
Subscript nodes displayed? NO YES NO NO NO
Global variables in another namespace (extended global reference) displayed? YES YES (extended global reference syntax shown) YES YES YES
Non-printing characters displayed? NO, not displayed; control characters executed YES, displayed as $c(n) YES, displayed as hexadecimal YES, displayed as $c(n) YES, displayed as $c(n)
List value format encoded string $lb(val) format encoded string $lb(val) format $lb(val) format
%Status format string containing encoded Lists string containing $lb(val) format Lists, with appended /*... */ comment specifying error and message. string containing encoded Lists string containing $lb(val) format Lists, with appended /*... */ comment specifying error and message. string containing $lb(val) format Lists, with (by default) appended /*... */ comment specifying error and message.
Bitstring format encoded string $zwc format with appended /* $bit() */ comment listing 1 bits. For example: %val=$zwc(407,2,1,2,3,5)/*$bit(2..4,6)*/ encoded string $zwc format with appended /* $bit() */ comment listing 1 bits. For example: %val=$zwc(407,2,1,2,3,5)/*$bit(2..4,6)*/ $zwc format with (by default) appended /* $bit() */ comment listing 1 bits. For example: %val=$zwc(407,2,1,2,3,5)/*$bit(2..4,6)*/
Object Reference (OREF) format OREF only OREF in <OBJECT REFERENCE>[oref] format. General information, attribute values, etc. details listed. All subnodes listed OREF only OREF in <OBJECT REFERENCE>[oref] format. General information, attribute values, etc. details listed. OREF only, as quoted string
JSON dynamic arrays and JSON dynamic objects are returned as OREF values by all of these commands. To return the JSON contents you must use %ToJSON(), as shown in the following example:
  SET jobj={"name":"Fred","city":"Bedrock"}
  WRITE "JSON object reference:",!
  ZWRITE jobj
  WRITE !!,"JSON object value:",!
  ZWRITE jobj.%ToJSON()
For further details, refer to the WRITE, ZWRITE, ZZDUMP, and ZZWRITE commands in the Caché ObjectScript Reference.
READ
The READ command allows you to accept and store input entered by the end user via the current input device. The READ command can have any of the following arguments:
  READ format, string, variable
Where format controls where the user input area will appear on the screen, string will appear on the screen before the input prompt, and variable will store the input data.
The following format codes are used to control the user input area:
Format Code Effect
! Starts a new line.
# Starts a new page. On a terminal it clears the current screen and starts at the top of a new screen.
?n Positions at the nth column position where n is a positive integer.
For further details, refer to the READ command in the Caché ObjectScript Reference.
OPEN, USE, and CLOSE
For more sophisticated device handling, Caché offers a wealth of options. In short, you can take ownership of an open device with the OPEN command; specify the current device with the USE command; and close an open device with the CLOSE command. This process as a whole is described in Caché I/O Device Guide.
For further details, refer to the OPEN, USE, and CLOSE commands in the Caché ObjectScript Reference.