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.9 required=5.0 tests=BAYES_00 autolearn=unavailable autolearn_force=no version=3.4.4 Path: border1.nntp.ams3.giganews.com!border2.nntp.ams3.giganews.com!border2.nntp.ams2.giganews.com!border4.nntp.ams.giganews.com!border2.nntp.ams.giganews.com!nntp.giganews.com!feeder.erje.net!eu.feeder.erje.net!news.albasani.net!news.szaf.org!news.gnuher.de!rz.uni-karlsruhe.de!feed.news.schlund.de!schlund.de!news.online.de!not-for-mail From: Felix Krause Newsgroups: comp.lang.ada Subject: Re: Generics and Child Packages Date: Sat, 10 Aug 2013 17:39:59 +0200 Organization: 1&1 Internet AG Message-ID: References: NNTP-Posting-Host: pd9542311.dip0.t-ipconnect.de Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit X-Trace: online.de 1376149199 28298 217.84.35.17 (10 Aug 2013 15:39:59 GMT) X-Complaints-To: abuse@einsundeins.com NNTP-Posting-Date: Sat, 10 Aug 2013 15:39:59 +0000 (UTC) User-Agent: Unison/2.1.10 X-Original-Bytes: 5026 Xref: number.nntp.dca.giganews.com comp.lang.ada:182942 Date: 2013-08-10T17:39:59+02:00 List-Id: On 2013-08-09 20:35:31 +0000, sbelmont700@gmail.com said: > Does anyone have any tips or tricks when it comes to using child > packages and generics? The whole thing seems pretty kludgy: as soon as > you make the parent generic, any public child unit suddenly becomes > "faux generic", and has to be instantiated explicitly albeit without > any parameters, which at best is a PITA. More critically, any private > child units suddenly becomes forbidden, and you end up with either one > gigantic package (bad), or having to split it out and with them in, > breaking encapsulation (worse). Why can't I just instantiate the > Parent, and automatically bring along respective copies of all the > (parameterless) Children, exactly like it would be if nested packages > were used instead of child packages? I have similar problems in my current project. I decided to follow the rule that a generic package may never have a child package unless that child package takes additional generic arguments. With a bit of work and if some preconditions are met, you can transform an existing package hierarchy into one that takes generic parameters. Let's have an example where we have a package P with some child packages and we want to make one base type generic. We start from: package P is type T_1 is new Integer; type T_2 is new Float; -- … end P; private package P.Q is -- … end P.Q; package P.R is -- … end P.R; We now want to make the base type of T_2 generic. This is one way how this can be done: package P is -- leave stuff that doesn't depend on the generic parameters here type T_1 is new Integer; end P; generic type Base_Type is private; package P.Base is -- here goes the stuff that was formerly in P and now depends on the parameter: type T_2 is new Base_Type; -- … end P.Base; private generic with package Parent is new P.Base (<>); package P.Q is -- same as before end P.Q; generic with package Parent is new P.Base (<>); package P.R is -- same as before private -- assuming that P.R depends on P.Q package My_Q is new P.Q (Parent); end P.R; generic -- same parameters as P.Base: type Base_Type is private; package P.Whole is package Parent ist new P.Base (Base_Type); package R is new P.R (Parent); -- import declarations from P.Base if you want: subtype T_2 is Parent.T_2; use type T_2; end P.Whole; You still have a non-generic base package where you can keep declarations that do not depend on the generic parameters. P.Whole is a convenience package to instantiate all child packages at once, but everything is modular - the user does not *need* to use P.Whole. All child packages are usable on their own. However, there are some caveats: * You have to instantiate P.Q in every package that needs it. You cannot share one instance between packages, because as P.Q as a private child unit cannot be parameter of the other generic units. This may break your code if P.Q defines any variables at library level. * You cannot access stuff from the private part of P.Base in the other packages. All private entities you want to share between these packages have to go into the private part of base package P. If they depend on generic parameters, you're out of luck. * You cannot have cross-dependencies (like one of the child package's implementation depends on another package's specification and vice versa). If you absolutely need to have a child package that does use private entities from P.Base, you can of course still define one with empty generic parameter set as child unit of P.Base. You could create an instance of it in P.Whole for convenience. -- Felix Krause http://flyx.org/