app.ducx expression language supports a wide range of operators.
Assignment operators allow you to set property and variable values. The next table contains a list of supported assignment operators.
Operator | Description |
= | The = operator is used for simple assignments. The value of the right operand is assigned to the left operand. |
+= | Both operands are added, and the result is assigned to the left operand. The += operator can be used with strings, numeric data types, currencies and lists. |
-= | The right operand is subtracted from the left operand, and the result is assigned to the left operand. The -= operator can be used with numeric data types, currencies, lists and dictionaries. |
*= | Both operands are multiplied, and the result is assigned to the left operand. The *= operator can be used with numeric data types, currencies, lists and dictionaries. |
/= | The left operand is divided by the right operand, and the result is assigned to the left operand. The /= operator can be used with numeric data types, currencies, lists and dictionaries. |
%= | A modulus operation is carried out, and the result is assigned to the left operand. The %= operator can only be used with numeric data types, currencies, lists and dictionaries. |
<<= | The <<= is used for character- and bitwise shifting to the left. The <<= operator can be used with strings, integers, currencies and lists. |
>>= | The >>= is used for character- and bitwise shifting to the right. The >>= operator can be used with strings, integers, currencies and lists. |
Table 37: Assignment operators
Example |
Order @order; // A simple assignment operation // Adding an element to a list // Adding an element to a list only if it is not part of the list already |
Logical operators are implemented to support short circuit evaluation semantics. The right operand is only evaluated if the result of the evaluation is not determined by the left operand already. The next table shows a list of the supported logical operators.
Operator | Description |
and (alternatively &&) | The and operator indicates whether both operands are true. If both operands have values of true, the result has the value true. Otherwise, the result has the value false. Both operands are implicitly converted to BOOLEAN and the result data type is BOOLEAN. |
or (alternatively ||) | The or operator indicates whether either operand is true. If either operand has a value of true, the result has the value true. Otherwise, the result has the value false. Both operands are implicitly converted to BOOLEAN and the result data type is BOOLEAN. |
not (alternatively !) | The expression yields the value true if the operand evaluates to false, and yields the value false if the operand evaluates to true. The operand is implicitly converted to BOOLEAN, and the data type of the result is BOOLEAN. |
Example |
if (@orderstate == OrderState(OS_SHIPPED) and @orderdate != null or |
Table 39 contains a list of supported calculation operators.
Operator | Description |
+ - * / % | The +, -, *, / and % operators are supported for numeric data types and lists. +, -, * and / are also supported for currencies (* and / need one integer or float operand). Additionally, the + operator can be used to concatenate strings. When used with lists, the following semantic applies: + (concatenation): The right operand is concatenated to the end of the left operand. - (difference): Each element from the right operand is removed from the left operand. * (union): Each element from the right operand is appended to the left operand if the element does not occur in the left operand. / (symmetric difference): The resulting list is the union of the difference of the left and the right operand and the difference of the right and the left operand: a / b == (a - b) * (b - a) == (a * b) - (b % a). % (intersection): The resulting list is the list of elements that exist in both the left and the right operand. Note: Each element in a list is treated as an individual element, even if the list contains other elements with the same value. So be careful if you use operators with lists that are not unique. Since there are two elements "2" in the left operand, these expressions are true: [1, 2, 2] - [2] == [1, 2]; [1, 2, 2] * [2] == [1, 2, 2]; When used with dictionaries, the following semantic applies: - (difference): Each entry from the right operand is removed from the left operand (regardless of the value of the entry) * (union): Each entry from the right operand is appended to the left operand if the entry does not occur in the left operand. / (symmetric difference): The resulting dictionary is the union of the difference of the left and the right operand and the difference of the right and the left operand: a / b == (a - b) * (b - a) == (a * b) - (b % a). % (intersection): The resulting dictionary contains the entries that exist in both the left and the right operand. The values are taken from the left operand. |
++ | The ++ increment operator is a unary operator that adds 1 to the value of a scalar numeric operand. The operand receives the result of the increment operation. You can put the ++ before or after the operand. If it appears before the operand, the operand is incremented. The incremented value is then used in the expression. If you put the ++ after the operand, the value of the operand is used in the expression before the operand is incremented. |
-- | The -- decrement operator is a unary operator that subtracts 1 from the value of a scalar numeric operand. The operand receives the result of the decrement operation. You can put the -- before or after the operand. If it appears before the operand, the operand is decremented. The decremented value is then used in the expression. If you put the -- after the operand, the value of the operand is used in the expression before the operand is decremented. |
<< | The << is used for character- and bitwise shifting to the left. The << operator can be used with strings, integers, currencies and lists. When used with strings, the right operand specifies the number of characters removed from the beginning of the string. When used with lists, the right operand specifies the number of elements to be removed from the top of the list. |
>> | The >> is used for character- and bitwise shifting to the right. The >> operator can be used with strings, integers, currencies and lists. When used with strings, the right operand specifies the number of spaces inserted on the left side of the string. When used with lists, the right operand specifies the number of elements to be removed from the end of the list. |
Table 39: Calculation operators
Example |
@aaa = ["John", "James", "Jim", "Jamie"]; // So it is more efficient to use the difference: // Check if the last change of an object was carried out on the same date it was |
Note: If two different currencies are added or subtracted an implicit conversion is carried out. Following evaluation order is defined: The conversion table of the transaction variable TV_CURRCONVTAB is used. If TV_CURRCONVTAB is not available, the conversion table of the left operand is used. If not available, the conversion table of the right operand is used. Otherwise, an error is generated.
The +, -, *, / and % operators (concatenation, difference, union, symmetric difference, intersection) are supported for lists. The following example shows how list operators work.
Example |
[]+[1] == [1]; [1, 2, 3] - [2, 3, 4] == [1]; [1, 2, 3] * [2, 3, 4] == [1, 2, 3, 4]; [1, 2, 3] / [4, 5, 6] == [1, 2, 3, 4, 5, 6]; [1, 2, 3, 4] % [2, 3, 4] == [2, 3, 4]; |
The -, *, / and % operators (difference, union, symmetric difference, intersection) are supported for dictionaries. These operators work on an element level, the value of a dictionary entry is not relevant. The left operand dominates. The following example shows how dictionary operators work.
Example |
({}) - ({}) == ({}); ({}) * ({}) == ({}); ({}) / ({}) == ({}); ({}) % ({}) == ({}); |
Comparison operators allow you to compare two operands. The next table provides a summary of the supported comparison operators. The data type of the result is always BOOLEAN.
Operator | Description |
== | The equality operator compares two operands and indicates whether the value of the left operand is equal to the value of the right operand. The equality operator has a lower precedence than the relational operators (<, <=, >, >=). |
!= (alternatively <>) | The inequality operator compares two operands and indicates whether the value of the left operand is not equal to the value of the right operand. The inequality operator has a lower precedence than the relational operators (<, <=, >, >=). |
< | The relational operator < compares two operands and indicates whether the value of the left operand is less than the value of the right operand. |
<= | The relational operator <= compares two operands and indicates whether the value of the left operand is less than or equal to the value of the right operand. |
> | The relational operator > compares two operands and indicates whether the value of the left operand is greater than the value of the right operand. |
>= | The relational operator >= compares two operands and indicates whether the value of the left operand is greater than or equal to the value of the right operand. |
<=> | The relational operator <=> compares two operands. It returns -1 if the left value is lower and +1 if the left value is greater than the right value. If the values are equal, the result is 0. |
contains | The contains operator determines whether left operand contains the right operand. This operator can be used with string operands. It may be preceded by the not keyword. |
like | The like operator determines whether the left string matches the right string. The % and _ wildcards can be used in the right string operand. The like operator can be preceded by the sounds keyword for a phonetic comparison. Furthermore, it can also be preceded by the not keyword. |
The in operator determines whether the value of the left operand is an element of the list provided in the right operand. The in operator can also be used with a list in the left operand. It may be preceded by the not keyword. When using lists in both operands, the semantic is: [a1, a2, ... an] in [b1, b2, ... bm] -> (a1 == b1 or a1 == b2 or ... or a1 == bm) or This means, that the expression is true, if any element from the left operand is in the list of the right operand. Note:
| |
includes | The includes operator determines whether the value of the right operand is an element of the list provided in the left operand. It may be preceded by the not keyword. When using lists in both operands, the semantic is: [a1, a2, ... an] includes [b1, b2, ... bm] -> (a1 == b1 or a1 == b2 or ... or a1 == bm) and This means, that the expression is true, if all elements from the right operand are in the list of the left operand. Note:
|
between and | The between and operator determines whether the value of the first operand is in the range between the values of the operands provided after the keywords between and and. If the first operand is a list, then all values of the list must be between the second and the third operand. |
is null | The is null operator returns true if the value of the left operand is undefined. |
Table 40: Comparison operators
Example |
if (@points < 100) { // If @memberstatus is null this evaluates to true if (@nickname like "Bob%" or @nickname in ["Dick", "Rob"]) { |
The conditional operator ?: has three operands. It tests the result of the first operand, and then evaluates one of the other two operands based on the result of the evaluation of the first operand. If the evaluation of the first operand yields true, the second operand is evaluated. Otherwise, the third operand is evaluated.
Example |
@orders = (@customer != null) ? |
The selection operator [] can be used for the following purposes:
Note:
Example |
// Constructing an empty list // Constructing a list of string values // Selecting elements from a list // Selecting multiple elements from a list // Selecting elements starting from the end of the list by specifying negative indices // Example for filtering a list: This expression returns the orders that // Selecting a sub list // Selecting a sub list with negative elements // Specifying a parameter as the return value when invoking a use case // Results in the method object of the call // Results in all entries of the customization point CPSymbols |
By default, the Fabasoft Folio Kernel tries to interpret identifiers as references when evaluating expressions. In order to use an identifier that could also be a reference as name, it must be prefixed with $.
Note: The Fabasoft app.ducx compiler will attempt to automatically insert the symbol $ when serializing the expression, if it can determine the context in which the identifier is used. If it can’t calculate a definitive type, you will receive a warning.
For the following example, assume that the local scope contains a dictionary. objname can only be used as a variable when prefixed with $.
Example |
// Assuming the local scope contains a dictionary: // When omitting the "$", the expression is interpreted as follows: |
If you need to retrieve a component object in an expression, you must prefix its reference with #. In order to use an identifier that could also be a variable as reference, it must be prefixed with #.
Note: The Fabasoft app.ducx compiler will attempt to automatically full qualify an identifier to a reference when serializing the expression, if it can determine the context in which the identifier is used. If it can’t calculate a definitive type, you will receive a warning.
For instance, when referring to a property definition or an object class, you must prefix the reference with # in order to get the corresponding component object.
Example |
// Accessing property definition COOSYSTEM@1.1:objname // Accessing object class APPDUCXSAMPLE@200.200:Order // Accessing property of undeclared object |