[comp.lang.pascal] Pointers to procedures

209507097@ucis.vill.edu (MCREE, JAMES F) (04/09/91)

	I been following the thread of calling procedures by pointers with a 
lot of interest recently.  Mostly because I have an application that is just 
begging for a solution like that.  However, the discussion and samples that I 
have seen (including those in the manual) deal with hardcoding procedure names 
into the program.  (ie. Proc[i] := Do_It_Procedure)  Is there a way of doing 
what my syntactically incorrect program below is trying to do?

Program Call_A_Variable_Procedure (Input,Output);
.
Var
    Proc_Name : Procedure;
.
.
Assorted necessary delcarations
.
Begin
.
.
Assorted code statements
.
.
Write ('Enter the name of a procedure to run: ');
Readln (Proc_Name);
Proc_Name;
.
.
End.


This is an example of a user-specified call to a procedure.  The user
specifies the procedure directly though.  Can this be done?

						Happy Coding!!!

						Jim.

dmurdoch@watmath.waterloo.edu (Duncan Murdoch) (04/09/91)

In article <26486@adm.brl.mil> 209507097@ucis.vill.edu (MCREE, JAMES F) writes:
>
>	I been following the thread of calling procedures by pointers with a 
>lot of interest recently.  Mostly because I have an application that is just 
>begging for a solution like that.  However, the discussion and samples that I 
>have seen (including those in the manual) deal with hardcoding procedure names 
>into the program.  (ie. Proc[i] := Do_It_Procedure)  Is there a way of doing 
>what my syntactically incorrect program below is trying to do?
...
>Write ('Enter the name of a procedure to run: ');
>Readln (Proc_Name);
>Proc_Name;
>.
>.
>End.
>
>
>This is an example of a user-specified call to a procedure.  The user
>specifies the procedure directly though.  Can this be done?

The closest thing to what you've got there would be to create an array of
procedure variables, and a corresponding array of names.  Then when the user
enters a name, search through the name array for a match, and call the
corresponding procedure.

For example:

 var
   procs : array[1..2] of procedure;
   names : array[1..2] of string[8];
   name  : string[8];
   i     : integer;
 begin

   { In TP 6, these assignments could all be done in a Const declaration }

   procs[1] := add;
   names[1] := 'ADD';
   procs[2] := subtract;
   names[2] := 'SUBTRACT';

   readln(name);
   i := 1;
   while (i <= 2) and (names[i] <> name) do
     inc(i);
   if i <= 2 then
     procs[i];
  end;

I hope this helps.

Duncan Murdoch
dmurdoch@watstat.waterloo.edu (when it gets fixed)
dmurdoch@watmath.waterloo.edu (temporarily)

CDCKAB%EMUVM1.BITNET@cunyvm.cuny.edu ( Karl Brendel) (04/09/91)

In article <9104081439.aa02828@VGR.BRL.MIL>, 209507097@ucis.vill.edu
  (MCREE, JAMES F) wrote:

>        I been following the thread of calling procedures by
>pointers with a lot of interest recently.  Mostly because I have an
>application that is just begging for a solution like that.  However,
>the discussion and samples that I have seen (including those in the
>manual) deal with hardcoding procedure names into the program.  (ie.
>Proc[i] := Do_It_Procedure)  Is there a way of doing what my
>syntactically incorrect program below is trying to do?
>
>Program Call_A_Variable_Procedure (Input,Output);
>.
>Var
>    Proc_Name : Procedure;
>.
>.
>Assorted necessary delcarations
>.
>Begin
>.
>.
>Assorted code statements
>.
>.
>Write ('Enter the name of a procedure to run: ');
>Readln (Proc_Name);
>Proc_Name;
>.
>.
>End.
>
>
>This is an example of a user-specified call to a procedure.  The
>user specifies the procedure directly though.  Can this be done?

It isn't really apparent (to me) that your application is truly
"begging for a solution like [pointers to procedures]". Why can you
not just use a series of IF statements for your purpose?

        Proc_Name := stUpCase(Proc_Name);
        IF Proc_Name = 'PROC_A' THEN Proc_A
        ELSE IF Proc_Name = 'PROC_B' THEN ProcB
        etc....

Note that you may want to let the user specify arguments prior to
calling the routine:

        Enter the name of a procedure to run (with arguments):

        proc_a(first_var, second_var)_

where the number of arguments may be different from routine to
routine. I don't think there's any way of doing that with proceure
types (or pointers thereto) which is really any more elegant or
compact than the series of IF statements. (But that's probably
shortsightedness on my part :) )

Cheers--                        --Karl

+--------------------------------------------------------------------+
| Karl Brendel                           Centers for Disease Control |
| Internet: CDCKAB@EMUVM1.BITNET         Epidemiology Program Office |
| Bitnet: CDCKAB@EMUVM1                  Atlanta GA  30093       USA |
|                        Home of Epi Info 5.0                        |
+--------------------------------------------------------------------+

bg11+@andrew.cmu.edu (Brian E. Gallew) (04/10/91)

I don't know much about Procedure Pointers in PASCAL, but I can see one
way in which this becomes truly elegant.
Define an array of Procedure Pointers.  This, in conjuction with a
numerical or key-letter input reduces to a mapping function (for
key-letters) and a single call ProcPtrVar[Choice];

While I have never done this in PASCAL, I have done exactly this in C.


                                  -Brian

You drop the bomb -more-
It goes off... -more-
-------------------------------------------------------------------------
I am *NOT* as think as you dumb I am!! |  This space for rent (241-6939)
-------------------------------------------------------------------------

mwizard@eecs.cs.pdx.edu (Craig Nelson) (04/10/91)

CDCKAB%EMUVM1.BITNET@cunyvm.cuny.edu ( Karl Brendel) writes:

>In article <9104081439.aa02828@VGR.BRL.MIL>, 209507097@ucis.vill.edu
>  (MCREE, JAMES F) wrote:

>>        I been following the thread of calling procedures by
>>pointers with a lot of interest recently.  Mostly because I have an
>>application that is just begging for a solution like that.  However,
>>the discussion and samples that I have seen (including those in the
>>manual) deal with hardcoding procedure names into the program.  (ie.
>>Proc[i] := Do_It_Procedure)  Is there a way of doing what my
>>syntactically incorrect program below is trying to do?
>>
>>Program Call_A_Variable_Procedure (Input,Output);
>>.
>>Var
>>    Proc_Name : Procedure;
>>.
>>.
>>Assorted necessary delcarations
>>.
>>Begin
>>.
>>.
>>Assorted code statements
>>.
>>.
>>Write ('Enter the name of a procedure to run: ');
>>Readln (Proc_Name);
>>Proc_Name;
>>.
>>.
>>End.
>>
>>
>>This is an example of a user-specified call to a procedure.  The
>>user specifies the procedure directly though.  Can this be done?

>It isn't really apparent (to me) that your application is truly
>"begging for a solution like [pointers to procedures]". Why can you
>not just use a series of IF statements for your purpose?

>        Proc_Name := stUpCase(Proc_Name);
>        IF Proc_Name = 'PROC_A' THEN Proc_A
>        ELSE IF Proc_Name = 'PROC_B' THEN ProcB
>        etc....


	How about this:

{$F+}
procedure proc1;
begin
  writeln('In Proc1');
end;

procedure proc2;
begin
  writeln('In Proc2');
end;

procedure proc3;
begin
  writeln('In Proc3');
end;



Const 

    NumProcedures = 3;

Type 

     ProcString = String[10];
     ProcRec = Record
		Name:PString;
		Proc:Procedure;
	       end;	


Const
     MyProcedures : Array[1..NumProcedures] of ProcRec = (
			(Name:'PROC1';Proc:proc1),
			(Name:'PROC2';Proc:proc2),
			(Name:'PROC3';Proc:proc3));
	


	With this kind of setup you should be able to have a function that
runs the procedure desired if found from the input line.  For instance, if
the function returned and index if the proper procedure was found, and 0 on
an error, then

	i:= FindProcedure(ReadString);
        if (i>0) then MyProcedures[i].Proc
	else writeln('No such procedure');


	Am I missing something or will this work ?  Should.... Looks like it
	will.

Cheers!

 []====================================================================[]
 || Craig R. Nelson                | CCSofD Software Inc.              ||
 || Programmer                     | Beaverton, OR, 97005              ||
 || mwizard@eecs.ee.pdx.edu        | (unlisted on the net)             ||

John G. Spragge <SPRAGGEJ@QUCDN.QueensU.CA> (04/10/91)

To read the name of a procedure and map it to a procedure
address, the program would have to look up the procedure in
the symbol table. Unfortunately, most programs do not include
the symbol table in their production versions, since it takes
up space. So the user can not enter the name of the program
to execute directly.

disclaimer: Queen's University supplies me with computer services, not
            my opinions.

John G. Spragge

CDCKAB%EMUVM1.BITNET@cunyvm.cuny.edu ( Karl Brendel) (04/11/91)

In article <Ec0TSOS00WCZAYM0Q3@andrew.cmu.edu>, bg11+@andrew.cmu.edu
  (Brian E. Gallew) wrote:

>I don't know much about Procedure Pointers in PASCAL, but I can see
>one way in which this becomes truly elegant.
>
>Define an array of Procedure Pointers.  This, in conjuction with a
>numerical or key-letter input reduces to a mapping function (for
>key-letters) and a single call ProcPtrVar[Choice];

True, but the original question involved accepting a character
_string_ naming the procedure (although e-mail has revealed that
what the poster really _wants_ is a menu pick). Also this solution
doesn't allow for passing parameters to procedures unless they all
take the same sequence of parameters (same quantity, order and
type). (E-mail has also revealed that the poster does want varying
sequences of parameters.)

(Of course, an input character string can be compared to an array of
character strings to determine an index to an array of pointers. I
think this has previously been proposed in this discussion. IMO,
that is only slightly more elegant than IFs, and again does not
allow varying sequences of parameters.)

Cheers--                        --Karl

+--------------------------------------------------------------------+
| Karl Brendel                           Centers for Disease Control |
| Internet: CDCKAB@EMUVM1.BITNET         Epidemiology Program Office |
| Bitnet: CDCKAB@EMUVM1                  Atlanta GA  30093       USA |
|                        Home of Epi Info 5.0                        |
+--------------------------------------------------------------------+

209507097@ucis.vill.edu (MCREE, JAMES F) (04/11/91)

Karl Brendel <CDCKAB%EMUVM1.BITNET@cunyvm.cuny.edu> writes...
 
>>I don't know much about Procedure Pointers in PASCAL, but I can see
>>one way in which this becomes truly elegant.
>>
>>Define an array of Procedure Pointers.  This, in conjuction with a
>>numerical or key-letter input reduces to a mapping function (for
>>key-letters) and a single call ProcPtrVar[Choice];
> 
>True, but the original question involved accepting a character
>_string_ naming the procedure (although e-mail has revealed that
>what the poster really _wants_ is a menu pick). Also this solution
>doesn't allow for passing parameters to procedures unless they all
>take the same sequence of parameters (same quantity, order and
>type). (E-mail has also revealed that the poster does want varying
>sequences of parameters.)

	That's not quite what I had in mind.  The user picks a menu choice 
which calls a procedure whose name is specified in an input file.  Consider the 
following file:

	1 Do_Operation_One (Some params)
	2 Do_A_Different_Op (A few other params)
	3 The_Final_Solution (All params)

My goal was to read in a menu file (use the above as an example).  If the user 
entered a 1 to a prompt, procedure "Do_Operation_One (Some params)" would be 
called.  Likewise for a 2 and 3.  Initially, this does not present a problem.

	Here's the problem.  Let's say we want to make this a generic menu unit 
which will have the capability of calling any procedure so long as its name is 
specified in an input file.  The name of the procedures would be read and if 
its number came up, it would be called.  All of this ideally should be done 
without the need to recompile the menu unit.

	The solution that I have ended up falling back to was a simple giant 
case statement because the procedures will have params that will not all be the 
same.  I'm still interested in the idea of calling a procedure whose name is 
specified by an input file entry without parameters though.  A series of IF 
statements might work equally as well, but would probably end up being longer 
if I were to stick to structured programming.  Thanks for all of the ideas.  
There are still a bunch of them that I would like to play with and see how 
useful they will be in other areas.

						Have a good day,

						Jim.