13

Is it possible to pass an object function as a parameter in a procedure rather than passing the whole object?

I have a record definition with a function defined as a public class parameter such as:

    TMyRecord = record
      public
        class function New(const a, b: Integer): TMyRecord; static;
        function GiveMeAValue(inputValue: integer): Single;
      public
        a, b: Integer;
      end;

The function could be something like:

    function TMyRecord.GiveMeAValue(inputValue: Integer): Single;
    begin
      RESULT := inputValue/(self.a + self.b);
    end;

I then wish to define a procedure that calls on the class function GiveMeAValue but I don't want to pass it the whole record. Can I do something like this, for example:

    Procedure DoSomething(var1: Single; var2, var3: Integer, ?TMyRecord.GiveMeAValue?);
    begin
      var1 = ?TMyRecord.GiveMeAValue?(var2 + var3);
      //Do Some Other Stuff
    end;

If so then how would I correctly pass the function as a procedure parameter?

Trojanian
  • 692
  • 2
  • 9
  • 25

1 Answers1

24

You can define a new type for the function like

TGiveMeAValue= function(inputValue: integer): Single of object;// this definition works fine for methods for records.

then define the method DoSomething

Procedure DoSomething(var1: Single; var2, var3: Integer;GiveMeAValue: TGiveMeAValue);
begin
  writeln(GiveMeAValue(var2 + var3));
end;

And use like so

var
  L : TMyRecord;
begin
    l.a:=4;
    l.b:=1;
    DoSomething(1, 20, 5, L.GiveMeAValue);
end;
RRUZ
  • 134,889
  • 20
  • 356
  • 483
  • 2
    Alternatively, one can use Anonymous Methods. This could allow you to call any function you like inside the anonymous method. http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/devcommon/anonymousmethods_xml.html – Warren P Nov 06 '13 at 04:09
  • 3
    Anon methods make code more flexible. However, they can be a performance headache. Don't reject them without timing, but if you uses anon methods in a bottleneck area of your program, you may suffer. – David Heffernan Nov 06 '13 at 07:34
  • Good point. I personally find the `procedure-or-function of object` syntax more readable than the `reference to procedure-or-function of object` syntax too. writing `procedure (a,b,c:Integer) begin ... end` inline begins to get ugly. – Warren P Nov 06 '13 at 11:05
  • Your method reference uses 'Single of object' instead of just 'of object'. Are you just telling it to put the Self pointer in a Single? – Noumenon Jun 16 '15 at 15:48
  • @Noumenon, No, the `of object` means which the function is a reference to a method of an instance object. You can find more info in the [Delphi DocWiki](http://docwiki.embarcadero.com/RADStudio/XE8/en/Procedural_Types) – RRUZ Jun 16 '15 at 16:12
  • I actually spent quite a while researching "of object" and method references before asking, but I never saw anyone inserting a numeric type like "Single" before the "of object". What does that mean? – Noumenon Jun 16 '15 at 16:17
  • *Single* is just the return type of the function. – RRUZ Jun 16 '15 at 17:07
  • If I declare `Procedure DoSomething(var1: Single; var2, var3: Integer;GiveMeAValue: TGiveMeAValue = nil);`, how can I check if the caller actually passed a callback function so I can safely call it? Something like `if GiveMeAValue <> nil then GiveMeAValue(..);` – ricardomenzer Mar 29 '21 at 18:52