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:
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;