comp.lang.ada
 help / color / mirror / Atom feed
From: "Anthony E. Glover" <aeg@hiwaay.net>
Subject: Re: How to?: Re-dispatching within an inherited method
Date: 1999/08/21
Date: 1999-08-21T00:00:00+00:00	[thread overview]
Message-ID: <37BEB518.AEC525CF@hiwaay.net> (raw)
In-Reply-To: 37bc0730@news1.us.ibm.net

[-- Attachment #1: Type: text/plain, Size: 3795 bytes --]

Matthew Heaney wrote:
> 
> In article <37BB74A8.F35560F7@hiwaay.net> , "Anthony E. Glover"
> <aeg@hiwaay.net> 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
>       <implementation for type A>
>     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
>       <implementation for type B>
>     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.
> 
> <http://www.acm.org/archives/patterns.html>

I will digest these comments some more when I get back to work.

Thanks for the reply,
Tony

[-- Attachment #2: Card for Anthony E. Glover --]
[-- Type: text/x-vcard, Size: 361 bytes --]

begin:vcard 
n:Glover;Anthony E.
tel;fax:256-721-1816
tel;home:256-837-7017
tel;work:256-721-7714 X249
x-mozilla-html:FALSE
url:www.elmco.com
org:ELMCO, Inc.
version:2.1
email;internet:aeg@hiwaay.net
title:Senior Software Engineer
adr;quoted-printable:;;6000 Technology Drive=0D=0ASuite N;Huntsville;AL;35805;USA
x-mozilla-cpt:;1
fn:Anthony E. Glover
end:vcard

      reply	other threads:[~1999-08-21  0:00 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1999-08-09  0:00 How to?: Re-dispatching within an inherited method Anthony E. Glover
1999-08-09  0:00 ` David C. Hoos, Sr.
1999-08-17  0:00   ` Matthew Heaney
1999-08-17  0:00     ` David C. Hoos, Sr.
1999-08-18  0:00       ` Matthew Heaney
1999-08-18  0:00         ` Anthony E. Glover
1999-08-19  0:00           ` Matthew Heaney
1999-08-21  0:00             ` Anthony E. Glover [this message]
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox