The Default Function Handler

reviewed: 22 February 2025

We have already seen many examples of expressions in previous documents. In this chapter we group the most important functions of the default hander.

Mathematical Functions

Function Use Details
abs abs(number) Returns the absolute value of a specified number
add add({numbers}) Add a collection of numbers
arcCos arcCos(number) Returns the angle whose cosine is the specified number
arcSin arcSin(number) Returns the angle whose sine is the specified number
arcTan arcTan(number) Returns the angle whose tangent is the specified number
arcTan2 arcTan2(y, x) Returns the angle whose tangent is the quotient of two specified numbers
avg avg({numbers}) Returns the average value for the given numbers
ceiling ceiling(number, [multiple]) Returns the smallest integral greater than or equal to the specified number
cos cos(angle) Returns the cosine of the specified angle
div div(number1, number2, [onDivideByZero]) Divide two numbers; with an optional on error return value
floor floor(number, [multiple]) Returns the largest integral less than or equal to the specified number
mod mod(number1, number2) Divides two numbers and returns only the remainder
mul mul(number1, number2) Multiply two numbers
percent percent(percentage, total) Calculate the value of a percentage for a given total percent(50, 200) // 100
percentageOfTotal percentageOfTotal(value, total) Calculate the percent of a value for a given total percentageOfTotal(100, 200) // 50
pow pow(number, exponent) Raises a number to the power of another number
random random([min], [max]) Returns a random number Either a double that is greater than or equal to 0.0, and less than 1.0. Or a long that is within a specified range.
round round(number, [digits]) Rounds a value to the specified number of fractional digits
sin sin(angle) Returns the sine of the specified angle
sqrt sqrt(number) Returns the square root of a specified number
sub sub({numbers}) Subtract a collection of numbers
sum sum({numbers}) Sum a collection of numbers
tan tan(angle) Returns the tangent of the specified angle
totalOfPercentage totalOfPercentage(value, percentage) Calculate the total from a known percentage value totalOfPercentage(100, 50) // 200

Date and Time Functions

Function Use Details
addDay addDay(date, days) Returns a date after adding the specified number of days
addHour addHour(date, hours) Returns a date after adding the specified number of hours
addMinute addMinute(date, minutes) Returns a date after adding the specified number of minutes
addMonth addMonth(date, months) Returns a date after adding the specified number of months
addSecond addSecond(date, seconds) Returns a date after adding the specified number of seconds
addYear addYear(date, years) Returns a date after adding the specified number of years
age age(date, [on]) Gets the difference in years since a given date
day day([date]) Gets the day component of today or a given date
dayOfYear dayOfYear([date]) Gets the day of the year for today or a given date
daysDiff daysDiff(from, to) Returns a Long value specifying the number of days between two dates
endOfMonth endOfMonth([date]) Gets the last day of the month
endOfYear endOfYear([date]) Gets the last day of the year for today or a given date
hoursDiff hoursDiff(from, to) Returns a Long value specifying the number of hours between two dates
makeDate makeDate(day, month, year, [hour], [minute], [second]) Generate a date value representing a specified day, month, and year
minutesDiff minutesDiff(from, to) Returns a Long value specifying the number of minutes between two dates
month month([date]) Gets the month component of today or a given date
monthsDiff monthsDiff(from, to) Returns a Long value specifying the number of months between two dates
nextAnn nextAnn(event, date) Gets the first anniversary on or after a date
now now() Gets the current system date and time
secondsDiff secondsDiff(from, to) Returns a Long value specifying the number of seconds between two dates
startOfMonth startOfMonth([date]) Gets the first day of the month for today or a given date
startOfYear startOfYear([date]) Gets the first day of the year for today or a given date
tickCount tickCount() Get the number of milliseconds elapsed since the system started
today today() Gets the current system date
week week([date]) Gets the week number for today or a given date
weekday weekday([date]) Gets the weekday number of today or a given date
year year([date]) Gets the year component of today or a given date
yearsDiff yearsDiff(from, to) Returns a Long value specifying the number of years between two dates

String Functions

Function Use Details
ascii ascii(character) Returns a Long value representing the character code corresponding to a character
buildString buildString(separator, {strings}) Concatenate a collection of strings using a specified separator
cGrep cGrep(string, pattern, [separator]) Returns the first line which contains an occurrence of the regular expression pattern
cGrepBlock cGrepBlock(string, startPattern, endPattern) Gets the first match between two regular expression patterns
chr chr(ascii) Returns the character associated With the specified character code
cMatch cMatch(string, pattern) Does a string match a certain regular expression pattern
concat concat({strings}) Combine two or more strings into one string
cr cr() Represents a carriage-return character for print and display functions
crLf crLf() Represents a carriage-return character combined with a linefeed character for print and display functions
endsWith endsWith(string, comparison) Determines whether the end of this string instance matches a specified string
format format(value, style, [culture]) Returns a string formatted according to instructions contained in the style
formatString formatString(base, {properties}) Converts the value of properties to strings based on the formats specified and inserts them into the base string
getLine getLine(string, line) Get a given line from a body of text
getWord getWord(string, index, [separator]) Get a given word from a body of text
grep grep(string, pattern, [separator]) Returns the first line which contains an occurrence of the regular expression pattern (Ignoring Case)
grepBlock grepBlock(string, startPattern, endPattern) Gets the first match between two regular expression patterns (Ignoring Case)
inStr inStr(string, comparison) Returns a Long specifying the start position of the first occurrence of one string within another
inStrRev inStrRev(string, comparison) Returns the position of the first occurrence of one string within another, starting from the right side of the string
lCase lCase(pobjString) Returns a String converted to lowercase
left left(string, length) Get the leftmost characters from a string
len len(string) Returns a Long containing the number of characters in a String
lf lf() Represents a linefeed character for print and display functions
match match(string, pattern) Does a string match a certain regular expression pattern (Ignoring Case)
mid mid(string, start, [length]) Returns a string containing a specified number of characters from a string
pCase pCase(string) Returns a String converted to proper-Case
pluralize pluralize(number, word, [plural], [zero]) Return the singular or plural form of the word based on the number, and optional values
randomString randomString(length, [chars]) Returns a random string
replace replace(string, pattern, replacement) Replace all occurrences of a string within a string
resolveTemplate resolveTemplate(template) Returns the resolved template
right right(string, length) Get the rightmost characters from a string
soundex soundex(string) Return the soundex of a string
startsWith startsWith(string, comparison) Determines whether the beginning of this string instance matches a specified string
strEq strEq(string1, string2) Case insensitive equal for strings
string string(count, character) Returns a string to the value indicated by a specified character repeated a specified number of times
stripChars stripChars(string, pattern) Remove all character matches of the regular expression pattern in the specified string
stripEmptyLines stripEmptyLines(string) Strips all empty lines from the given string
stripNonChars stripNonChars(string, pattern) Return all character matches of the regular expression pattern in the specified string
strNeq strNeq(string1, string2) Case insensitive not-equal for strings
substring substring(string, start, [length]) Returns a string containing a specified number of characters from a string
summarize summarize(string, length) Summarize a string, removing all newlines and truncating to a set length
tab tab() Represents a tab character for print and display functions
trim trim(string, [{chars}]) Removes all leading and trailing white-space characters from the string.
trimEnd trimEnd(string, [{chars}]) Removes all trailing white-space characters from the string.
trimStart trimStart(string, [{chars}]) Removes all leading white-space characters from the string.
trunc trunc(number) Calculates the integer part of a number by removing any fractional digits
uCase uCase(string) Returns a String converted to uppercase

Encryption and Generic Encoding Functions

Function Use Details
base64Decode base64Decode(value) Decode a Base64 UTF8 string value
base64Encode base64Encode(value) Encode the UTF8 string value of a property to Base64
decrypt decrypt(string, [key], [iv], [provider]) Get the decrypted value of a string
encrypt encrypt(string, [key], [iv], [provider]) Get the encrypted value of a string
hmacMd5 hmacMd5(key, string) Gets a MD5 Hash-based Message Authentication Code (HMAC)
hmacSha1 hmacSha1(key, string) Gets a SHA-1 Hash-based Message Authentication Code (HMAC)
hmacSha256 hmacSha256(key, string) Gets a SHA-256 Hash-based Message Authentication Code (HMAC)
hmacSha512 hmacSha512(key, string) Gets a SHA-512 Hash-based Message Authentication Code (HMAC)
md5 md5(string) Get the MD5 hash of a string
nonce nonce([bytes]) Get a new nonce
salt salt([bytes]) Get a new salt
sha1 sha1(string) Get the SHA-1 hash of a string
sha256 sha256(string) Get the SHA-256 hash of a string
sha512 sha512(string) Get the SHA-512 hash of a string

Logical Functions

Function Use Details
_and _and({values}) Not short circuited Performs a logical conjunction on two or more Boolean values
_choose _choose(index, {values}) Not short circuited Return the value at a given index
_if _if(condition, then, else) Not short circuited Conditionally returns a property based on a Boolean expression
_ifNull _ifNull(value, replacement) Not short circuited Returns the replacement value if the original value is null
_onError _onError(expression, errorValue) Returns a value when an expression errors and includes the exception in the stack
_or _or({values}) Not short circuited Performs a logical disjunction on two or more Boolean values
_select _select({dictionary}) Not short circuited Gets the value of the first case in the dictionary where the condition is True
_translate _translate(key, {dictionary}) Not short circuited Gets a value corresponding to its key from a given dictionary
and and({values}) Performs a logical conjunction on two or more Boolean values
between between(value, start, end) Returns True if a value is within a set range; else False
biggest biggest({values}) Gets the biggest value out of a collection of values
choose choose(index, {values}) Return the value at a given index
eq eq(value1, value2) Checks if the values of two operands are equal or not; if yes, then condition becomes true
firstNotNull firstNotNull({values}) Gets the first non null value from a collection
ge ge(value1, value2) Checks if the value of left operand is greater than or equal to the value of right operand; if yes, then condition becomes true
gt gt(value1, value2) Checks if the value of left operand is greater than the value of right operand; if yes, then condition becomes true
if if(condition, then, else) Conditionally returns a property based on a Boolean expression
ifEqual ifEqual(value1, value2, replacement) Returns the replacement value if the original values are equal
ifNull ifNull(value, replacement) *Returns the replacement value if the original value is null
in in(value, {array}) Determine if a value is in a given collection of values
le le(value1, value2) Checks if the value of left operand is less than or equal to the value of right operand; if yes, then condition becomes true
lt lt(value1, value2) Checks if the value of left operand is less than the value of right operand; if yes, then condition becomes true
ne ne(value1, value2) Checks if the values of two operands are equal or not; if values are not equal, then condition becomes true
not not(boolean) Performs logical negation on a Boolean expression
onError onError(expression, errorValue) Returns a value when an expression errors
or or({values}) Performs a logical disjunction on two or more Boolean values
select select({dictionary}) Gets the value of the first case in the dictionary where the condition is True
smallest smallest({values}) Gets the smallest value out of a collection of values
translate translate(key, {dictionary}) Gets a value corresponding to its key from a given dictionary
xor xor(value1, value2) Performs a logical exclusion on two Boolean values

Managing Variables

Function Use Details
bln bln(value) Cast a value to a Boolean
clone clone(value) Clone a value
dat dat(value, [culture]) Cast a value to a Date
dbl dbl(value) Cast a value to a Double
false false() Represents a Boolean value
get get(name) Get a value from the context
guid guid() Get a new GUID
isBO isBO(value) Returns a Boolean value indicating whether a value is a business object
isBODesc isBODesc(value) Returns a Boolean value indicating whether a value is a business object descriptor
isBoolean isBoolean(value) Returns a Boolean value indicating whether a value is a Boolean
isDate isDate(value) Returns a Boolean value indicating whether a value represents a valid Date
isGuid isGuid(value) Returns a Boolean value indicating whether a value represents a valid GUID
isLambda isLambda(value) Returns a Boolean value indicating whether a value is a lambda function
isNotNull isNotNull(value) Returns a Boolean value that indicates whether a value contains valid data
isNull isNull(value) Returns a Boolean value that indicates whether a value contains no valid data
isNumeric isNumeric(value) Returns a Boolean value indicating whether a value represents a valid Number
isPB isPB(value) Returns a Boolean value indicating whether a value is a property bag
lng lng(value) Cast a value to a Long
null null() Represents a null value
remove remove(name) Remove a value from the context
set set(name, value) Set a value in the context
str str(value) Cast a value to a String
true true() Represents a Boolean value
typeOf typeOf(value) Get the data type of a property value

Miscelleanous

Function Use Details
config config(path) Gets a value from the system configuration
logInfo logInfo(message) Write an info message to the log
eval eval(expression) Evaluate an expression and returns its value
getTranslation getTranslation(key, [{values}]) Get a translation
inContext inContext(name) Determines if a given name is in the context
inGroup inGroup({groups}) Is the current user a member of any of the given groups
logWarning logWarning(message) Write an warning message to the log
logError logError(message) Write an error message to the log
script script({functions}) Execute an array of functions and return the value of the last entry
sleep sleep(milliseconds) Suspend the current expression for a specified time
user user() Returns the current user primary key

The Subtle Difference Between and() and _and()

You may have noticed that the function handler has a number of functions with a name starting with an underscore (_) and that also a function exists with the same name but without the underscore. For example:

  • _and and and
  • _or and or
  • _if and if
  • etc

The difference between the function pairs is always the same and is best explained using an example of the and() function.

Imagine the following scenario:

  • I want to load a business object from the database; the requested record may or may not exist
  • I want to check the status of the business object; this check will fail if the business object was not found
function doTest()

    // Try to load client with PK = 6 and assign to variable c
    set( 'c', bo.quickLoad( 'client', 6 ) )

    if eq( bo.attr( [c], 'status' ), 4 )
        // Some logic here
    else
        // Some logic here
    end-if

end-function

No client exists with PK=6 and a fatal error is raised which contains the following snippet:

BO not found for bo.attr() [c]
[page] test2:doTest, line 28
[0] clsExprFHBO.attr
....BO not found for bo.attr() [c]
....bo = clsStrProperty
....name = clsStrProperty [status]

What happens is that the bo.quickLoad() return null() as no client with PK 6 exists. In the if statement we try to access the BO c to test the value of the status attribute. This fails as c does not point to a valid BO, it has the value null().

We can only test the value of status if c is not null.

The following revised version will not fail:

function doTest()

    // Try to load client with PK = 6 and assign to variable c
    set( 'c', bo.quickLoad( 'client', 6 ) )

    if isNotNull( [c] )
        if eq( bo.attr( [c], 'status' ), 4 )
            // Some logic here
        else
            // Some logic here
        end-if
    end-if

end-function

However, the and() function allows for more elegant code:

function doTest()

    // Try to load client with PK = 6 and assign to variable c
    set( 'c', bo.quickLoad( 'client', 6 ) )

    if and(
        isNotNull( [c] ),
        eq( bo.attr( [c], 'status' ), 4 )
    )
        // Some logic here
    else
        // Some logic here; either client is not found or status is not 4
    end-if

end-function

The and() function does what is known as short circuiting; it will stop evaluating the parameters as soon as it has found a parameter that evaluates to false (as the outcome of the and() will now always be false()).

This means that and() will simply ignore the bo.attr() function (the one that can fail) when c has no value.

The _and() counterpart does not do short circuiting and will thus result in a fatal error.

Note that you can have any number of expression in an and() (or or()) function. See the following real-life example:

    if and(
        eq( [timing], eventActionTiming.Pre ),
        eq( [type], eventActionType.Update ),
        eq( bo.attr( [_me], 'ptvStatus' ), 3 ),         // Sent to PTV
        ne( bo.attr( [_me], 'status' ), 4 ),            // Completed
        ge( bo.attr( [_me], 'date' ), today() ),        // Not in the past
        not( boDesc.inGroup( [_me], 'ptvStatus', [group] )  )
    )
        bo.setAttr( [_me], 'ptvStatus', 2 )             // Requires resending
    end-if

Type Casting

We have learned that CaseMaster tries to be helpful where it can and will cast variables (and literals) from one datatype to another as required. This is often useful but can sometimes result in some interesting side effects:

function doTest()

    if gt( '18', 2 )
        response.write( 'YES: 18 gt 2<br>' )
    else
        response.write( 'NO: 18 gt 2<br>' )
    end-if

    if gt( 18, 2 )
        response.write( 'YES: 18 gt 2<br>' )
    else
        response.write( 'NO: 18 gt 2<br>' )
    end-if

    if gt( 18, '2' )
        response.write( 'YES: 18 gt 2<br>' )
    else
        response.write( 'NO: 18 gt 2<br>' )
    end-if

    // Output
    // NO: 18 gt 2
    // YES: 18 gt 2
    // YES: 18 gt 2
end-function

Many functions will look at the datatype of the first parameter and use that as a guide for how to cast where necessary.

You can use the various casting functions to force a datatype:

function doTest()

    if gt( lng( '18' ), 2 )
        response.write( 'YES: 18 gt 2<br>' )
    else
        response.write( 'NO: 18 gt 2<br>' )
    end-if

    if gt( 18, 2 )
        response.write( 'YES: 18 gt 2<br>' )
    else
        response.write( 'NO: 18 gt 2<br>' )
    end-if

    if gt( str( 18 ), '2' )
        response.write( 'YES: 18 gt 2<br>' )
    else
        response.write( 'NO: 18 gt 2<br>' )
    end-if

    // Output
    // YES: 18 gt 2
    // YES: 18 gt 2
    // NO: 18 gt 2
end-function

Exception Handling Using onError()

It is possible that you need to call a function that may raise a fatal error that you want to catch. The onError() function allow you to use a replacement value if an expression raises a fatal error.

function doTest()

    if eq( onError( script.call( 'test:thisFunctionCanFail' ), -1 ), -1 )
        // Handle error; note we assume test:thisFunctionCanFail never returns -1!
    else
        // All is well
    end-if

end-function

Note that often try - catch - finally - end-try is a more elegant way of catching exceptions (see here).

The config() Function

The config() function deserves a special mention and can be used to get values from the application configuration.

We have seen here that each application has a configuration.cms file that optionally includes additional settings from incDevelopment.cms, incTest.cms or incProduction.cms (depending on the run-modus as specified in environment.cms).

The configuration is a larger property bag with a large number of default settings, overrides of default settings and custom entries. The config() function takes a property bag path as parameter to retrieve a value. Examples:

config( 'security/allowManualUserCreation' )
config( 'login/passwordMask' )

<End of document>