Skip to main content

Defining Procedures

Defining Procedures

As in other languages, a procedure is a series of ObjectScript commands (a section of a larger routine) that accomplishes a specific task. Similar to constructs such as If, the code of a procedure is contained within curly braces.

Procedures allow you to define each variable as either public or private. For example, the following procedure, is called MyProc:

MyProc(x,y) [a,b] PUBLIC {
 Write "x + y = ", x + y
}

defines a public procedure named MyProc which takes two parameters, x and y. It defines two public variables, a and b. All other variables used in the procedure (in this case, x and y) are private variables.

By default, procedures are private, which means that you can only call them from elsewhere in the same routine. You can also create procedures that are public, using the Public keyword after the procedure name. Public procedures can be called from other routines.

Procedures do not need to have defined parameters. To create procedures with parameters, place a parenthesized list of variables immediately after the label.

Invoking Procedures

To invoke a procedure, either issue a DO command that specifies the procedure, or call it as a function using the $$ syntax. You can control whether a procedure can be invoked from any program (public), or only from the program in which it is located (private). If invoked with DO, a procedure does not return a value; if invoked as a function call, a procedure returns a value. The $$ form provides the most functionality, and is generally the preferred form.

Using the $$ Prefix

You can invoke a user-defined function in any context in which an expression is allowed. A user-defined function call takes the form:

$$name([param[ ,...]])

where:

  • name specifies the name of the function. Depending on where the function is defined, name can be specified as:

    • label is a line label within the current routine.

    • label^routine is a line label within the named routine that resides on disk.

    • ^routine is a routine that resides on disk. The routine must contain only the code for the function to be performed.

  • param specifies the values to be passed to the function. The supplied parameters are known as the actual parameter list. They must match the formal parameter list defined for the function. For example, the function code may expect two parameters, with the first being a numeric value and the second being a string literal. If you specify the string literal for the first parameter and the numeric value for the second, the function may yield an incorrect value or possibly generate an error. Parameters in the formal parameter list always have NEW invoked by the function. See the NEW command. Parameters can be passed by value or by reference. See Parameter Passing. If you pass fewer parameters to the function than are listed in the function’s formal parameter list, parameter defaults are used (if defined); if there are no defaults, these parameters remain undefined.

Using the DO Command

You can invoke a user-defined function using the DO command. (You cannot invoke a system-supplied function using the DO command.) A function invoked using DO does not return a value. That is, the function must generate a return value, but the DO command ignores this return value. This greatly limits the use of DO for invoking user-defined functions.

To invoke a user-defined function using DO, you issue a command in the following syntax:

DO label(param[,...])

The DO command calls the function named label and passes it the parameters (if any) specified by param. Note that the $$ prefix is not used, and that the parameter parentheses are mandatory. The same rules apply for specifying the label and param as when invoking a user-defined function using the $$ prefix.

A function must always return a value. However, when a function is called with DO, this returned value is ignored by the calling program.

Procedure Syntax

Procedure syntax:

 label([param[=default]][,...]) [[pubvar[,...]]] [access] 
  {
   code 
  } 

Invoking syntax:

DO label([param[,...]]) 

or

 command $$label([param][,...]) 

where

Argument Description
label The procedure name. A standard label. It must start in column one. The parameter parentheses following the label are mandatory.
param A variable for each parameter expected by the procedure. These expected parameters are known as the formal parameter list. The parameters themselves are optional (there may be none, one, or more than one param) but the parentheses are mandatory. Multiple param values are separated by commas. Parameters may be passed to the formal parameter list by value or by reference. Procedures that are routines do not include type information about their parameters; procedures that are methods do include this information. The maximum number of formal parameters is 255.
default An optional default value for the param preceding it. You can either provide or omit a default value for each parameter. A default value is applied when no actual parameter is provided for that formal parameter, or when an actual parameter is passed by reference and the local variable in question does not have a value. This default value must be a literal: either a number, or a string enclosed in quotation marks. You can specify a null string () as a default value. This differs from specifying no default value, because a null string defines the variable, whereas the variable for a parameter with no specified or default value would remain undefined. If you specify a default value that is not a literal, InterSystems IRIS issues a <PARAMETER> error.
pubvar Public variables. An optional list of public variables used by the procedure and available to other routines and procedures. This is a list of variables both defined within this procedure and available to other routines and defined within another routine and available to this procedure. If specified, pubvar is enclosed in square brackets. If no pubvar is specified, the square brackets may be omitted. Multiple pubvar values are separated by commas. All variables not declared as public variables are private variables. Private variables are available only to the current invocation of the procedure. They are undefined when the procedure is invoked, and destroyed when the procedure is exited. If the procedure calls any code outside of that procedure, the private variables are preserved, but are unavailable until the call returns to the procedure. All % variables are always public, whether or not they are listed here. The list of public variables can include one or more of the param specified for this routine.
access An optional keyword that declares whether the procedure is public or private. There are two available values: PUBLIC, which declares that this procedure can be called from any routine. PRIVATE, which declares that this procedure can only be called from the routine in which it is defined. PRIVATE is the default.
code A block of code, enclosed in curly braces. The opening curly brace ({) must be separated from the characters preceding and following it by at least one space or a line break. The closing curly brace (}) must not be followed by any code on the same line; it can only be followed by blank space or a comment. The closing curly brace can be placed in column one. This block of code is only entered by the label.

You cannot insert a line break between a command and its arguments.

Each procedure is implemented as part of a routine; each routine can contain multiple procedures.

In addition to standard ObjectScript syntax, there are special rules governing routines. A line in a routine can have a label at the beginning (also called a tag), ObjectScript code, and a comment at the end; but all of these elements are optional.

InterSystems recommends that the first line of a routine have a label matching the name of the routine, followed by a tab or space, followed by a short comment explaining the purpose of the routine. If a line has a label, you must separate it from the rest of the line with a tab or a space. This means that as you add lines to your routine using Studio, you either type a label and a tab/space, followed by ObjectScript code, or you skip the label and type a tab or space, followed by ObjectScript. So in either case, every line must have a tab or space before the first command.

To denote a single-line comment use either a double slash (//) or a semicolon (;). If a comment follows code, there must be a space before the slashes or semicolon; if the line contains only a comment, there must be a tab or space before the slashes or semicolon. By definition, there can be no line break within a single-line comment; for a multiline comment, mark the beginning of the comment with /* and the end with */.

Procedure Variables

Procedures and methods both support private and public variables; all of the following statements apply equally to procedures and methods:

Variables used within procedures are automatically private to that procedure. Hence, you do not have to declare them as such and they do not require a NEW command. To share some of these variables with procedures that this procedure calls, pass them as parameters to the other procedures.

You can also declare public variables. These are available to all procedures and methods; those that this procedure or method calls and those that called this procedure or method. A relatively small number of variables should be defined in this way, to act as environmental variables for an application. To define public variables, list them in square brackets following the procedure name and its parameters.

The following example defines a procedure with two declared public variables [a, b] and two private variables (c, d):

publicvarsexample
    ; examples of public variables
    ;
    DO proc1()   ; call a procedure
    QUIT    ; end of the main routine
    ;
proc1() [a, b]
    ; a private procedure
    ; "c" and "d" are private variables
    {
    WRITE !, "setting a"  SET a = 1
    WRITE !, "setting b"  SET b = 2
    WRITE !, "setting c"  SET c = 3
    SET d = a + b + c
    WRITE !, "The sum is: ", d
    }
USER>WRITE

USER>DO ^publicvarsexample

setting a
setting b
setting c
The sum is: 6
USER>WRITE

a=1
b=2
USER>

Public versus Private Variables

Within a procedure, local variables may be either public or private. The public list [pubvar] declares which variable references in the procedure are added to the set of public variables; all other variable references in the procedure are to a private set seen only by the current invocation of the procedure.

Private variables are undefined when a procedure is entered, and they are destroyed when a procedure is exited.

When code within a procedure calls any code outside of that procedure, the private variables are restored upon the return to the procedure. The called procedure or routine has access to public variables (as well as its own private ones.) Thus, [pubvar] specifies both the public variables seen by this procedure and the variables used in this procedure that are capable of being seen by a routine that the procedure calls.

If the public list is empty, then all variables are private. In this case, the square brackets are optional.

Variables whose name starts with the percent (%) character are typically variables used by the system or for some special purpose. InterSystems IRIS reserves all % variables (except %z and %Z variables) for system use; user code should only use % variables that begin with %z or %Z. All % variables are implicitly public. They can be listed in the public list (for documentation purposes) but this is not necessary.

Private Variables versus Variables Created with NEW

Note that private variables are not the same as variables newly created with NEW. If a procedure wants to make a variable directly available to other procedures or subroutines that it calls, then it must be a public variable and it must be listed in the public list. If it is a public variable being introduced by this procedure, then it makes sense to perform a NEW on it. That way it will be automatically destroyed when the procedure exits, and also it protects any previous value that public variable may have had. For example, the code:

MyProc(x,y)[name]{
 NEW name
 SET name="John"
 DO xyz^abc
}

enables procedure xyz in routine abc to see the value John for name, because it is public. Invoking the NEW command for name protects any public variable named name that may already have existed when the procedure MyProc was called.

The NEW command does not affect private variables; it only works on public variables. Within a procedure, it is illegal to specify NEW x or NEW (x) if x is not listed in the public list and x is not a % variable.

Making Formal List Parameters Public

If a procedure has a formal list parameter, (such as x or y in MyProc(x,y) ) that is needed by other procedures it calls, then the parameter should be listed in the public list.

Thus,

MyProc(x,y)[x] {
 DO abc^rou
 }

makes the value of x, but not y, available to the routine abc^rou.

Public and Private Procedures

A procedure can be public or private. A private procedure can only be called from within the routine in which the procedure is defined, whereas a public procedure can be called from any routine. If the PUBLIC and PRIVATE keywords are omitted, the default is private.

For instance,

MyProc(x,y) PUBLIC { }

defines a public procedure, while

MyProc(x,y) PRIVATE { }

and

MyProc(x,y) { }

both define a private procedure.

FeedbackOpens in a new tab