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-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,13b19740d69cbdc2 X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2003-10-10 02:15:22 PST Path: archiver1.google.com!news2.google.com!news.maxwell.syr.edu!fu-berlin.de!uni-berlin.de!tar-alcarin.cbb-automation.DE!not-for-mail From: Dmitry A. Kazakov Newsgroups: comp.lang.ada Subject: Re: Modes (was unbounded_string) Date: Fri, 10 Oct 2003 11:15:27 +0200 Message-ID: References: <20031010074015.761204C40C1@lovelace.ada-france.org> NNTP-Posting-Host: tar-alcarin.cbb-automation.de (212.79.194.111) Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Trace: news.uni-berlin.de 1065777320 19797537 212.79.194.111 (16 [77047]) X-Newsreader: Forte Agent 1.8/32.548 Xref: archiver1.google.com comp.lang.ada:589 Date: 2003-10-10T11:15:27+02:00 List-Id: On Fri, 10 Oct 2003 02:27:19 -0600, "Andrew Carroll" wrote: >>>For all other types, the compiler chooses the parameter >>>mode best suited to the type. >Great!!! SIGN ME UP!!! But...is it possible that the compiler >doesn't get it right? What would I need to do if I found that >the compiler didn't get it right in my testing? I'm guessing >that you will say, "specify the mode". You cannot directly specify the by-value vs. by-reference mode. >package x is >type x; >type xptr is access x; >type x is tagged limited record > head: nodeptr; > something: unbounded_string; >end record; > >--creates a new node to put into the 'head' list. >--new node is created from information in token. >--token has nothing to do with the 'something' variable >--declared in the record above. >procedure add(this: xptr; token: unbounded_string); > >end x; > >So, with the above code "example", xptr is passed as an 'in' >or 'in out' mode at the add procedure? It depends only on whether the value of the pointer This has to be modified by Add. If yes, then the mode is "in out". If not, then the mode is "in". If it is a garbage and has to be set in Add, then the mode has to be "out". Note that all this has nothing to do with the object the value of This points to. It is This, an access type object, which is passed to Add, not the object which it accidentally points (or not) to. >Are you saying that I should use just x and not xptr as the >parameter so that the compiler will choose the correct mode? The rule of thumb is: newer use pointers if there is an alternative. So: procedure Add (This: in out X; Token: Unbounded_String); Note that X is tagged limited, so it will be passed by reference as expected. There is nothing to choose for the compiler. Observe also subtle pitfalls caused by pointers: your Add is not a primitive subprogram of X. So it cannot be overridden by descendant types! Thus another rule: if a pointer, then when possible anonymous: procedure Add (This: access X; Token: Unbounded_String); -- This will be a primitive subprogram of X >If so, you recommend it because of deallocation issues? Irrelevant. In 90% cases, just forget that there is any difference between by-reference vs. by-value. >On to strings... >>> Basically, you have reinvented the wheel. What you have is >>> Unbounded_String, but with its guts hanging out all over the place, >>> instead of using information hiding as a software engineer should, and >>> as Ada.Strings.Unbounded does. >[snip] >>> The "Ada Way" / "Ada idiom" > >Is there something in the code below that I missed about information >hiding? > >Temp: gnat.os_lib.String_Access; >... >Temp := gnat.os_lib.getenv("QUERY_STRING"); >... >--------------------------------------- >-- ready to use Temp for something else >--------------------------------------- >Temp := gnat.os_lib.getenv("SOME_OTHER_VARIABLE"); > >Considering the code above, what is the "Ada idiom" to "resize" a String >without pointers and dynamic allocation? In other words; what "Ada >idiom" code would you write to do the same thing I did, without pointers >and dynamic allocation? You don't have to write the code, a good >reading reference would be okay. with Ada.Strings.Unbounded; use Ada.Strings.Unbounded; with GNAT.OS_Lib; use GNAT.OS_Lib; ... Temp : Unbounded_String; ... Temp := To_Unbounded_String (Getenv ("QUERY_STRING").all); -- Note that Temp is a copy of the env-string. So you can -- modify it. ... Temp := To_Unbounded_String (Getenv ("SOME_OTHER_VARIABLE").all); BUT FORGET IT AT ONCE! The Ada way is not to create objects you do not need. The right way: with GNAT.OS_Lib; use GNAT.OS_Lib; ... declare -- I need the value of QUERY_STRING here Temp : String renames Getenv ("QUERY_STRING").all; -- Temp is an alias to the env-string. You cannot modify it. -- Yet it is not a pointer. An analogue would be C++ reference begin ... -- Doing with Temp everything I can to do to -- a constant String end; -- I don't need it anymore for example: function Query_Variable_Name return String is ...; -- -- Print all queried env-strings, which values start with 'A': -- loop declare Name : constant String := Query_Variable_Name; begin exit when Name'Length = 0; declare Value : String renames Getenv (Name).all; begin if Value'Length > 0 and then Value (Value'First) = 'A' then Put_Line (Name & "=" & Value); end if; end; end; end loop; --- Regards, Dmitry Kazakov www.dmitry-kazakov.de