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
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
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
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
- 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
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
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
)
)