DelphiScript - Functions and Procedures

Applies to TestComplete 14.40, last modified on April 22, 2021

This topic contains basic information about the syntax used for DelphiScript functions and procedures.

Return Values

To return a value from a function, use Result instead of the function name. Using the function name will cause an error:

DelphiScript

function Calc(x, y) : Integer;
begin
  Calc := (x - y) * (x + y); // Error !!!
  Result := (x - y) * (x + y); // Correct variant
end;

Nested Routines

In Object Pascal, the body of a function or a procedure can contain declarations of other functions and procedures:

Delphi

procedure FuncA;
 
  procedure FuncB;
  begin
     {do something}
  end;
  ...
begin
  ...
end;

In DelphiScript scripts that are run from TestComplete, nested routine declarations are not allowed.

Variable Names

The names of script variables cannot coincide with the names of Delphi keywords regardless of whether this keyword is supported or not supported by DelphiScript. For instance, you cannot use the variable named Message in your scripts, this will cause an error:

DelphiScript

procedure Test;
var
Message : OleVariant; // <-- Error!
begin
end;

Delphi Functions Support

The support of some Delphi functions are built-in in DelphiScript. Some other Delphi routines are provided by the Utilities programming object. This object is available if the Utilities plugin is installed. The plugin “registers” Delphi functions in TestComplete and makes them available to your script code. If the plugin is not installed, calls to Delphi routines outside of System will not be supported. The interpreter will not recognize them, and post an error message when it meets an “unknown” identifier.

Unsupported Delphi Routines

The following Delphi routines are not supported in DelphiScript:

Abort
Addr
Assert
Dispose
Finalize
Hi
High
Initialize
Lo
Low
New
Ptr
SetString
SizeOf
Str
UniqueString
VarArrayRef
VarCast
VarCopy

Default Values of Routine Parameters

You can specify default values for routine parameters using the same syntax you would use in Delphi. For instance, the following declaration specifies the default value for the Param2 parameter:

DelphiScript

function TestA(Param1, Param2 : OleVariant = 100);

According to this declaration, the two following function calls are equivalent:

DelphiScript

TestA(20, 100);
TestA(20);

Note that you must specify a data type for parameters with default values. The data type is ignored, but the DelphiScript syntax parser requires something between the parameter name and the default value.

The default value must be a constant. It can be neither an array, nor an object. It is possible to use expression as default parameter value:

DelphiScript

const MyConst=5;
function TestB(Param1 : OleVariant = 100 + MyConst);

Parameters with default values must be at the end of the parameter list. That is, the following declaration is incorrect:

DelphiScript

// Incorrect!!!
function TestB(Param1 : OleVariant = 20; Param2);

To specify default values for both Param1 and Param2, use the following declaration (note that we separate parameters with a semicolon, not a comma):

DelphiScript

// Correct
function TestB(Param1 : OleVariant = 20; Param2 : OleVariant = 100);

If all of the routine’s parameters are optional and you want to omit them during the routine call, then you must omit the parenthesis as well:

DelphiScript

TestB;    // Correct variant

TestB();  // Error!!!

If the routine that has default parameter values is forward-declared, you must specify the default parameter values in the forward declaration as well, and they must be the same as the one specified in the routine implementation. That is, you cannot override the default parameter values:

DelphiScript

function TestA(Param1, Param2 : OleVariant = 100); forward;
...

function TestA(Param1, Param2: OleVariant = 50); // Error !!!
begin
  Result := Param1 + Param2;
end;

However, if you have specified default parameter values in the routine’s forward declaration, you can omit default values from the routine implementation:

DelphiScript

function TestA(Param1, Param2 : OleVariant = 100); forward;
...

function TestA(Param1, Param2);
begin
  Result := Param1 + Param2;
end;

Passing Routine Parameters by Reference

Like in Delphi, you can pass parameters to DelphiScript routines by value, reference or as out parameters.

Parameters passed by value are similar to local variables. The routine creates a local copy of this parameter, initializes it with the specified value and then works with the local copy. So, changes made to the parameter value within the routine body do not affect the original variable. Parameters specified with the var keyword are passed by reference. Unlike parameters passed by value, changes made to reference parameters within the routine body are made to the original variable.

The example below demonstrate the difference between parameters passed by value and by reference. The IncByVal and IncByRef functions return the same result (parameter value plus 1), however the IncByRef function does change the value of a variable that has been passed to it.

DelphiScript

function IncByVal (x);
begin
  x := x + 1;
  Result := x;
end;

function IncByRef (var x);
begin
  x := x + 1;
  Result := x;
end;

procedure Main;
var a, b, a2, b2 : OleVariant;
begin
  a := 2;
  b := 2;
  a2 := IncByRef(a);
  Log.Message('a = ' + aqConvert.VarToStr(a) + ' a2 = ' + aqConvert.VarToStr(a2));    // a = 3, a2 = 3
  b2 := IncByVal(b);
  Log.Message('b = ' + aqConvert.VarToStr(b) + ' b2 = ' + aqConvert.VarToStr(b2));    // b = 2, b2 = 3
end;

Out parameters are similar to parameters passed by reference. The difference is that out parameters are only used to return data from the routine and not to pass it to:

DelphiScript

procedure Copy (x; out y);
begin
  y := x;
end;

procedure Main;
var a: OleVariant;
begin
  Copy(10, a);
  Log.Message(aqConvert.VarToStr(a));  // a = 10
end;

Since reference and out parameters can be used to return data from routines, you can use them to create routines that have several return values:

DelphiScript

function Test (x; var doublex, squaredx);
begin
  doublex  := 2 * x;
  squaredx := x * x;
end;

procedure Main;
var x, y, z: OleVariant;
begin
  x := 5;
  Test(x, y, z);
  Log.Message(y);  // y = 10
  Log.Message(z);  // z = 25
end;

Note that since reference and out parameters can be assigned, you can only pass variables, not constant values in routine calls:

DelphiScript

procedure IncParam (var x);
begin
  x := x + 1;
end;

procedure Main;
var a : OleVariant;
begin
  a := 1;
  IncParam(a);    // Correct
  IncParam(5);    // Error!!!
end;

See Also

DelphiScript Description

Highlight search results