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.3 required=5.0 tests=BAYES_00,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: Matthew Heaney Subject: Re: Can't export object of private type Date: 1999/02/28 Message-ID: #1/1 X-Deja-AN: 449644881 Sender: matt@mheaney.ni.net References: NNTP-Posting-Date: Sun, 28 Feb 1999 13:50:34 PDT Newsgroups: comp.lang.ada Date: 1999-02-28T00:00:00+00:00 List-Id: You may want to read what I had to say about singleton patterns in the patterns archive at the ACM (June 98). If you need a singleton abstraction, then implement it as a state machine package. package Singleton is procedure Do_Something; end; This is the simplest way to implement this idiom. A singleton is the limiting case of the "well-known" objects pattern, when the cardinality is one. For example, you may may know up front that there are two well-known objects (a "doubleton"?), in which case you pass an id to each operation: package Well_Known_Objects is type Id_Type is range 1 .. 2; procedure Do_Something (Id : in Id_Type); end Well_Known_Objects; You can't continue using types, because at some point you bottom-out and must declare instances of the type, and at the highest levels of abstraction those objects are going to have to get declared in a state machine package. So don't use a type unless you have have a compelling need to. If you decide that yes, you really want a type, then you'll have to refer to the singleton object indirectly, because (as you observed) you can't declare an instance of the type until after the full view of the type has been declared. Implement the type as limited and indefinite, and export a function that returns a pointer to the one object, declared in the body. package Singletons is type Singleton_Type (<>) is limited private; procedure Do_Something (Singleton : in out Singleton_Type); type Singleton_Access is access all Singleton_Type; function Ref return Singleton_Access; private type Singleton_Type is limited record ...; end Singletons; package body Singletons is Singleton : aliased Singleton_Type; function Ref return Singleton_Access is begin return Singleton'Access; end; ... end Singletons; Now to use it, you rename the object designated by the pointer: declare Singleton : Singleton_Type renames Ref.all; begin ... end; But like I said, don't use this implementation unless you have a real compelling need to do so. Use a state machine package. nospam@thanks.com.au (Don Harrison) writes: > The best workaround I've been able to come up with is to export an access > variable to the singleton. For example, > > 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: Access_Singleton_Type; > > private > type Singleton_Type is tagged null record; > S: aliased Singleton_Type; > end; > > initialising the access variable at elaboration .. > > S_Ptr := S.all'Access; > > and using it in clients .. > > Do_Something (S_Ptr.all); > > > > Any better suggestions? .. > > > (Of course, it would be easier if Ada just allowed you to export a variable > of a private type from the same package. :) Oh, well.