To generate an empty implementation from the method definitions press Ctrl + Shift + C.
The generated method looks like this:
The MyClass. prefix tells the compiler to which class the method belongs - this is needed because you can define more than one class in the file.
Between the begin and end; statements you can write your implementation, by example when this method has to:
- return the string representation of the result of 100 divided by the integer parameter
- but only when the parameter is bigger than zero (otherwise a custom error is thrown)
- and only when the result is bigger than 10 (otherwise a custom error is thrown)
The implementation will be:
When the result was smaller than 10 or when the parameter smaller or equal to zero, a custom exception (error) is thrown.
Note that, when you use the keyword Exit, the function exits immediately - any code following it won't be executed anymore. And when an exception is raised, the method is also immediately terminated - without result, and the exception should be catched by an error handler that is defined in the calling chain - if not, the program will terminate with this exception.
Exception handling is a topic for a future post where I will explain it further.
When the check p > 0 is a requirement to run this method, in other words when a call to this method with a value of p <= 0 is considered as a bug then a contract should be used.
A contract specifies the expected state of the parameters (and or other class states) that are required to run this method. The example above with an implemented contract for the parameter p looks as following:
If a result smaller or equal to 10 is also considered a bug then we can check this in a contract too:
In this example I use the result variable instead of Exit. The result variable is always available in any function and has the same type as the return type of the function.
When the function completes without an exit statement, the value of the result variable is returned to the caller.
Because the result will be smaller than 10 as soon as p > 10, we could also have written:
You see that the boolean check in the require contract exists out of 3 values instead of 2 as normal. This is the way you can write a boolean between test anywhere in Oxygene.
You can add as may checks as you want to both the require and ensure checks - all checks must be in the form of a boolean expression and an assertion is raised when one or more checks do not pass.
The require and ensure checks are not executed in a release build making sure that the checks do no slow down the released version, but are only used during the development and debug stage.
I personally find the contracts really awesome!
Next post will be about the Field definitions and constants - see you there.