Method Access & Calls
Methods of a Class, Record or Interface can be accessed simply by specifying their name.
For methods of the current type (i.e. the class or record that the current code is also a part of), simply the name of the method on its own suffices to access it. To access methods on a different type (or a different instance of the same type), a Member Access Expression is used, appending an
: to the expression that represents the instance, followed by the method name.
By default, accessing a method means to call it, unless the expression is preceeded by an
@ Address-Of operator, or the surrounding context suggests that the address of the method is expected. More on that below.
Parameter-less methods can be called with just their name, or an optional empty set of parenthesis (
()). For methods that require parameters, these must be provided in parenthesis after the method name:
type Foo = public class private method Print; method Update(aValue: String); public method Test(aBar: Bar); begin Print; Update(aBar.Name); aBar.NortifyOfUpdate(self); end; end;
In the above example,
Update can be called directly, as methods on the current instance of the class. A Member Access Expression is used to call the
NortifyOfUpdate method on
aBar – a different object.
self to Avoid Ambiguity
self expression can be used to explicitly access a method on the current instance, in cases where the name of the field is hidden by a different identifier in scope:
method Test(aBar: Bar); begin var Print := new StarryNight(5, 10); ... self.Print; end;
In the above example, the local
lPrint) hides the
self keyword it can still be called. In this case simply adding parenthesis,
Print(), would also have resolved the ambiguity.
Methods might be defines with generic parameters. In most cases, these can be inferred from parameters of the method call, but sometimes it might be necessary to explicitly specify them, using angle brackets between the method name and the (optional) parameter list:
var x := lStringList.Select<Integer>(s -> length(s));
The above example would compile without the explicit
<Integer> because the type can be inferred from the code in the Lambda Expression, but it is good to have the option to be explicit.
Multi-Part Method Names
Methods can have Multi-part Method Names that give a more expressive description for individual parameters. The individual parts of the method name will be used for the call in the same way as they are in the declaration, with each part being followed by a set of parenthesis containing a subset of parameters:
lObject.RunCommand('ebuild') Arguments('MyProject.sln', '--configuration:Debug');
If the last parameter of a Method (or Constructor) is a Block type used as a callback, rather than passing a method name or Anonymous Method, the block can follow the method call as a "trailing closure". This allows for a more natural integration of the callback into the flow of code and essentially makes the method call feel more like a native language construct being followed by an
The following snippet shows a call to
dispatch_async with a trailing closure:
dispatch_async(dispatch_get_main_queue) begin // do work on the main thread end;
If the closure receives any parameters, their names will be inferred from the declaration of the method or the Block type used in the declaration, and become available as if they were local identifiers:
remoteAdapter.beginGetDataTablewWithSQL('SELECT * FROM FOO') begin writeLn(table) end;
To avoid ambiguity, trailing closures are not supported inside
ensure clauses of Class Contracts.
Getting the Address of a Method
Sometimes, instead of calling a method, one needs to obtain its address – typically to assign to an Event or pass it as a Block. There are two ways to achieve this.
Preceding the method access expression with the
@ Address-Of operator will always return its address:
var m := @lMyObject.Foo; // get the address ... m(); // call it, later
Alternatively the compiler will also infer that the address of the method is requested, based on the context the method access expression is used in – for example when assigning to a Block type variable/parameter or to an event via
Button.Click += OnClick; var callback: block := OnSuccess;
Note that parenthesis after the method name are not permitted when obtaining a method's address. In fact, specifying either
@ or an empty set of
() can resolve (rare) ambiguities where both the methods address or its result would be valid (for example, if the method's return value is a block of the same type as the method itself).
- Assign Statements
- Member Access Expressions