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=unavailable autolearn_force=no version=3.4.4 Path: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!news.eternal-september.org!mx02.eternal-september.org!feeder.eternal-september.org!news.swapon.de!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail From: hreba Newsgroups: comp.lang.ada Subject: Re: How to use read-only variables? Date: Sun, 04 Jan 2015 10:56:38 -0200 Message-ID: References: Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-Trace: individual.net 0QQRMCQgtQyZrZ6orJLwcwQ7HIEqASVnTzqCuCS1GL7G/KdLSr Cancel-Lock: sha1:qelNwVKrxW9ZGGuq438ZzzTPclA= User-Agent: Mozilla/5.0 (X11; Linux i686; rv:31.0) Gecko/20100101 Thunderbird/31.3.0 In-Reply-To: Xref: news.eternal-september.org comp.lang.ada:24340 Date: 2015-01-04T10:56:38-02:00 List-Id: On 01/03/2015 10:58 PM, hreba wrote: > My Ada book says that 'access const' types serve for readonly > variables but I am not sure whether I grasped the idea. > > I want a readonly variable 'n' as component of a record 'R'. The > variable which is accessed by 'n', let's call it 'nv' must be hidden, > otherwise the client could change it. > > Consequently 'R' must be extensible, that is tagged. It makes no sense > to use the base class alone (without something for 'n' to point to), > so it must be abstract. As the pointer-target relation wouldn't be > conserved in a simple assignment, the record must be limited. This > leads to > > type R is abstract tagged limited record > n: access constant Integer; > end record; > > type Rv is new R with private; > > private > > type Rv is new R with record > nv: aliased Integer; > end record; > > The value of 'n' would be defined in an initialization procedure: > > procedure Init (rec: in out Rv) is > begin > rec.n:= rec.nv'Access; > end Init; > > This however gives me an error message: > > non-local pointer cannot point to local object > > Now I am really confused: > > - Are readonly variables really handled this way, typically? > - How can rec.nv be local and rec.n not? > - How would you write the correct initialization procedure? > > All this seems pretty complicated to somebody used to Oberon, where > all this would be simply written as > > TYPE > R* = RECORD > n-: INTEGER; > END; > I am responding to my own post in order not to repeat myself in individual answers. First of all: thanks for your help. Second, I thought the meaning of "read-only" was clear, but perhaps it isn't. What I meant is what Brad expressed as "read only from the client perspective but modifiable locally". Third, looking at the answer of Shark8 which solves the problem using "access const", I guess using a function returning the value of a hidden variable would be a much simpler solution. An example of a read-only variable would be the number of elements in a linked list. Within the defining package it is changed whenever the user adds or removes an element, you want the user to read it, but by no means you want to give him write access to it. I guess I understand now why 'Length' in Ada.Containers.Doubly_Linked_Lists is a function and no read-only variable. Fourth, in what practical cases do you really use 'access const' for read-only variables; I thought my case a pretty typical one? -- Frank Hrebabetzky +55 / 48 / 3235 1106 Florianopolis, Brazil