dslg0849@uxa.cso.uiuc.edu (Daniel S. Lewart) (12/03/90)
I am attempting to store an object's method in a procedure variable in TP5.5. However, I get a compiler error in the assignment statement. What am I doing wrong? Is there some way to do what I want to do? Thanks in advance, Daniel Lewart d-lewart@uiuc.edu ------------------------------------------------------------------------------- {$F+} type ObjectType = object procedure Method; end; var Obj: ObjectType; ProcVar: procedure; procedure ObjectType.Method; begin end; procedure Proc; begin end; Begin ProcVar := Proc; { This compiles } ProcVar := Obj.Method; { This doesn't } End. ------------------------------------------------------------------------------- e:\> tpc test Turbo Pascal Version 5.5 Copyright (c) 1983,89 Borland International TEST.PAS(15): Error 143: Invalid procedure or function reference. ProcVar := Obj.Method; { This doesn't } ^ -------------------------------------------------------------------------------
decomyn@penguin.uss.tek.com (12/04/90)
In article <1990Dec3.061013.22258@ux1.cso.uiuc.edu> dslg0849@uxa.cso.uiuc.edu (Daniel S. Lewart) writes: >I am attempting to store an object's method in a procedure variable in TP5.5. >However, I get a compiler error in the assignment statement. What am I doing >wrong? Is there some way to do what I want to do? >------------------------------------------------------------------------------- >{$F+} >type > ObjectType = object > procedure Method; > end; >var > Obj: ObjectType; > ProcVar: procedure; > >procedure ObjectType.Method; begin end; >procedure Proc; begin end; > >Begin > ProcVar := Proc; { This compiles } > ProcVar := Obj.Method; { This doesn't } >End. >------------------------------------------------------------------------------- >TEST.PAS(15): Error 143: Invalid procedure or function reference. The problem is that you are thinking of an object's methods as procedures. Technically, they are not procedures, and you can't treat them the same as independent procedures in many ways... including, apparently, this one. Unfortunately, I can't think of an immediate answer. You might try ProcVar := @Obj.Method, but I doubt that it will work. Also, take a peek at how the Procedure variables are stored. You might be able to force the correct calling address in by creating an absolute variable record at the Procedure variable location, something like this: type Testrec = Record segm : word; offs : word; End; var [...] ProcCall : Testrec absolute ProcVar; Begin Testrec.segm:=Seg(Obj.Method); Testrec.offs:=Ofs(Obj.Method); [...] etcetera. It may or may not work. (Note: the correct order may be offset first: I haven't looked at any generated code with that in mind) Good luck. ------------------------------------------------------------------------------- Brendt Hess a.k.a. | Disclaimer: Opinions? I don't even work here! Vergil William de Comyn a.k.a. |----------------------------------------------- Payne Hirds | Life is not a zero-sum game: decomyn@penguin.uss.tek.com | don't treat it as such.
garlange@mentor.cc.purdue.edu (Mark Garlanger) (12/04/90)
In article <1990Dec3.061013.22258@ux1.cso.uiuc.edu> dslg0849@uxa.cso.uiuc.edu (Daniel S. Lewart) writes: >I am attempting to store an object's method in a procedure variable in TP5.5. >However, I get a compiler error in the assignment statement. What am I doing >wrong? Is there some way to do what I want to do? > The question I have is WHY you would want to do this? Methods are closely tied to the data structure associated with it. What would you want the program to do with the method tries to access the data that the object has defined? What you are trying to do would cause many ambiguities for the compiler. I bet there is a way to solve your general problem by using the object-oriented programming directly, such as using virtual methods. I have done some work with objects and if you gave your general problem, I may be able to offer some hints on how to do it. Mark
dslg0849@uxa.cso.uiuc.edu (Daniel S. Lewart) (12/05/90)
garlange@mentor.cc.purdue.edu (Mark Garlanger) writes: > The question I have is WHY you would want to do this? Methods are closely > tied to the data structure associated with it. What would you want the > program to do with the method tries to access the data that the object has > defined? What you are trying to do would cause many ambiguities for the > compiler. I bet there is a way to solve your general problem by using > the object-oriented programming directly, such as using virtual methods. > I have done some work with objects and if you gave your general problem, I > may be able to offer some hints on how to do it. My intention is to use object methods in my menuing system. For each entry in a menu, there is a procedure which is executed when that entry is selected. This works for ordinary procedures, but it won't even compile for object methods. The example I posted was constructed to illustrate my problem as simply as possible. I don't see how there would be any compiler ambiguities, but I do hope you win the bet! In practice, my code for initializing each entry in a menu looks like the following (Name's are strings): AddItemProc( Name1, Proc1 ); AddItemProc( Name2, Proc2 ); ... I would like one of these Proc's to be an object method: AddItemProc( Name3, Obj.Method ); Currently, I have to resort to the following code: procedure ObjMethod; begin Obj.Method; end; AddItemProc( Name3, ObjMethod ); Thank you for your kind offer, Daniel Lewart d-lewart@uiuc.edu
dslg0849@uxa.cso.uiuc.edu (Daniel S. Lewart) (12/05/90)
The following are excerpts from a note sent to me by Mark Garlanger: > What you have to remember is that each method has a 'Self' parameter. That > is Obj.Method; can be thought of as Method(Obj); look on page 17,18 of > Turbo 5.5 OOP Guide. So when you try to assign a method to a procedure > variable, there are two addresses that need to be saved(Obj and the address of > Method). Since the compiler only has room for one address in the procedure > variable, it prints out the compiler error. > ... > To me, this looks like the only way to do it. Maybe someone else out there > knows another solution to this. Sorry I couldn't be of more help. I believe that this is the correct explanation of my problem. My last question is whether @ can be applied to an object method. The OOP Guide says 'yes', but my experience says 'no'. Thanks to everyone who helped, Dan d-lewart@uiuc.edu
dmurdoch@watserv1.waterloo.edu (D.J. Murdoch - Statistics) (12/06/90)
In article <1990Dec4.232438.927@ux1.cso.uiuc.edu> dslg0849@uxa.cso.uiuc.edu (Daniel S. Lewart) writes: >I believe that this is the correct explanation of my problem. My last question >is whether @ can be applied to an object method. The OOP Guide says 'yes', but >my experience says 'no'. You seem to be allowed to do it if you specify the method with a type prefix, but not with a variable prefix. For example: type myobj = object constructor init; procedure static; procedure virt; virtual; end; { code for init, static, and virt omitted... } var o : myobj; p : pointer; begin p := @myobj.static; { these first two work } p := @myobj.virt; o.init; p := @o.static; { these last two don't compile } p := @o.virt; end. Duncan Murdoch
streich@tigger.Colorado.EDU (Mark Streich) (12/07/90)
dmurdoch@watserv1.waterloo.edu (D.J. Murdoch - Statistics) writes: >You seem to be allowed to do it [get address of object method] if you >specify the method with a type prefix, but not with a variable prefix. >For example: > >type > myobj = object > constructor init; > procedure static; > procedure virt; virtual; > end; >{ code for init, static, and virt omitted... } > >var > o : myobj; > p : pointer; >begin > p := @myobj.static; { these first two work } > p := @myobj.virt; > o.init; > p := @o.static; { these last two don't compile } > p := @o.virt; >end. This looks quite suspicious because you're taking the address of a class, and not the address of an *instance* of the class. Two instances may (obviously?) have different virtual methods. As a comparison, it looks like you're taking the address of the integer type rather than an integer variable. (i.e., p := @integer rather than p := @i { of type integer }) Does this run correctly with different instances of the object? Mark Streich streich@tigger.colorado.edu
dmurdoch@watstat.waterloo.edu (Duncan Murdoch) (12/10/90)
In article <1990Dec7.153019.23716@csn.org> streich@tigger.Colorado.EDU (Mark Streich) writes: > >This looks quite suspicious because you're taking the address of a class, >and not the address of an *instance* of the class. Two instances may >(obviously?) have different virtual methods. It wasn't the address of the class, rather tthe address of the entry point of a method defined within the class. (Please excuse my bouncy keyboardd! Nortthgatte has promised me a replacement any day now; when it arrives, I should be able to type again.) But your commment aboutt virtual methods is right on: there's no easy way to find the appropriate virtual method for an instance, other than just calling it. In fact, it says somewhere in the manual that the "@" operattor applied to routines is useless as long as you stay within TP; it's just provided for completeness, in case you want to pass the address to some assembly code. Duncan Murdoch