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=ham autolearn_force=no version=3.4.4 X-Google-Thread: 103376,b88383a5d9c51aa0 X-Google-Attributes: gid103376,domainid0,public,usenet X-Google-Language: ENGLISH,ASCII Path: g2news2.google.com!postnews.google.com!z15g2000yqm.googlegroups.com!not-for-mail From: Ludovic Brenta Newsgroups: comp.lang.ada Subject: Re: Ada-Singleton-Why does it work like this? Date: Tue, 24 Mar 2009 13:52:59 -0700 (PDT) Organization: http://groups.google.com Message-ID: <9a5fb100-c38d-45f6-a482-1c67b26c5866@z15g2000yqm.googlegroups.com> References: <5a7a870c-40e2-4803-8753-0f9cfd2b800f@k2g2000yql.googlegroups.com> NNTP-Posting-Host: 94.108.217.162 Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable X-Trace: posting.google.com 1237927979 25195 127.0.0.1 (24 Mar 2009 20:52:59 GMT) X-Complaints-To: groups-abuse@google.com NNTP-Posting-Date: Tue, 24 Mar 2009 20:52:59 +0000 (UTC) Complaints-To: groups-abuse@google.com Injection-Info: z15g2000yqm.googlegroups.com; posting-host=94.108.217.162; posting-account=pcLQNgkAAAD9TrXkhkIgiY6-MDtJjIlC User-Agent: G2/1.0 X-HTTP-UserAgent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.0.6) Gecko/2009020407 Iceweasel/3.0.6 (Debian-3.0.6-1),gzip(gfe),gzip(gfe) Xref: g2news2.google.com comp.lang.ada:5238 Date: 2009-03-24T13:52:59-07:00 List-Id: Patrick Gunia wrote: > Hi all, > I=B4m currently working on implementing several design patterns in Ada, > and I found some code concerning the Singleton-pattern when searching > through the posts of this group. I used this code and it all worked as > expected. My problem is, that I don=B4t ave any idea, why it does...here > is my code: > > package Singleton is > > =A0 =A0 =A0 =A0 type Singleton_Type (<>) is tagged limited private; > =A0 =A0 =A0 =A0 type Singleton_Access is access all Singleton_Type; > > =A0 =A0 =A0 =A0 function return_Single return Singleton_Access; > > =A0 =A0 =A0 =A0 procedure setValues(input : in out Singleton_Access; valu= eIN : > Integer; valueIN2 : Integer); > =A0 =A0 =A0 =A0 procedure print_something(input : Singleton_Access); > > =A0 =A0 =A0 =A0 private > =A0 =A0 =A0 =A0 type Singleton_Type is tagged limited record > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 value : Integer; > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 value2 : Integer; > =A0 =A0 =A0 =A0 end record; > > end Singleton; > > Here is the implementation part: > > package body Singleton is > =A0 =A0 =A0 =A0 It: aliased Singleton_Type; > =A0 =A0 =A0 =A0 procedure setValues(input : in out Singleton_Access; valu= eIN : > Integer; valueIN2 : Integer) is > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 begin > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 input.value :=3D valueIN; > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 input.value2 :=3D valueIN= 2; > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 end setValues; > > =A0 =A0 =A0 =A0 function return_Single return Singleton_Access is > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 begin > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 return It'Access; > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 end return_Single; > > =A0 =A0 =A0 =A0 procedure print_something(input : Singleton_Access) is > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 begin > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 put(input.value); > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 put(input.value2); > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 end print_something; > > end Singleton; > > As far as I get it, is the declaration "type Singleton_Type (<>) is > tagged limited private;" the key-feature to realize the Singleton > pattern, but how, and why does this work? I looked through my Ada- > book, searched the web but didn=B4t find an explanation for this > construct! Could you please tell me, what exactly happens when I use > (<>) within a type-declaration and why it is necessary for the > Singleton-Implementation? As Pascal replied, the (<>) declares that Singleton_Type is unconstrained; because, in addition, it is private, it is therefore impossible to declare objects of this type outside the package Singleton. Consider: with Singleton; procedure Wrong is Second_Singleton : Singleton.Singleton_Type; -- error, the type is unconstrained But your example is much too complicated. Why is Singleton_Type tagged? Why pass parameters to all subprograms when there is only one object anyway? A proper singleton looks like this: package Singleton is procedure Set (Value_1, Value_2 : in Integer); procedure Print; private Value_1, Value_2 : Integer; end Singleton; package body Singleton is procedure Set (Value_1, Value_2 : in Integer) is begin Singleton.Value_1 :=3D Value_1; Singleton.Value_2 :=3D Value_2; end Set; procedure Print is begin Put (Value_1); Put (Value_2); end Print; end Singleton; A variation of this design pattern is when you want to allocate the singleton dynamically on first use and never deallocate it. In this situation, you do need an access type and value but you do not need to expose them to clients; in fact the whole allocation business should be confined to the body of the package: package body Singleton is type Singleton_Type is record Value_1, Value_2 : Integer; end record; type Singleton_Access is access Singleton_Type; The_Singleton : Singleton_Access; procedure Allocate_If_Null is begin if The_Singleton =3D null then The_Singleton :=3D new Singleton_Type; end if; end Allocate_If_Null; procedure Set (Value_1, Value_2 : in Integer) is begin Allocate_If_Null; The_Singleton.Value_1 :=3D Value_1; The_Singleton.Value_2 :=3D Value_2; end Set; procedure Print is -- raises Constraint_Error if The_Singleton =3D null, i.e. if Set never called begin Put (The_Singleton.Value_1); Put (The_Singleton.Value_2); end Print; end Singleton; HTH -- Ludovic Brenta.