Skip to end of metadata
Go to start of metadata

The actions extension technique allows the developer to declare an abstract action in one module and add to it an implementation in other modules. This technique is essentially a "postponed definition" of a branch operator, where the operator’s title is defined when the property is declared, and branching conditions are added as new functionality (of classes or static objects) is added to the system. Furthermore, branching conditions (if branching is not mutually exclusive) can be added both to the beginning and to the end of the abstract action created. Similarly, this technique works with a sequence operator.

For abstract actions, the expected classes of parameters must be specified. Then the platform will automatically check that the added implementations match these classes. Also, if necessary, you can check that for all descendants of the parameter classes at least one implementation is specified (or exactly one, if the conditions are mutually exclusive).

Actions extension allows:

  • Implement the concept of action polymorphism by analogy with certain object-oriented programming languages.
  • Remove dependency between modules by adding specific "entry points," to which new behavior can be added later.

Polymorphic form

As with a branching operator, for an abstract action there is a polymorphic form, where it is possible not to define a condition explicitly, but to use as a condition matching the signature of the action that corresponds to this condition.

Mutual exclusion of conditions

As for a branch operator, you can specify that all conditions of an abstract action must be mutually exclusive. If this option is specified, and the conditions are not in fact mutually exclusive, the platform will throw the corresponding error.

It is worth noting that this check is no more than a hint to the platform (for better optimization), and also a kind of self-checking on the part of the developer. However, in many cases it allows to make the code more transparent and readable (especially in a polymorphic form of the abstract action).

Language

The key instructions that implement the extension technique are the ABSTRACT operator, for declaring an abstract action, and the ACTION+ instruction, for adding an implementation to it.

Examples

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 exportXls 'Export to Excel'  ABSTRACT CASE ( Order);         // In this case, ABSTRACT CASE OVERRIDE LAST is created
exportXls (Order o) + WHEN name(currency(o)) == 'USD' THEN { 
    MESSAGE 'Export USD not implemented';
} 

CLASS Task;
run 'Execute'  ABSTRACT ( Task);                           // ABSTRACT MULTI EXCLUSIVE

CLASS Task1 : Task;
name = DATA STRING[100] (Task);
run (Task1 t) + { 
    MESSAGE 'Run Task1 ' + name(t);
}


CLASS OrderDetail;
price = DATA NUMERIC[14,2] (OrderDetail);

CLASS InvoiceDetail;
price = DATA NUMERIC[14,2] (InvoiceDetail);
fill  ABSTRACT LIST ( OrderDetail, InvoiceDetail);   // ABSTRACT LIST LAST

fill (OrderDetail od, InvoiceDetail id) + { 
    price(id) <- price(od);
}

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
 CLASS ABSTRACT Animal;
whoAmI  ABSTRACT ( Animal);

CLASS Dog : Animal;
whoAmI (Dog d) + {  MESSAGE 'I am a dog!'; }

CLASS Cat : Animal;
whoAmI (Cat c) + {  MESSAGE 'I am a сat!'; }

ask ()  { 
    FOR Animal a IS Animal DO
        whoAmI(a); // a corresponding message will be shown for each object
}

onStarted  ABSTRACT LIST ( );
onStarted () + { 
    name(Sku s) <- '1';
}
onStarted () + { 
    name(Sku s) <- '2';
}
// first, the 1st action is executed, then the 2nd action

CLASS Human;
name = DATA STRING[100] (Human);

testName  ABSTRACT CASE ( Human);

testName (Human h) + WHEN name(h) == 'John' THEN {  MESSAGE 'I am John'; } 
testName (Human h) + WHEN name(h) == 'Bob' THEN {  MESSAGE 'I am Bob'; } 

  • No labels