Skip to main content

Defining Custom Utility Functions

Defining Custom Utility Functions

InterSystems IRIS® provides a set of utility functions that can be invoked from business rules and from DTL; these are described in Utility Functions for Use in Productions. You can add your own functions, and the business rules engine and Business Rule Editor accommodate your extensions automatically.

To add a new utility function:

  1. Create a new class that is a subclass of Ens.Rule.FunctionSetOpens in a new tab. This class must not extend any other superclasses, only Ens.Rule.FunctionSetOpens in a new tab.

  2. For each function you wish to define, add a class method to your new function set class. There is no support for polymorphism, so to be precise, you must mark these class methods as final. You can view this in the existing Ens.Util.FunctionSetOpens in a new tab methods (Ens.Util.FunctionSetOpens in a new tab is a superclass of Ens.Rule.FunctionSetOpens in a new tab).

  3. Compile the new class. The new functions are now available for use in rule expressions. To invoke these functions, use the ClassMethod name from your subclass. Unlike functions defined in Ens.Rule.FunctionSetOpens in a new tab, user-defined method names must be fully qualified with the class that they belong to. This happens automatically if you add them by selecting names from the wizards in the Management Portal.

As an example, the following function set class provides date and time functions for use in business rules. Its class methods DayOfWeek() and TimeInSeconds() invoke the ObjectScript functions $ZDATE and $PIECE to extract the desired date and time values from the ObjectScript special variable $HOROLOG:

/// Time functions to use in rule definitions.
Class Demo.MsgRouter.Functions Extends Ens.Rule.FunctionSet
{

/// Returns the ordinal position of the day in the week,
/// where 0 is Sunday, 1 is Monday, and so on.
ClassMethod DayOfWeek() As %Integer [ CodeMode = expression, Final ]
{
$zd($H,10)
}

/// Returns the time as a number of seconds since midnight.
ClassMethod TimeInSeconds() As %Integer [ CodeMode = expression, Final ]
{
$p($H,",",2)
}

}

For a full list of functions and special variables available in ObjectScript, see ObjectScript Reference.

Once you have added a new function as described in this topic, the syntax for referring to it is slightly different than for built-in functions. Suppose you define this function in a class that inherits from Ens.Rule.FunctionSetOpens in a new tab.

ClassMethod normalizaSexo(value as %String) as %String {}

After you compile the class, when you use one of the InterSystems IRIS Interoperability visual tools such as the Routing Rule Editor or Data Transformation Builder, you see your function name normalizaSexo included in the function selection box along with built-in functions like Strip, In, Contains, and so on.

Suppose you choose a built-in function from the function selection box and look at the generated code. You see that InterSystems IRIS has generated the function call using double-dot method call syntax (in DTL) or has simply referenced the function by name (in a business rule). (These syntax rules are explained in Utility Functions for Use in Productions.)

The following example is an <assign> statement from DTL that references the built-in Strip function with double-dot syntax:

<assign property='target.cod'
        value='..Strip(source.{PatientIDExternalID.ID},"<>CW")'
        action='set'/> 

However, if you create your own, user-defined functions, the syntax for DTL is different. It is not enough simply to identify the function; you must also identify the full class name for the class that contains the class method for your function. Suppose your function normalizaSexo was defined in a class named HP.Util.funciones. In that case, after you chose a function from the function selection box and looked at the generated code, you would see something like the following example:

<assign property='target.sexo'
        value='##class(HP.Util.funciones).normalizaSexo(source.{Sex})'
        action='set'/> 

You need to be aware of this syntax variation if you wish to type statements like this directly into your DTL code, rather than using the Data Transformation Builder to generate the code.

FeedbackOpens in a new tab