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,FREEMAIL_FROM autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,248f80acc3d5ccb3,start X-Google-Attributes: gid103376,public From: "Vladimir Olensky" Subject: Objects properties - Ada design issues question Date: 2000/02/04 Message-ID: X-Deja-AN: 581501443 Organization: Posted via Supernews, http://www.supernews.com X-MimeOLE: Produced By Microsoft MimeOLE V4.72.3110.3 Newsgroups: comp.lang.ada X-Complaints-To: newsabuse@supernews.com Date: 2000-02-04T00:00:00+00:00 List-Id: Objects properties - Ada design issues question: In "Black Box" design model any object may have some properties (run time or design ) that need to be known to the client of that "Black Box" object. Some of them are read-write properties, some others are read-only properties. Last ones are viewed as constants by clients but could be updated internally, so they have read-write access internally. The notion of properties is already supported by some of the non standardized languages (e.g. Delphi Object Pascal). It is some pain though to model them in Ada. The problem is that when designing the hierarchy of some types we do not know in advance how many and which properties descendants of the root type will have. On the other hand we want to provide standard common interface to each "Black Box" component including access to it's properties which we do not know in advance. So this means that we do not want to export additional Get and Set functions/procedures for each new descendant with new set of properties and we want to get access (read or write) to these properties in some unified way without exporting new set of Get and Set functions/procedures for each new descendant. In Ada if we want to have predetermined and separate access to each internal "Black Box" property (read or read-write) we have to extend our public interface adding new Get and Set procedures for each internal property and separately describe each property in our interface. This brakes our intent not to disturb common hierarchy interface by extending it for descendant types. In other words it does not allow us to obtain highest possible level of encapsulation by hiding Get and Set individual property procedures from clients. This means that we are not able to provide unified property interfaces for the whole type hierarchy. One of two possible ways in Ada to provide unified access to each instance property is to have record that contains all the object properties. This record is in turn is one of the field in the "Black Box" object record. Doing that we can use root predefined Get_Properties and Set_Properties procedures which retrieve or set the whole record of properties all at once. Though this approach allows us to obtain some additional level of encapsulation we lose two things. 1. First we can not now address each property individually as Get and Set procedures are applied to the whole properties record. One should remember that main intent of the Get and Set procedure is not only to extract or set some properties fields. Get procedure should update appropriate property fields from some object internal and thus make them available for client. Set procedure should not only update property field in the property record but put it into effect internally. 2. Secondly this does not allow us to have some properties to have different access privileges (some are with read-write access and some are with read-only access which is a constant view). All of the entries in the property fields of the object instance property record entry will have read-write access for the client which is not good. This is due to the fact that Ada does not allow to have constant fields in record types. So described above approach could be considered only as some extremely limited way to provide common interface to any descendant object properties. I should mention that for "static" type properties that is common for several type instances it is very easy to provide constant view of the internal read-write variable to the client of the package without need to use access types for client. (If anyone is interested I may provide working example of that). But we need to be able to do that for properties of each object instance so though it may be useful in some situations it does not help much. I like the approach to this problem implemented in Delphi Object Pascal. We may declare some public or published object properties and assign for each property individual Read or Write or both procedures that are not visible to the clients as they are located in the private object declaration part. In addition we may also use different property use and access modifiers. Delphi approach is very close to Ada syntax. We can just declare something like this: type T = class (some_parent_class) private function Get_Property1 () : Integer; function Get_Property2 () : Integer; procedure Set_Property1 (prop :Integer); procedure Set_Property2 (prop: Integer); public property prop_1 : Integer read Get_Property1 write Set_Property1; published property prop_2 : Integer read Get_Property2 write Set_Property2; end; Then having an instance of type T , we can access that attributes directly by using ":=" operator. If the property is a right hand operand then Get_Propery is involved. If the property is a left hand operand then Set_Propery is involved. program Var obj : T; p1, p2 : Integer; begin p1 := obj.Prop_1; p2 := obj.Prop_2; { or } obj.Prop_1 := 2; obj.Prop_2 := 10; end; In Ada it seems that we can do something like that by overloading ":=" operator. But we can do that only for distinct types but not for the particular property instance/field. So this is not perfect solution. On the other hand I see that current Ada representation syntax perfectly fits here. We can just declare: package P is type T is tagged private; type T1 is new T with record -- public properties A and B; -- they are public views of some internal states -- which in turn could be fields of some complex -- "Black Box" internal structures; A : [property] constant Integer; B : [property] Integer; end record; private type T is tagged record < some fields> end record; function Get_Property1 (obj: in out T ) : Integer; function Get_Property2 (obj: in out T ) : Integer; procedure Set_Property2 (obj: in out T; prop: Integer); -- and then representation clause: for T.A'Get use Get_Property1 (obj: in out T ) : Integer; for T.B'Get use Get_Property1 (obj: in out T ) : Integer; for T.B'Set use Set_Property1 (obj: in out T; prop: Integer); end P; No need to introduce any new keywords. May be only the PROPERTY keyword could be introduced for clarity but generally there is no need to do that at all. Everything fit perfectly into current Ada syntax. It would be very interesting to hear different opinions regarding this "objects properties" issue and it's prospective of being implemented in future Ada revisions. As was shown this could be done without changing current Ada syntax. Regards, Vladimir Olensky