Difference between revisions of "How to use procedural variables"
From Lazarus wiki
Jump to navigationJump to searchDaniel-fpc (talk | contribs) m (How To Use Function Pointers moved to How to use procedural variables: Function pointers are C terminology. No IniCaps in title.) |
m (Actually add page template :-) |
||
(12 intermediate revisions by 7 users not shown) | |||
Line 1: | Line 1: | ||
− | + | {{How_to_use_procedural_variables}} | |
+ | Copy the text below and it will demonstrate the use of procedural variables, this is a fully working program. You don't even need to understand how it works. The syntax is pretty simple. | ||
− | + | <syntaxhighlight lang=pascal> | |
− | + | program Test; | |
− | |||
− | < | ||
− | program | ||
{$mode objfpc}{$H+} | {$mode objfpc}{$H+} | ||
Line 13: | Line 11: | ||
cthreads, | cthreads, | ||
{$ENDIF}{$ENDIF} | {$ENDIF}{$ENDIF} | ||
− | Classes | + | Classes; |
− | + | ||
− | //Make the Types the type corresponds to a function signature | + | // Make the Types the type corresponds to a function signature |
type | type | ||
− | + | TFuncNoArgsString = function(): String; | |
− | + | TFuncOneArgsString = function(x: string): string; | |
− | // | + | // Example functions |
− | function Hello | + | function Hello: String; |
begin | begin | ||
− | + | Result := 'Hello There'; | |
end; | end; | ||
− | function Woah(G:String):String; | + | |
+ | function Woah(G: String): String; | ||
begin | begin | ||
− | + | Result := 'Woah ' + G; | |
end; | end; | ||
− | // | + | // Overloaded function takes the two types of function |
− | //pointers created above | + | // pointers created above |
− | procedure Take(f: | + | procedure Take(f: TFuncNoArgsString); overload; |
begin | begin | ||
− | + | WriteLn(f()); | |
end; | end; | ||
− | procedure Take(f: | + | procedure Take(f: TFuncOneArgsString); overload; |
begin | begin | ||
− | + | WriteLn(f('there!!!')); | |
end; | end; | ||
var | var | ||
− | + | ptr: Pointer; | |
− | + | List: TList; | |
begin | begin | ||
− | // the "@" symbol turns the variable into a pointer. | + | // the "@" symbol turns the variable into a pointer. |
− | // This must be done in order pass a function as a | + | // This must be done in order pass a function as a |
− | // | + | // parameter. This also demonstrates that pascal |
− | // keeps track of the pointer type so the overloading works! | + | // keeps track of the pointer type so the overloading works! |
− | Take(@Hello); | + | Take(@Hello); |
− | Take(@Woah); | + | Take(@Woah); |
− | // | + | // Now put a function in an untyped pointer |
− | ptr:=@Hello; | + | ptr := @Hello; |
− | //Type the pointer and call it all at the same time | + | // Type the pointer and call it all at the same time |
− | + | WriteLn(TFuncNoArgsString(ptr)); | |
− | //A | + | // A TList Example |
− | + | List := TList.Create; | |
− | + | List.Add(@Hello); | |
− | + | WriteLn(TFuncNoArgsString(List[0])); | |
− | + | ReadLn; | |
− | end. | + | end.</syntaxhighlight> |
− | </ | ||
− | ---- | + | With <code>{$modeswitch classicprocvars+}</code> the [[@|<code>@</code>-address-operator]] is not necessary to refer to methods. |
+ | Also, if you are using the <code>@</code>-address-operator usage of <code>{$typedaddress on}</code> is advised in order to prevent programming mistakes. |
Latest revision as of 07:30, 17 February 2020
│
English (en) │
Copy the text below and it will demonstrate the use of procedural variables, this is a fully working program. You don't even need to understand how it works. The syntax is pretty simple.
program Test;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Classes;
// Make the Types the type corresponds to a function signature
type
TFuncNoArgsString = function(): String;
TFuncOneArgsString = function(x: string): string;
// Example functions
function Hello: String;
begin
Result := 'Hello There';
end;
function Woah(G: String): String;
begin
Result := 'Woah ' + G;
end;
// Overloaded function takes the two types of function
// pointers created above
procedure Take(f: TFuncNoArgsString); overload;
begin
WriteLn(f());
end;
procedure Take(f: TFuncOneArgsString); overload;
begin
WriteLn(f('there!!!'));
end;
var
ptr: Pointer;
List: TList;
begin
// the "@" symbol turns the variable into a pointer.
// This must be done in order pass a function as a
// parameter. This also demonstrates that pascal
// keeps track of the pointer type so the overloading works!
Take(@Hello);
Take(@Woah);
// Now put a function in an untyped pointer
ptr := @Hello;
// Type the pointer and call it all at the same time
WriteLn(TFuncNoArgsString(ptr));
// A TList Example
List := TList.Create;
List.Add(@Hello);
WriteLn(TFuncNoArgsString(List[0]));
ReadLn;
end.
With {$modeswitch classicprocvars+}
the @
-address-operator is not necessary to refer to methods.
Also, if you are using the @
-address-operator usage of {$typedaddress on}
is advised in order to prevent programming mistakes.