You can evaluate an OCL expression stored as text at run time when you need configurable formulas and clear validation feedback in a Turnkey user interface.
ScriptEval is an operator on a model object, called the context, that evaluates an expression held in a String attribute. Use ScriptEvalCheck first to verify that the text is valid in that context and returns the required type.
When to use ScriptEval[edit source]
Use ScriptEval when the expression is data rather than fixed model code. For example, an Order can store a configurable discount formula in DynamicFormula:
self.Total * 0.10.ToDecimalThe formula is evaluated with the Order as self, so self.Total resolves to that Order's Total attribute.
Do not use ScriptEval for database-side evaluation of large data sets. For database-computed ViewModel columns, use PSExpressions instead.
Validate before evaluating[edit source]
ScriptEvalCheck validates the expression text in the supplied context. You must provide the expected return type. It returns 'ok' when the expression is valid and returns that type; otherwise, it returns an error message.
| Operator | Purpose | Result |
|---|---|---|
self.ScriptEvalCheck(false, Decimal, self.DynamicFormula)
|
Validate expression syntax, context, and return type. | 'ok' or an error message.
|
self.ScriptEval(false, Decimal, self.DynamicFormula)
|
Evaluate validated expression text. | The expression result, as the declared return type. |
The return type is required and must match the expression result. For example, use Decimal for an expression that returns a Decimal, and Double for an expression that returns a Double.
Store a formula result and validation message[edit source]
This example uses two attributes on an Order class:
| Attribute | Type | Purpose |
|---|---|---|
DynamicFormula
|
String, derived | Holds OCL code as text, for example self.Total * 0.10.ToDecimal.
|
FormulaResult
|
String, persistent | Stores either the evaluated value or the validation error message. |
Create a Executable Action Language (EAL) action in a ViewModel and set its expression to the following code:
let validationInfo = self.ScriptEvalCheck(false, Decimal, self.DynamicFormula) in
(
if validationInfo = 'ok' then
self.FormulaResult := self.ScriptEval(false, Decimal, self.DynamicFormula).asstring
else
self.FormulaResult := validationInfo
endif
)The assignment operator := writes the result to FormulaResult. This is an EAL action because it changes an attribute. A regular OCL expression must have no side effects.
Add the action to a ViewModel[edit source]
- In MDriven Designer, add
DynamicFormulaandFormulaResultto the Order class. - Create an Order ViewModel that displays both attributes.
- Add an action, for example labelled
SCRIPT EVAL CHECK. - Enter the EAL code in the action's ExecuteExpression. A ClassAction uses
selfas the current Order. For other action contexts, use the context variables available to the action. - Run the Turnkey application, enter a formula, and invoke the action.
Type alignment example[edit source]
If Total is Decimal, this formula has aligned numeric types:
self.Total * 0.10.ToDecimalWith Order.Total set to 50.00, the action stores 5.0 in FormulaResult.
This formula can fail validation because 0.10 is a Double while Total is Decimal:
self.Total * 0.10In that case, ScriptEvalCheck returns an error such as There is no version of * that takes these parameter types. The example action stores that message in FormulaResult rather than attempting evaluation.
Context example[edit source]
The expression text can navigate from its context object. With self as the context, the following expression returns a numeric result:
0.2222 + self.SomeInt + self.SomeDateTime.TicksDeclare the matching expected type when checking and evaluating it. For a Double result:
let info = self.ScriptEvalCheck(false, Double, self.SomeString) in
(
vSomeStringResult := (info = 'ok').casetruefalse(
self.ScriptEval(false, Double, self.SomeString).asstring,
info
)
)