Executable Action Language (EAL) lets you write data-changing actions in MDriven, and this page is for modelers who know or are learning OCL and need to implement behavior.
What EAL is
EAL extends Object Constraint Language (OCL) with imperative operations. OCL is declarative: it queries data and expresses rules without side effects. EAL performs side effects, such as assigning an attribute, creating an object, changing a collection, saving data, navigating a ViewModel, or calling an external API.
For example, this EAL action sets three values on the current object (self):
self.SomeDateTime := DateTime.Now;
self.SomeInt := 27;
self.SomeString := self.SomeDateTime.ToString('yyyy-MM-dd')
Use EAL when an operation must change state. Use OCL when an expression only needs to calculate, select, validate, or display a value.
| Need | Use | Example |
|---|---|---|
| Calculate or validate without changing data | OCL | A derived attribute calculates a total. |
| Change data or invoke an operation | EAL | A button creates an order and saves it. |
Where you use EAL
You can enter EAL in these MDriven locations:
- An Action execute expression.
- An execute expression on a ViewModel column.
- A class method implementation.
- A StateMachine effect.
For example, an Action execute expression can assign a status when a user invokes the action:
self.Status := 'Approved'
See EAL for the EAL overview and operator index.
Learn the core syntax
Assign values with :=
Use := to assign a value. Use = to compare values.
self.SomeInt := 27;
self.SomeInt = 27
The first expression changes SomeInt. The second expression evaluates whether SomeInt is 27.
Sequence statements with ;
Use a semicolon to separate statements that must run in sequence.
self.Name := 'Northwind';
self.IsActive := true
Do not add a trailing semicolon. The semicolon is valid only between statements. For example, 'a string';0 has the type of its final expression, integer. In contrast, 'a string';0; is invalid because EAL expects another statement after the final semicolon.
Create objects
Create an object with the class Create operation, then set its values or add it to an association.
let pktv = TaggedValue.Create in
(
pktv.Tag := 'PrimaryKey';
pktv.Value := 'true';
self.TaggedValue.add(pktv)
)
This example creates a TaggedValue, assigns its Tag and Value, and adds it to the current object's TaggedValue collection.
Use conditions and collections
EAL includes flow-control operations such as whentrue, whenfalse, and foreach. It also works with OCL collection expressions such as select and collect.
For example, this expression finds actions whose execute expression contains an old class name and replaces that name:
AbstractAction.allInstances->
select(aa|aa.ExecuteExpression.Contains('CalendarView'))->
collect(aa|aa.ExecuteExpression := aa.ExecuteExpression.Replace('CalendarView', 'ViewSetting'))
This changes model metadata. When you use EAL to refactor a model, validate the model after each change. For a guided example, see Rename a class in your model using the model debugger.
Continue learning
Learn EAL in this order:
- Learn OCL expressions, navigation, types, and collection operations.
- Practice assignment with
:=and statement sequencing with;. - Create and connect objects with
Createand collection operations such asadd. - Use conditions and iteration to apply an action to selected objects.
- Learn persistence, navigation, import/export, and external communication operators from EAL.
Common EAL tasks
| Task | Relevant EAL operations |
|---|---|
| Assign and sequence work | :=, ;
|
| Control flow | whentrue, whenfalse, foreach
|
| Manage objects | Create, delete, setToNull, deepclone
|
| Change collections | add, insertAt, remove, clear
|
| Work with persistence | Save, Refresh, Search, ReQuery
|
| Navigate the UI | Navigate, NavigateUrl, ExecuteAction
|
| Call external services | RestGet, RestPost, RestPut, RestPatch, RestDelete
|
Inheritance
When a class method overrides a base-class method, call the inherited implementation with self.base.MethodName.
For example, an OnCreate implementation on Person can call the base implementation before adding its own behavior:
self.base.OnCreate
See Calling base class for the complete example.
