[comp.lang.pascal] Procedure Vars, Methods, Chaos, Ruin

trodgers@nmsu.edu (Thomas Rodgers) (12/11/90)

In Reference to : TP5.5: Can't store method in procedure variable

I am pleased to find that I am not the only one with this problem!

I am constructing an object to encapsulate TurboPower software's BTREE
FILER v5.05 calls.  It was my desire to have the index definition and
key functions as virtual methods that could be overidden in another
definition.  The relevent go something like :

type
  idx_key_func = function(var dat; key : integer) : IsamKeyStr;
  idx_def_proc = procedure(var iid: IsamIndDescr)'

dbobj = object(root)

... Stuff ...
  idxkey : idx_key_func;
  idxdef : idx_def_proc;
 
... Method Stuff ...
  procedure SetIdxKeyFunc(ikf : idx_key_func);
  procedure SetIdxDefProc(idp : idx_def_proc);
  { So the user doesn't necessarily have to derive a new object to
    use the database }
  function IndexKey(var dat; key : integer) :IsamKeyStr;virtual;
  procedure IndexDef(var iid : IsamIndDescr);virtual;
  { The Default actions of these are to call the routines in idxkey
    and idxdef }

  ... More Stuff ...
end;

Everything works great, except when my object detects a corrupted
database, it calls the standard BTREE rebuild procedure.  The chaos
and madness starts here.  BTREE makes heavy use of procedure pointers,
not procedure variables, this is to maintain compatibility with TP4.0,

They use inline code inside a local procedure to call the supplied
procedure through its pointer.  After digging through the OOP guide, I
found that virtual methods expect a different stack frame than do
ordinary procedures (an invisible self pointer is put on the stack).
Needless to say, since the stack frame was not quite the same the call
drove off into the weeds.  I modified the code of the reorg routines
to accept procedure types instead of pointers, and started getting the
"Invalid procedure or funtion reference" stuff.  It is my opinion that
when you declare :

type
  proc = procedure;

you are telling the compiler that you want a procedure type of the
"standard form" (ie not a method).  Since methods have the additional
self parameter in their stack frame, they aren't truly the same
beasts, the compiler won't let you interchange them.  As far as trying
to use the @ operator, this doesn't seem to work either (the self
parameter still bites us).

I have stewed over several possible solutions, but none are very
convenient.  But if I find one I'll post it.