Procedures as variables 
Author Message
 Procedures as variables

Is it possible to define a procedure as a variable so that I can do this:

Function(variable:Procedure)
Begin
  Variable;
End;

I want to put the name of a procedure into a variable so I can start the
procedure from a function....



Wed, 18 Jun 1902 08:00:00 GMT  
 Procedures as variables
You can put procedures addresses into pointer-type varibles:

Procedure Something;
begin
end;

var p:pointer;

begin

end.

But i don't knw the offical way to call a procedure by pointer.

Quote:

> Is it possible to define a procedure as a variable so that I can do this:

> Function(variable:Procedure)
> Begin
>   Variable;
> End;

> I want to put the name of a procedure into a variable so I can start the
> procedure from a function....



Wed, 18 Jun 1902 08:00:00 GMT  
 Procedures as variables

Quote:

> I want to put the name of a procedure into a variable so I can start the
> procedure from a function....

Look in the help index under procedural type, it will explain
everything you need to know (I hope).

Regards,
Hanford



Wed, 18 Jun 1902 08:00:00 GMT  
 Procedures as variables


Quote:
> Is it possible to define a procedure as a variable so that I can do this:

> Function(variable:Procedure)
> Begin
>   Variable;
> End;

> I want to put the name of a procedure into a variable so I can start the
> procedure from a function....

Yes, like this:

Type
  tSomeProcedure = Procedure(...params...);

Function (Proc:tSomeProcedure);
Begin
  ...
  Proc(...params...);
  ...
End;

where (...params...) is of course replaced by a valid parameter list.

Define a type for the procedure and its parameters, then define a parameter
of that type in your function. Call the procedure by using the name of your
function parameter. This is actually a pointer to a procedure, unfortunately
with the ^ removed where the procedure is called, so NIL could be passed in.


An example:

Function Sum(i1, i2:Integer):Integer; Far;
Begin
  Sum := i1+i2;
End;

Function Differ(x1, x2:Integer):Integer; Far;
Begin
  Differ := x1-x2;
End;

Type
  tOperate = Function(i1, i2:Integer):Integer;
    { procedure type for doing some operation on 2 integers
    }
  tDisp = Procedure(i:Integer);
    { procedure to display an integer
    }

Procedure WriteInt(n:Integer); Far;
Begin
  Writeln(n);
End;

Procedure ArrowInt(z:Integer); Far;
Begin
  Writeln('---> ',z,' <---');
End;

Procedure DoStuff(a, b:Integer; op:tOperate; disp:tDisp);
Begin

    op := Sum;
  Disp(op(a,b));
End;

begin
  DoStuff(1, 2, NIL, WriteInt); { 3 }
  DoStuff(1, 2, sum, ArrowInt); { ---> 3 <--- }
  DoStuff(1, 2, differ, ArrowInt); { ---> -1 <--- }
End.

Notes:
1. The procedures and functions passed as arguments may be defined before or
after the procedure type used to pass them: Sum and Differ are defined
before tOperate, while WriteInt and ArrowInt are defined after tDisp.

2. The parameter types must match those in tDisp and tOperate, but their
names can differ.

3. The procedures and functions must be defined as Far, so that they will
return properly; this can be done by declaring them in the interface section
of a unit, by using {$F+} or by using the Far keyword. The Far keyword is
IMHO preferable to {$F+} but is not supported before v7 of TurboPascal.

4. DoStuff checks the address of Op and defaults to Sum if none is passed.
Disp is always assumed to be valid. Assumptions like this should be checked
by an assertion - which you would have to build yourself because Pascal
doesn't have them. It's not difficult to create an Assert unit but you have
to use {$ifdef...} every time you use it, which is a pain.

Hope that helps

FP



Wed, 18 Jun 1902 08:00:00 GMT  
 Procedures as variables
Bendik Eide schrieb:

Quote:
> Is it possible to define a procedure as a variable so that I can do this:

Yes, of course. Here is an example:

type
  {-define the type of the proc (or function if you like) that you want
to call}
  SpecialProc = procedure(Msg : String);

  procedure DoIt(MsgProc : SpecialProc);
    {-The proc (can also be a function) that call the given proc}
  begin
    {-Be sure that we have a valid proc}

      {-It's okay, call that thing}
      MsgProc('from the DoIt-Proc')
    else
      {-No proc to call, do something else}
      WriteLn('No Proc to execute');
  end;

  procedure MyMsg(S : String); Far;
    {-This proc MUST be FAR, otherwise you can't pass it to the
DoIt-Proc!}
  begin
    WriteLn('This is a message ', S);
  end;

begin
  DoIt(MyMsg);
  DoIt(nil);
end.

By, Andreas.



Wed, 18 Jun 1902 08:00:00 GMT  
 Procedures as variables

Quote:

> Define a type for the procedure and its parameters, then define a parameter
> of that type in your function. Call the procedure by using the name of your
> function parameter. This is actually a pointer to a procedure, unfortunately
> with the ^ removed where the procedure is called, so NIL could be passed in.



Or equivalently, use

  if not Assigned(Proc) then...

Newsgroups and followup-to lines trimmed.

--
______________________________________________________________________
     The Scarlet Manuka,      |        Nitpickers' Party motto:
  Pratchett Quoter At Large,  |  "He who guards his lips guards his
 First Prophet of Bonni, is:  |  soul, but he who speaks rashly will

______________________________|_______________________________________



Wed, 18 Jun 1902 08:00:00 GMT  
 Procedures as variables



Quote:

> > Define a type for the procedure and its parameters, then define a
parameter
> > of that type in your function. Call the procedure by using the name of
your
> > function parameter. This is actually a pointer to a procedure,
unfortunately
> > with the ^ removed where the procedure is called, so NIL could be passed
in.


> Or equivalently, use

>   if not Assigned(Proc) then...

Thanks for that, I had thought that assigned() was a Delphi thing, since it
is not mentioned in the BP7 Language guide section on Procedural Values,

its on-line help.

Assigned is, of course, neater when you want to compare the procedure's

compare the address with some value other than NIL, for example another
procedural variable, you still need it: given two function variables f1 and
f2 you can compare them with


(although I'm not saying you'd often have a need for this).

Anyway, the point for Bendik Eide is that you can't compare a function or
procedure variable directly:

  if f1 = f2 then...

would mean "call f1 and f2 and if their return values are equal then...". I
wanted to point this out because I found the lack of a ^ (when you want to
invoke the function rather than refer to the variable) rather
counterintuitive.

FP



Wed, 18 Jun 1902 08:00:00 GMT  
 
 [ 7 post ] 

 Relevant Pages 

1. Procedure with variable number of parameters.

2. Procedure/Function Variables

3. Variable length argument list procedure?

4. Elimination of global variables in procedure

5. elimination of global variables in procedure

6. procedure variables in objects

7. freeware goodie: Procedure variables in OBJECTS

8. procedure variables

9. passing variables to an asm procedure in fpk

10. How can my procedures remember their variables?

11. Easy question: passing variables FROM a procedure

12. Declaring variable number of arguments in a function or procedure

 

 
Powered by phpBB® Forum Software