comp.lang.ada
 help / color / mirror / Atom feed
From: Ludovic Brenta <ludovic@ludovic-brenta.org>
Subject: Re: Ada-Singleton-Why does it work like this?
Date: Tue, 24 Mar 2009 13:52:59 -0700 (PDT)
Date: 2009-03-24T13:52:59-07:00	[thread overview]
Message-ID: <9a5fb100-c38d-45f6-a482-1c67b26c5866@z15g2000yqm.googlegroups.com> (raw)
In-Reply-To: 5a7a870c-40e2-4803-8753-0f9cfd2b800f@k2g2000yql.googlegroups.com

Patrick Gunia wrote:
> Hi all,
> I´m 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´t ave any idea, why it does...here
> is my code:
>
> package Singleton is
>
>         type Singleton_Type (<>) is tagged limited private;
>         type Singleton_Access is access all Singleton_Type;
>
>         function return_Single return Singleton_Access;
>
>         procedure setValues(input : in out Singleton_Access; valueIN :
> Integer; valueIN2 : Integer);
>         procedure print_something(input : Singleton_Access);
>
>         private
>         type Singleton_Type is tagged limited record
>                 value : Integer;
>                 value2 : Integer;
>         end record;
>
> end Singleton;
>
> Here is the implementation part:
>
> package body Singleton is
>         It: aliased Singleton_Type;
>         procedure setValues(input : in out Singleton_Access; valueIN :
> Integer; valueIN2 : Integer) is
>                 begin
>                         input.value := valueIN;
>                         input.value2 := valueIN2;
>
>                 end setValues;
>
>         function return_Single return Singleton_Access is
>                 begin
>                         return It'Access;
>                 end return_Single;
>
>         procedure print_something(input : Singleton_Access) is
>                 begin
>                         put(input.value);
>                         put(input.value2);
>                 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´t 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 := Value_1;
      Singleton.Value_2 := 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 = null then
         The_Singleton := 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 := Value_1;
      The_Singleton.Value_2 := Value_2;
   end Set;

   procedure Print is
      -- raises Constraint_Error if The_Singleton = 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.



  parent reply	other threads:[~2009-03-24 20:52 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-03-24 19:01 Ada-Singleton-Why does it work like this? patrick.gunia
2009-03-24 19:10 ` Pascal Obry
2009-03-24 20:47 ` Jeffrey R. Carter
2009-03-25  0:10   ` Martin
2009-03-25  0:41     ` Jeffrey R. Carter
2009-03-25  9:30     ` Dmitry A. Kazakov
2009-03-26  8:55       ` Martin
2009-03-26  9:28         ` Dmitry A. Kazakov
2009-03-26 13:39           ` Maciej Sobczak
2009-03-26 14:07             ` Georg Bauhaus
2009-03-26 14:33               ` Dmitry A. Kazakov
2009-03-26 15:22                 ` Georg Bauhaus
2009-03-26 16:31                   ` Dmitry A. Kazakov
2009-03-26 14:28             ` Dmitry A. Kazakov
2009-03-26 22:00               ` Maciej Sobczak
2009-03-27 10:02                 ` Dmitry A. Kazakov
2009-03-25 22:29   ` sjw
2009-03-24 20:52 ` Ludovic Brenta [this message]
2009-03-25  9:59   ` patrick.gunia
2009-03-25 10:29     ` Jean-Pierre Rosen
2009-03-25 11:26     ` Georg Bauhaus
2009-03-25 11:49       ` patrick.gunia
2009-03-29  7:29     ` Jacob Sparre Andersen
2009-03-24 21:21 ` Dmitry A. Kazakov
2009-03-25 10:07   ` patrick.gunia
2009-03-25 10:57     ` patrick.gunia
2009-03-25 11:40       ` Georg Bauhaus
2009-03-25 11:46       ` Ludovic Brenta
2009-03-25 11:55         ` patrick.gunia
2009-03-25 14:10         ` patrick.gunia
2009-03-25 14:40           ` Ludovic Brenta
2009-03-25 15:16             ` Adam Beneschan
2009-03-25 15:19             ` patrick.gunia
2009-03-25 16:52               ` Georg Bauhaus
2009-03-25 11:10     ` Dmitry A. Kazakov
2009-03-25 11:37       ` patrick.gunia
2009-03-25 12:07         ` Ludovic Brenta
2009-03-25 15:00         ` Robert A Duff
2009-03-25 11:17     ` Jean-Pierre Rosen
2009-03-26  9:04       ` Martin
2009-03-25 11:38     ` Ludovic Brenta
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox