You can use ScriptEval when you store an OCL expression as text and need to validate and evaluate that expression against the current model object.
Purpose
ScriptEval treats a string as an OCL expression. The expression runs in the context of the object that calls the operator, normally self.
Use it when an expression is data rather than fixed code. For example, an Order can hold a formula in a string attribute, and a ViewModel action can calculate that formula for the current Order.
Before evaluating an expression, use ScriptEvalCheck. It verifies that the text is valid in the current context and that its result has the return type you declare.
Operators
| Operator | Purpose | Result |
|---|---|---|
ScriptEvalCheck(false, ReturnType, ExpressionText)
|
Validates an expression string in the current context. | 'ok' when the expression is valid; otherwise, an error description.
|
ScriptEval(false, ReturnType, ExpressionText)
|
Evaluates an expression string in the current context. | The evaluated value, with the declared return type. |
ReturnType is required. Declare the type that the expression must return, such as Double or Decimal. The expression must return that type; otherwise, ScriptEvalCheck reports the type error.
Validate before you evaluate
Use this pattern whenever the expression text can be invalid:
- Store the expression text in a String attribute.
- Call
ScriptEvalCheckwith the expected return type. - Evaluate with
ScriptEvalonly when the check returns'ok'. - Store or display the validation message when the check fails.
The following expression validates self.SomeString as a Double expression. If it is valid, the evaluated value is converted to a string and assigned to vSomeStringResult. If it is invalid, the validation message is assigned instead.
let info=self.ScriptEvalCheck(false,Double, self.SomeString) in
(
vSomeStringResult:=(info='ok').casetruefalse(
self.ScriptEval(false,Double, self.SomeString).asstring,
info
)
)For example, when SomeString contains the following text, the expression is evaluated in the context of self:
0.2222+self.SomeInt+self.SomeDateTime.TicksThis expression uses attributes of the current object: SomeInt and SomeDateTime.
Example: evaluate an Order formula
This example keeps an Order calculation as text, then executes it from a ViewModel action. The action writes either the calculation result or the validation error to a visible attribute.
Model attributes
Add these attributes to the Order class:
| Attribute | Type | Purpose |
|---|---|---|
DynamicFormula
|
String, derived | Holds the OCL expression text to evaluate. |
FormulaResult
|
String, persistent | Holds the evaluated result or the validation message. |
For example, set DynamicFormula to:
self.Total * 0.10.ToDecimalViewModel action
Create a ViewModel action, for example a button labelled SCRIPT EVAL CHECK, and place the following Executable Action Language (EAL) code in that action:
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 let operator stores the check result so that the action can use it in both branches; see Documentation:OCLOperators let. The assignment operator := writes the result to FormulaResult.
Expected result
If Order.Total is 50.00 and DynamicFormula is self.Total * 0.10.ToDecimal, running the action writes 5.0 to FormulaResult.
If the formula has an invalid operation, the action does not evaluate it. Instead, FormulaResult receives the message returned by ScriptEvalCheck. For example, multiplying a Decimal Total by an unconverted 0.10 can produce a message stating that no version of * accepts those parameter types.
Type rules and troubleshooting
- Match the declared type. If you call
ScriptEvalCheck(false, Decimal, ...), write an expression that returns a Decimal. - Make constant types explicit when needed. In the Order example,
0.10.ToDecimalaligns the constant with a DecimalTotal. - Evaluate only after a successful check.
ScriptEvalCheckgives the user or developer an actionable error message without attempting the evaluation. - Remember the context. The expression text runs for the calling object. In
self.Total * 0.10.ToDecimal,selfis the current Order. - Convert for display deliberately. The examples use
.asstringbecauseFormulaResultandvSomeStringResultare String values.
For general OCL syntax and available operators, see Documentation:OCL General Operators and Documentation:OCL Boolean Operators.
