Certain important constructs
No edit summary
No edit summary
 
(6 intermediate revisions by 2 users not shown)
Line 80: Line 80:
|When you are in the context of an object, you can use the variable self to access the properties of this.
|When you are in the context of an object, you can use the variable self to access the properties of this.
|}
|}
You may define methods in classes to and implement these with OCL:
You may define methods in classes too and implement these with OCL:


[[File:Constructs image 1.png|frameless]]
[[File:Constructs image 1.png|frameless|402x402px]]


You will in the OCL implementation in the Body-property:
You will in the OCL implementation in the Body-property:


[[File:Constructs image 2.png|frameless]]
[[File:Constructs image 2.png|frameless|459x459px]]


Notice that since this was a method MDriven will treat you OCL as EAL – something that is allowed to have side effects.
Notice that since this was a method, MDriven will treat your OCL as EAL – something that has side effects.


In this case our method do not have any side effects and I may want to be able to use this method in OCL.
In this case, our method does not have any side effects and I may want to be able to use this method in OCL.


But trying to use it in OCL will not succeed. Methods with side effects are not recognized by OCL . There is a flag on the Method definition called IsQuery and if this is set we “promise” that it does not have intentional side effects. Now it is seen by OCL:
But trying to use it in OCL will not succeed. Methods with side effects are not recognized by OCL. There is a flag on the Method definition called IsQuery and if this is set we “promise” that it does not have intentional side effects. Now it is seen by OCL:


[[File:Constructs image 3.png|frameless]]
[[File:Constructs image 3.png|frameless|464x464px]]


We can then use our IsQuery method in any expression in OCL. <code>Thing.allinstances->select(x|x.MyMethod(x.SomeInt))</code>
We can then use our IsQuery method in any expression in OCL. <code>Thing.allinstances->select(x|x.MyMethod(x.SomeInt))</code>
== EAL differences ==
When using EAL one often want to stack expressions after each other. To allow for this EAL has introduced an expression separator: The semicolon “;”. This means that you can build method bodies that do several things like this:
self.SomeDateTime := DateTime.Now;
self.SomeInt := 27;
self.SomeString := self.SomeDateTime.ToString('yyyy-MM-dd')
In EAL we use := to assign but = to compare.
In EAL we can also create new objects Thing.Create
Worth noting is that the expression separator “;” can only be used between statements. So writing this ‘a string’;0 is of type integer. But writing this ‘a string’;0; is of unknown type and hence wrong – the last statement that the parser expect after the last ; is not found.
== OCLps differences ==
OCLps is a subset of OCL. No side effects, and you cannot use your methods even if they are marked with IsQuery. The collect, groupby and other operators that return tuples are not supported. The reason is that the main use of OCLps is to return a list of identities based some criteria’s from select or difference or the like. Once MDriven has the set of identities we will load the corresponding objects – then you can take over with normal OCL.


== Summary OCL ==
== Summary OCL ==
I often get the question if OCL is capable of doing everything we need to do in a line of business application. The answer is that as long as the arguments and result is representable in your model – yes it will do anything. Sometimes you have external or ambient data not accessible from the model – then you cannot use OCL – until you make that data available.
I am often asked if OCL is capable of doing everything we need to do in a line of business application. The answer is that as long as the arguments and result are representable in your model – yes it will do anything. Sometimes you have external or ambient data not accessible from the model – then you cannot use OCL – until you make that data available.


Not only can you do everything you need – it also comes out in small easily interpreted snippets of text that very much looks just like the requirements you are set to implement.
Not only can you do everything you need – it also comes out in small easily interpreted snippets of text that very much looks just like the requirements you are set to implement.


I like to compare OCL and modeling with Calculus. In math you can discuss numbers and operators on those number in plain language – but you seldom do since it will be error prune and require you to use a lot of words for even simple things. Instead everyone actually doing math uses calculus notation to write up expressions. The expressions are often reduced to the smallest possible – so that they are easily understood and ready to be used for a purpose.  
I like to compare OCL and modeling with Calculus. In math you can discuss numbers and operators on those numbers in plain language – but you seldom do since it will be error prone and require you to use a lot of words for even simple things. Instead, everyone actually doing math uses calculus notation to write up expressions. The expressions are often reduced to the smallest possible – so that they are easily understood and ready to be used for a purpose.
 
Use OCL for the same reason but not on only numbers but on all your designed information. Imagine a world without a good way to declaratively work with math. In this world, we would probably not have been able to do much cool technology. The ability to convey compact math between people is very good for mankind. I am certain that a good compact way to convey rules on information is equally important – if not even more usable – for mankind.


Use OCL for the same reason but not on only numbers but on all your designed information. Imagine a world without a good way to declaratively work with math. In this world we would probably not have been able to do much cool technology. The ability to convey compact math between people is very good for mankind. I am certain that a good compact way to convey rules on information is equally important – if not even more usable – for mankind.
The MDriven Book - See: [[Training:Seeker view|Seeker view]]
[[Category:OCL]]
[[Category:OCL]]
[[Category:The MDriven Book]]
[[Category:The MDriven Book]]

Latest revision as of 05:29, 3 April 2024

Some constructs are more returning than others as an everyday business developer with MDriven. Your favorite ways to express yourself may be different from mine but these are some of my returning expressions:

let z= Things.allinstances- >select(x|x.someInt>3)->size in

(

If z>4 then

‘There are more than 4

Things with SomeInt>3’

else

‘There are ‘+z.asstring+’

Things with SomeInt>3’

endif

)

I use the “let” construct to assign a result of an expression to a temporary variable. This is so I do not need to repeat myself in the testing of z>4 and the z.asstring.
Thing.allinstances-

>groupby(x|x.SomeValue)

Groupby - this expression has the type Collection(SomeValue:ValueStore+List:Collection(Thing)) so I get a list of SomeValue and for each a list of the things that use it.
Thing.allinstances-

>collect(x|x.SomeValue.UsedB

y.SomeInt->sum,

x.SomeValue.UsedBy-

>collect(y|x, y.Details))

Nested collecting. This expression gets the type Collection(Part1:System.Int32+Part2:Collection(Thing:Thing+Det ails:Collection(Detail))). The ability to nest collections is very powerful. In this case, I start with all Things – grab the SomeValue valueStore– check what other things have this set via the association MultiValuePick, and for these, I sum up all SomeValue plus grab the Details. This kind of multi-level collect-usage is very handy when summarizing deep object hierarchies on different levels.
' '.Chars(0) This expression returns System.Char. Since OCL has no literal way to input a single character – it is always interpreted as string – this trick will help when calling certain .net functions that take characters as arguments.
if true then

'this returns a string'

else

0.asstring

endif

All return paths must result in the same type. Since OCL is a functional language we must be consistent. This is one way to get the expression correct; add.asstring after the zero
Thing.allinstances-

>select(someint>3)

ValueStore.allinstances-

>select(usedby-

>notEmpty).Thing

Like this:

Thing.allinstances-

>select(someint>3)

->intersection(

ValueStore.allinstances-

>select(usedby-

>notEmpty).Thing

)

Working with OCLps – expressions that will be translated into SQL and executed in a database- it is sometimes easier to do one expression per complex constraint and at the end intersect all the expressions together.
self When you are in the context of an object, you can use the variable self to access the properties of this.

You may define methods in classes too and implement these with OCL:

Constructs image 1.png

You will in the OCL implementation in the Body-property:

Constructs image 2.png

Notice that since this was a method, MDriven will treat your OCL as EAL – something that has side effects.

In this case, our method does not have any side effects and I may want to be able to use this method in OCL.

But trying to use it in OCL will not succeed. Methods with side effects are not recognized by OCL. There is a flag on the Method definition called IsQuery and if this is set we “promise” that it does not have intentional side effects. Now it is seen by OCL:

Constructs image 3.png

We can then use our IsQuery method in any expression in OCL. Thing.allinstances->select(x|x.MyMethod(x.SomeInt))

Summary OCL

I am often asked if OCL is capable of doing everything we need to do in a line of business application. The answer is that as long as the arguments and result are representable in your model – yes it will do anything. Sometimes you have external or ambient data not accessible from the model – then you cannot use OCL – until you make that data available.

Not only can you do everything you need – it also comes out in small easily interpreted snippets of text that very much looks just like the requirements you are set to implement.

I like to compare OCL and modeling with Calculus. In math you can discuss numbers and operators on those numbers in plain language – but you seldom do since it will be error prone and require you to use a lot of words for even simple things. Instead, everyone actually doing math uses calculus notation to write up expressions. The expressions are often reduced to the smallest possible – so that they are easily understood and ready to be used for a purpose.

Use OCL for the same reason but not on only numbers but on all your designed information. Imagine a world without a good way to declaratively work with math. In this world, we would probably not have been able to do much cool technology. The ability to convey compact math between people is very good for mankind. I am certain that a good compact way to convey rules on information is equally important – if not even more usable – for mankind.

The MDriven Book - See: Seeker view

This page was edited 45 days ago on 04/03/2024. What links here