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=0.2 required=5.0 tests=BAYES_00,INVALID_MSGID, REPLYTO_WITHOUT_TO_CC autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,772ae8afc5db35f2 X-Google-Attributes: gid103376,public From: nospam@thanks.com.au (Don Harrison) Subject: Re: Can't export object of private type Date: 1999/02/25 Message-ID: #1/1 X-Deja-AN: 448218375 Sender: news@syd.csa.com.au X-Nntp-Posting-Host: dev7 References: <7b1k4h$13k6@news3.newsguy.com> Organization: CSC Australia, Sydney Reply-To: nospam@thanks.com.au Newsgroups: comp.lang.ada Date: 1999-02-25T00:00:00+00:00 List-Id: Sam Mize wrote: :Well, I didn't see any previous message, but maybe that's just me :or my newsreader. Looks like you weren't the only one. Here it is again: ---------------------- :Ada doean't allow you to declare a private type and declare an object of that :type in the visible part of the same spec. For example, the following is :illegal: : : package Private_Stuff is : type Private_Type is tagged private; : procedure Do_Something (A: in Private_Type); : P: Private_Type; : private : type Private_Type is tagged null record; : end; : :GNAT protests: : : private_stuff.ads:4:03: error: premature usage of incomplete private type : "Private_Type" defined at line 2 : :I'm basically trying to implement singletons so that they can be used :polymorphically in the same way as other objects - for example : : Do_Something (P); : :rather than : : Private_Stuff.Do_Something; : :(Otherwise, I would shove the declaration of P into the body and remove A :from the signature). : : :Any suggestions? ---------------------- :You appear to want to export a variable of a private type, in the :public part of the package that defines that type. Correct. Actually, I don't necessarily want to do that. What I'm really after is polymorphic singletons - objects that 1) Have only one instance 2) Are polymorphic 3) Are visible to clients 4) Can be called without a package prefix. I can acheive two or three, but not all four. :( :The catch is that the full type definition must be available to the :compiler (if not visible to the user) when a variable is declared, so :it knows how much space to allocate. Yes, Ada doesn't expect its compilers to look ahead. :At the end of this message I show a workaround using a contained :package. It ain't pretty, ... If possible, I would prefer something simpler. :I didn't see anything important in the use of "tagged" for this question, :so I left it out. I want the type to be polymorphic. Otherwise I would just gain the singleton effect through a (non-generic) package and call their operations differently from non-singletons. :Let me improve your access-based solution. Changes are in all-caps: : :> package Singleton is :> :> type Singleton_Type is tagged private; :> type Access_Singleton_Type is access all Singleton_Type'Class; :> :> procedure Do_Something (S: in Singleton_Type); :> :> S_Ptr: CONSTANT Access_Singleton_Type; :> :> private :> type Singleton_Type is tagged null record; :> S: aliased Singleton_Type; : S_PTR: CONSTANT ACCESS_SINGLETON_TYPE := S'ACCESS; :> end; : :This way, users of the package don't have to wait for the elaboration :of Singleton's BODY for S_Ptr to denote S -- it does so once the SPEC :has been elaborated. (E.g, a package spec that "withs" Singleton could :do something meaningful with it.) (It would be smart to initialize S.) Good idea. Tucker Taft wrote: :One reasonably nice work-around is to put the variable into :a child package. Unfortunately, I would have to sacrifice 1) above. -- Don (Harrison). donh at syd.csa.com.au