Skip to main content
HealthShare Health Connect 2024.3
AskMe (beta)
Loading icon

Passing Arguments

This page describes how to pass arguments when calling units of code.

Formal Argument Lists and Examples

Each ObjectScript function has a formal argument list, as does each class or instance method, and each procedure or other subroutine type. A formal argument list is a comma-separated list of arguments. This section presents basic examples.

ObjectScript functions

For an ObjectScript function, the corresponding reference page shows the formal argument list. For example, the reference page for the $LENGTH function shows the formal argument list as follows:

$LENGTH(expression,delimiter)
Methods

For methods, the class documentation shows the formal argument list and any generated comments, and you can also view the code directly in your IDE. In contrast to the ObjectScript function documentation, the formal argument list includes information about the expected values of the arguments and default values.

For example, %Library.FileOpens in a new tab shows the formal argument list for the NormalizeFilename() method as follows:

classmethod NormalizeFilename(filename As %String, directory As %String = "") as %String
Functions, procedures, and subroutines

For any type of subroutine explained in the documentation, the documentation generally shows the formal argument list in context—for example as part of the command you would use. For example, the reference page for the ^PERFMON routine shows the syntax for calling the Collect() function within this routine, as follows:

 set status = $$Collect^PERFMON(time,format,output)

Passing Arguments (Basics)

When you invoke a unit of code, you pass arguments, usually using syntax of the following general form:

 codeunitidentifier(arg1,arg2,arg3)

Note the following general points:

  • This syntax passes arguments by value. An alternative, less common-form passes arguments by reference.

  • Some units of code do not accept any arguments.

    If the unit of code is a method or an ObjectScript function, you must include the parentheses after its name. If the unit of code is a subroutine (of any form), you do not need to include the parentheses after its name.

  • InterSystems IRIS maps the given arguments, by position, to the corresponding arguments in the formal argument list. Thus, the value of the first arguments in the actual list is placed in the first variable in the formal list; the second value is placed in the second variable; and so on.

    The matching of these arguments is done by position, not name.

  • In some cases, some arguments are optional. If an argument is optional, and you need to specify an argument in a later position, simply use commas to skip the arguments that you do not want to pass. For example:

     set myval=##class(Sample.MyClass).MyMethod(arg1,,,arg4)
    
  • If you pass more arguments than are present in the formal argument list, a <PARAMETER> error occurs. (This does not include code units that accept a variable number of arguments; these never produce a <PARAMETER> error.)

Variations are discussed in the following sections.

Passing a Variable Number of Arguments

Some units of code can accept a variable number of arguments. For example:

  • The reference page for the $CLASSMETHOD function shows the formal argument list as follows:

    $CLASSMETHOD(classname, methodname, arg1, arg2, arg3, ... )
    

    In this case, arg1, arg2, and arg3 are placeholders, and the three trailing periods indicate that this function can accept a variable number of arguments.

  • %SQL.StatementOpens in a new tab shows the formal argument list for the %Execute() method as follows:

    method %Execute(%parm...) as %SQL.StatementResult
    

    Notice the three periods after the argument. This syntax indicates that the method accepts a variable number of arguments.

With a variable number of arguments like this, you can pass a set of arguments—of varying number—to another unit of code, which has a argument list that may not be known in advance. In all cases when a variable number of arguments are accepted, you should list these arguments in the order expected by the applicable downstream unit of code. Separate these arguments with commas as usual.

For example, the $CLASSMETHOD function enables you to invoke a class method, passing to it any arguments of that method. The following ObjectScript shell session demonstrates this function:

USER>WRITE $CLASSMETHOD("%SYSTEM.Util","CreateGUID",1)
e0a1a880-cec1-11ef-8000-b5030da4acfe
USER>WRITE $CLASSMETHOD("%SYSTEM.Version","Is64Bits")
1

The CreateGUID() method of %SYSTEM.UtilOpens in a new tab accepts 1 argument and generates a GUID. The Is64Bits() method of %SYSTEM.VersionOpens in a new tab takes no arguments and returns 1 if the underlying system uses 64–bit architecture (or 0 otherwise). While this is an artificial example and you would not need to call these methods in this manner, the $CLASSMETHOD function can be a very powerful tool in complex applications.

Similarly, as seen above, the %Execute() method accepts a variable number of arguments, which are all passed, in order, to the query being executed by the %SQL.StatementOpens in a new tab instance.

ObjectScript handles passing a variable number of parameters by creating a subscripted variable, creating one subscript for each passed variable. The top level of the variable contains the number of parameters passed. The variable subscripts contain the passed values.

Also see Variable Numbers of Arguments in Methods.

Passing ByRef or Output Arguments

Some argument lists include the keyword ByRef or the keyword Output before one or more arguments. For example:

  • %Library.PersistentOpens in a new tab shows the formal argument list for the %OpenID() method as follows, with line breaks for readability:

    classmethod %OpenID(id As %String="", 
                        concurrency As %Integer = -1, 
                        ByRef sc As %Status = $$$OK) as %ObjectHandle
    
  • %Library.FileOpens in a new tab shows the formal argument list for the Exists() method as follows:

    classmethod Exists(filename As %String, Output return As %Integer) as %Boolean
    

In these cases, when calling such units of code, place a period immediately before any ByRef or Output argument. This means that the argument must be a variable, rather than a literal or other kind of expression.

In these cases, you are passing the given argument by reference. In general, this means that this argument is set by or updated by the code unit that you are calling. Similarly, this means that the argument then contains a value intended for your use, such as in deciding how to proceed.

For example, when calling the Exists() method of the %Library.FileOpens in a new tab class, use a period before the second argument:

 set status=##class(%Library.File).Exists("c:\temp\check.txt",.returncode)

As indicated in the class reference, the second argument contains the value obtained from the operating system when this check is performed.

Similarly, when calling the %OpenID() method of %Library.PersistentOpens in a new tab, inherited by all persistent classes, use a period before the third argument:

 set myvar=##class(MyPackage.MyClass).%OpenId(10034,,.statuscode)

As indicated in the class reference, the third argument contains the status code that indicates success or failure ( and the reason, in case of failure).

Except for ObjectScript functions, any unit of code can be written to accept arguments passed by reference.

Comparison: Arguments by Value and Arguments by Reference

This section describes the differences between the two ways of passing arguments. This section first discusses passing local variables with no subscripts (the most common scenario).

As with other programming languages, InterSystems IRIS has a memory location that contains the value of each local variable. The name of the variable acts as the address to the memory location.

When you pass a local variable with no subscripts to a method, you pass the variable by value. This means that the system makes a copy of the value, so that the original value is not affected. To pass the memory address instead, place a period immediately before the name of the variable in the argument list.

To demonstrate this, consider the following method in a class called Test.Parameters:

ClassMethod Square(input As %Integer) As %Integer
{
    set answer=input*input
    set input=input + 10
    return answer
}

Suppose that you define a variable and pass it by value to this method:

TESTNAMESPACE>set myVariable = 5
 
TESTNAMESPACE>write ##class(Test.Parameters).Square(myVariable)
25
TESTNAMESPACE>write myVariable
5

In contrast, suppose that you pass the variable by reference:

TESTNAMESPACE>set myVariable = 5
 
TESTNAMESPACE>write ##class(Test.Parameters).Square(.myVariable)
25
TESTNAMESPACE>write myVariable
15

Consider the following method, which writes the contents of the argument it receives:

ClassMethod WriteContents(input As %String)
{
    zwrite input
}

Now, suppose you have an array with three nodes:

TESTNAMESPACE>zwrite myArray
myArray="Hello"
myArray(1)="My"
myArray(2)="Friend"

If you pass the array to the method by value, you are only passing the top-level node:

TESTNAMESPACE>do ##class(Test.Parameters).WriteContents(myArray)
input="Hello"

If you pass the array to the method by reference, you are passing the entire array:

TESTNAMESPACE>do ##class(Test.Parameters).WriteContents(.myArray)
input="Hello"
input(1)="My"
input(2)="Friend"

You can pass the value of a single node of a global to a method:

TESTNAMESPACE>zwrite ^myGlobal
^myGlobal="Start"
^myGlobal(1)="Your"
^myGlobal(2)="Engines"
TESTNAMESPACE>do ##class(Test.Parameters).WriteContents(^myGlobal)
input="Start"

Trying to pass a global to a method by reference results in a syntax error:

TESTNAMESPACE>do ##class(Test.Parameters).WriteContents(.^myGlobal)
^
<SYNTAX>

The following table summarizes all the possibilities:

Kind of Variable Passing by Value Passing by Reference
Local variable with no subscripts The standard way in which these variables are passed Allowed
Local with subscripts (array) Passes the value of a single node The standard way in which these variables are passed
Global variable with or without subscripts Passes the value of a single node Cannot be passed this way (data for a global is not in memory)
Object Reference (OREF)* The standard way in which these variables are passed Allowed

* If you have a variable representing an object, you refer to the object by means of an object reference (OREF). When you pass an OREF as an argument, you typically pass it by value. However, since an OREF is a pointer to the object, you are effectively passing the object by reference. Changing the value of a property of the object inside the method changes the actual object, not a copy of the object. Passing an OREF by reference is allowed and can be used if you want to change the OREF to point to a different object. This is not a common usage. See Objects for more information on objects and object references.

FeedbackOpens in a new tab