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.2 required=5.0 tests=BAYES_00,FROM_WORDY, INVALID_MSGID 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: "Nick Roberts" Subject: Re: Can't export object of private type Date: 1999/02/27 Message-ID: <7b8cvc$ii5$3@plug.news.pipex.net>#1/1 X-Deja-AN: 449223744 References: <7b4517$2bbr@news3.newsguy.com> X-MimeOLE: Produced By Microsoft MimeOLE V4.72.3110.3 Organization: UUNET WorldCom server (post doesn't reflect views of UUNET WorldCom) Newsgroups: comp.lang.ada Date: 1999-02-27T00:00:00+00:00 List-Id: I think possibly you guys are trying to use a sledgehammer to crack a nut here. One possible solution is: (a) provide a base (or common) package, which defines a selector type; (b) implement each singleton as a (child) package; (c) provide a 'gateway' package which provides dynamic selection of the singletons. E.g. (choosing the child package option): package Planetary is type Distance is digits 6 range 0.0 .. 1.0e14; -- metres type Time is ...; ... type Planet_Id is private; Planet_Error: exception; private type Planet_Id is new Positive range 1..99; ... end Planetary; package Planetary.Mercury is function Equatorial_Diameter return Distance; function Solar_Distance (T: in Time) return Distance; ... Id: constant Planet_Id; private ... Id: constant Planet_Id := 1; end Planetary.Mercury; ... etc. for the other planets, numbered 2, 3, etc. package Planetary.General_Planet is function Equatorial_Diameter (Planet: in Planet_Id) return Distance; function Solar_Distance (Planet: in Planet_Id; T: in Time) return Distance; ... end Planetary.General_Planet; The bodies of the functions in General_Planet contain a 'case' statement which selects the appropriate function of the appropriate package to call: function Equatorial_Diameter (Planet: in Planet_Id) return Distance is begin case Planet is when Mercury.Id => return Mercury.Equatorial_Distance; ... when others => raise Planet_Error; end case; end Equatorial_Diameter; In reality, the implementation may have to be more sophisticated than this. To add a new planet, you only have to edit and (re)compile: (a) the new planet package (spec & body); (b) the General_Planet package body. Simple! There will be many variations possible on this theme for each different specific application, many of them neater than the above. Another possible scheme that might suit you is: (a) declare a limited tagged type which is derived from Finalization.Limited_Controlled; (b) implement Initialize so that it increments a counter (which is itself initialized to 0), and if it goes above 1 (or some other number), raise an exception; (c) implement Finalize so it decrements the counter. This way you can polymorphise the type as normal, but be sure no more than one object of the type exists at any one time. One needs to make a distinction between a design concept and the implementational mechanism of that design concept, and not make the mistake of thinking that a particular design is inextricably wedded to a particular mechanism. It all depends on what you're trying to do (or, rather, why you're trying to do it). In all cases: power to your arm (and brain). ------------------------------------- Nick Roberts -------------------------------------