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.9 required=5.0 tests=BAYES_00,FORGED_GMAIL_RCVD, FREEMAIL_FROM autolearn=no autolearn_force=no version=3.4.4 X-Google-Thread: 103376,efc9f994d31d0d5e X-Google-Attributes: gid103376,domainid0,public,usenet X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news1.google.com!postnews.google.com!d21g2000prf.googlegroups.com!not-for-mail From: Eric Hughes Newsgroups: comp.lang.ada Subject: Re: Limited initialization for non-limited types Date: Tue, 1 Apr 2008 21:06:32 -0700 (PDT) Organization: http://groups.google.com Message-ID: References: NNTP-Posting-Host: 166.70.57.218 Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Trace: posting.google.com 1207109192 6683 127.0.0.1 (2 Apr 2008 04:06:32 GMT) X-Complaints-To: groups-abuse@google.com NNTP-Posting-Date: Wed, 2 Apr 2008 04:06:32 +0000 (UTC) Complaints-To: groups-abuse@google.com Injection-Info: d21g2000prf.googlegroups.com; posting-host=166.70.57.218; posting-account=5RIiTwoAAACt_Eu87gmPAJMoMTeMz-rn User-Agent: G2/1.0 X-HTTP-UserAgent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.12) Gecko/20080201 Firefox/2.0.0.12,gzip(gfe),gzip(gfe) Xref: g2news1.google.com comp.lang.ada:20747 Date: 2008-04-01T21:06:32-07:00 List-Id: On Mar 26, 7:26 am, I wrote: > package Foo is > type X is new Ada.Finalization.Controlled with > record T : Trace ; end record ; > Trace_Stash : Trace ; > end Foo ; > ... > package body Foo is > procedure Finalize( Object : in out X ) is begin > Trace_Stash = Object.T ; > Object.T.Trace_Finalize ; > end ; > procedure Adjust( Object : in out X ) is begin > Object.T = Trace_Stash ; > Object.T.Trace_Adjust ; > end ; > end Foo ; OK, figuring out initialization was blindingly easy once I got the right trick. Consider the following additional code in package Foo: package Foo [...] type Nil is null record ; function Construct_X( T : Trace ) return Nil ; end Foo ; ... package body Foo is function Construct_X( T : Trace ) return Nil is begin Trash_Stash = T ; return Nonce : Nil ; end ; function Initialize( Object : in out X ) is begin Object.T = Trace_Stash ; Object.T.Trace_Initialize ; end ; end Foo ; Why do I have a constructor function for X that returns Nil? Here's the sample code: declare T : Trace ; NA : Nil := Construct_X( T ) ; A : X ; begin ... What happens is that the Nil constructor has a side effect upon a package variable, which is then used in the default initialization of variable A. The realization I needed was that I could use a trivial constructor function within a declarative_part--where I would have otherwise used a procedure--to get side effects by which default initialization would work. That part of this trick is applicable in other code. My actual code is more involved. Here's an actual snippet, lifted from a unit test: [declarative_part] NA : Nil := Construct_Traced_Existence( Name => "A", T => T ) ; A : Traced_Existence ; NB : Nil := Construct_Traced_Existence( Name => "B", T => T ) ; B : Traced_Existence ; [handled_sequence_of_statements] A := B ; The trace that comes back (it's generated at run-time) is "(A.I)(B.I) (A.F)(A.A)", just like you'd expect. The previous method I had tried, which used ordinary constructor functions, that one didn't work well at all. Eric