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: a07f3367d7,efde8669839c1c0a X-Google-Attributes: gida07f3367d7,public,usenet X-Google-NewGroupId: yes X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news2.google.com!news1.google.com!npeer02.iad.highwinds-media.com!news.highwinds-media.com!feed-me.highwinds-media.com!post01.iad.highwinds-media.com!newsfe24.iad.POSTED!7564ea0f!not-for-mail From: Brad Moore User-Agent: Thunderbird 2.0.0.23 (X11/20090817) MIME-Version: 1.0 Newsgroups: comp.lang.ada Subject: Re: Proper program structure References: <638d582c-f275-48a9-aa2a-237f2edd123c@c37g2000yqi.googlegroups.com> In-Reply-To: Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 8bit Message-ID: NNTP-Posting-Host: 70.72.159.148 X-Complaints-To: internet.abuse@sjrb.ca X-Trace: newsfe24.iad 1254411422 70.72.159.148 (Thu, 01 Oct 2009 15:37:02 UTC) NNTP-Posting-Date: Thu, 01 Oct 2009 15:37:02 UTC Date: Thu, 01 Oct 2009 09:36:52 -0600 Xref: g2news2.google.com comp.lang.ada:8562 Date: 2009-10-01T09:36:52-06:00 List-Id: Maciej Sobczak wrote: > On 1 Paz', 08:34, Brad Moore wrote: > >> See my example below. I have each component as a private child of Cars. > > Well, I was too quick to reply. > Your example does not do what I need. It allows the components to see > the visible spec of the containing car (in your example, Gear_Box > calls *public* procedure Shift_Gear in Vehicle), but not the car's > structure. > In other words, the Engine still cannot see the Gear_Box within the > same car. > > It is of course possible to expose delegating operations, but this > pollutes the public interface of the car with operations that are of > interest only to its private components. Users should not have access > to these operations. > > -- > Maciej Sobczak * www.msobczak.com * www.inspirel.com > > Database Access Library for Ada: www.inspirel.com/soci-ada OK, but I can apply a similar technique to hide the routines from the public interface of the car. In this case, I renamed the Cars.Vehicle package to be Cars.Vehicle_Internal, then created a public Cars.Vehicle package that wraps the internal one, but hides the interfaces that you do not want to expose. Is this version acceptable? Revised Example: ----------------------------------------------------- with Cars.Vehicle; procedure Main is My_Car : Cars.Vehicle.Vehicle_Type := Cars.Vehicle.Construct; begin null; end Main; ----------------------------------------------- package Cars is pragma Pure; end Cars; -------------------------------------------- private with Cars.Vehicle_Internal; package Cars.Vehicle is type Vehicle_Type (<>) is limited private; function Construct return Vehicle_Type; private use Cars.Vehicle_Internal; type Vehicle_Type is record Internals : Vehicle_Internal_Type; end record; end Cars.Vehicle; ----------------------------------------- package body Cars.Vehicle is function Construct return Vehicle_Type is begin return New_Vehicle : Vehicle_Type := Vehicle_Type'(Internals => Vehicle_Internal.Construct) do return; end return; end Construct; end Cars.Vehicle; ------------------------------------------ with Cars.Types; use Cars.Types; private with Cars.Wheels, Cars.Chassis, Cars.Engine, Cars.Gear_Box; private package Cars.Vehicle_Internal is type Vehicle_Internal_Type is limited private; procedure Shift_Gears (Car : in out Vehicle_Internal_Type; Gear : Gear_Type); function Construct return Vehicle_Internal_Type; private use Cars.Wheels, Cars.Chassis, Cars.Engine, Cars.Gear_Box; type Wheel_Array_Type is array (1 .. 4) of Wheel_Type; type Vehicle_Internal_Type is limited record Wheels : Wheel_Array_Type; Chassis : Chassis_Type; Engine : Engine_Type; Gear_Box : Gear_Box_Type (Vehicle_Internal_Type'Access); end record; end Cars.Vehicle_Internal; -------------------------------------- package body Cars.Vehicle_Internal is function Construct return Vehicle_Internal_Type is begin return New_Vehicle : Vehicle_Internal_Type do Gear_Box.Select_Gear (New_Vehicle.Gear_Box, Park); return; end return; end Construct; procedure Shift_Gears (Car : in out Vehicle_Internal_Type; Gear : Gear_Type) is begin Cars.Engine.Shift_Gears (Motor => Car.Engine, Gear => Gear); end Shift_Gears; end Cars.Vehicle_Internal; ------------------------------------------- private package Cars.Wheels is type Wheel_Type is private; private type Length_In_Inches is new Natural; subtype Wheel_Diameter_Type is Length_In_Inches range 30 .. 80; type Wheel_Type is record Diameter : Wheel_Diameter_Type := 50; end record; end Cars.Wheels; -------------------------- with Cars.Types; use Cars.Types; limited with Cars.Vehicle_Internal; private package Cars.Gear_Box is type Gear_Box_Type (Containing_Vehicle : access Cars.Vehicle_Internal.Vehicle_Internal_Type) is private; procedure Select_Gear (Gear_Shift : in out Gear_Box_Type; Gear : Gear_Type); -- Somehow this gets called, presumably by user action. private type Gear_Box_Type (Containing_Vehicle : access Cars.Vehicle_Internal.Vehicle_Internal_Type) is null record; end Cars.Gear_Box; ------------------------------------- with Cars.Vehicle_Internal; package body Cars.Gear_Box is procedure Select_Gear (Gear_Shift : in out Gear_Box_Type; Gear : Gear_Type) is begin Cars.Vehicle_Internal.Shift_Gears (Car => Gear_Shift.Containing_Vehicle.all, Gear => Gear); end Select_Gear; end Cars.Gear_Box; -------------------------- with Cars.Types; use Cars.Types; private package Cars.Engine is type Engine_Type is private; procedure Shift_Gears (Motor : in out Engine_Type; Gear : Gear_Type); private type Engine_Type is record Current_Gear : Gear_Type; end record; end Cars.Engine; ------------------------------ package body Cars.Engine is procedure Shift_Gears (Motor : in out Engine_Type; Gear : Gear_Type) is begin Motor.Current_Gear := Gear; end Shift_Gears; end Cars.Engine; -------------------- private package Cars.Chassis is type Chassis_Type is private; private type Chassis_Type is null record; end Cars.Chassis;