Matthew Heaney wrote: > > 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.) The reason I am using pointers is because I have varying number of widgets and types of widgets that are stored and used by another piece of code; therefore, I store the pointers to the widgets in a list. I can then iterate over the list and perform processing using the dispatched methods without having to add if checks to my main processing. Pointers were the suggested method for achieving this based upon the Ada95 Barnes book I was reading. > > > 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); > I will give it a try. > 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. > > I will digest these comments some more when I get back to work. Thanks for the reply, Tony