Skip to main content

Defining Custom Utility Functions

Defining Custom Utility Functions

Ensemble provides a set of utility functions that can be invoked from business rules and from DTL; these are described in “Ensemble Utility Functions” in Developing Business Rules. 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.HL7.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)
}

}

The default language inside a method is ObjectScript, as in the previous example, but you can also use Caché Basic if you define the method using the Language keyword as described in:

  • The “Language” entry in the “Class Keywords” section of the Caché ObjectScript Reference.

  • The “Methods” chapter in Using Caché Objects.

For a full list of functions and special variables available in Caché Basic or ObjectScript, see:

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 Ensemble 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 Ensemble 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 “Ensemble Utility Functions” in Developing Business Rules.)

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