From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.3 required=5.0 tests=BAYES_00,INVALID_MSGID autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,a370fcbf5c4dae94 X-Google-Attributes: gid103376,public From: "Matthew Heaney" Subject: Re: How to?: Re-dispatching within an inherited method Date: 1999/08/19 Message-ID: <37bc0730@news1.us.ibm.net>#1/1 X-Deja-AN: 514674820 Content-transfer-encoding: 7bit References: <37AF0ADE.3D80FEB3@hiwaay.net> <7onk8f$2qg@hobbes.crc.com> <37b9a823@news1.us.ibm.net> <7pcar9$aeg@hobbes.crc.com> <37bae808@news1.us.ibm.net> <37BB74A8.F35560F7@hiwaay.net> X-Trace: 19 Aug 1999 13:31:28 GMT, 129.37.213.161 Organization: Global Network Services - Remote Access Mail & News Services X-Notice: should be reported to postmaster@ibm.net Content-Type: text/plain; charset="US-ASCII" Mime-version: 1.0 Newsgroups: comp.lang.ada X-Complaints-To: postmaster@ibm.net Date: 1999-08-19T00:00:00+00:00 List-Id: In article <37BB74A8.F35560F7@hiwaay.net> , "Anthony E. Glover" wrote: > In my case, I am using pointers to objects; Just out of curiosity: why are you using pointers? Ada was designed so that heap use is often not necessary. (I just want to make sure you were aware of this, so you don't inculcate any bad habits.) > so, I actually have to 'use' all derived type packages and then make the > procedure call without full dot notation, such as: > > use A; > use B; > > ... > ... > > Run_Widget( UnknownWidget.all ); > > Where UnknownWidget is a pointer to the class wide type. Is there a better way > of doing this? I not convinced you really need to do this. You don't have to with all the packages that override primitive operations, if the parameter has a class-wide type. The following should work (please test this): A.Run_Widget (UnknownWidget.all); One alternative (that I'm not convinced is necessary) is to make Run_Widget a class-wide operation (a "template method"), that is implemented by calling a private primitive operation that dispatches on the tag of the parameter. For example: package P is type A is tagged null record; -- or tagged private procedure Run_Widget (O : in out A'Class); -- class-wide private procedure Do_Run_Widget (O : in out A); -- primitive (and private) end P; package body P is procedure Run_Widget (O : in out A'Class) is begin Do_Run_Widget (O); -- dispatches on tag of O end; procedure Do_Run_Widget (O : in out A) is begin end; end P; package P.Q is type B is new A with null record; private procedure Do_Run_Widget (O : in out B); -- override primitive op end P.Q; package body P.Q is procedure Do_Run_Widget (O : in out B) is begin end; end P.Q; Now, there is only one (public) Run_Widget operation. When you call it: A.Run_Widget (UnknownWidget.all); the internal call to Do_Run_Widget will dispatch on the tag of the param. I you have a basic algorithm that's that same for all implementations of an operation -- only parts on it changed based in the specific type -- then a class-wide operation ("template method") is the way to go. But if each overriding of the operation has a completely different implementation, then the operation should just be a simple, public primitive operation. I know it must seem weird to say: A.Run_Widget (UnknownWidget.all); and "really" be calling B.Run_Widget, or C.Run_Widget, but that's the nature of the dispatching mechanism. > If I add a new package with another derived type, then I have to go add 'uses' > to all packages that make calls to methods of the class. No, I don't think so: not if the object has a class-wide type. If you want more information about template methods, so my posts to the ACM patterns archive. -- Matt It is impossible to feel great confidence in a negative theory which has always rested its main support on the weak points of its opponent. Joseph Needham, "A Mechanistic Criticism of Vitalism"