Skip to content

Delegation of Access Methods

Object-access expressions delegate! This is a powerful and useful feature. When a message is sent to an object with the standard object access method, the access expression is evaluated using delegation (if required).

Send hello of B

Consider the above statement. This statement will be executed in two steps:

  1. The object ID of object B must be resolved. The runtime will search for a child object named B. If found, it will use that object ID. If no object is found, delegation will occur, and the search for an object named B will continue. This occurs until an object named B is found or delegation reaches the desktop object, at which point an error will result.

  2. If the ID is found, the message hello will be sent to the object ID evaluated in step 1.

The above statement could have been coded as:

Move (B(self)) to hoID
Send Hello of hoID

In this example, we are temporarily using an alternate syntax for the object name that more accurately shows how DataFlex resolves message names. When you see the syntax (object_name(self)), you are creating an expression asking DataFlex to find an object named object_name that is a child of self. Self is the current object, which is the object that is sending the message. Therefore, we are asking DataFlex to find the object and return its object handle (hoID). That handle is then used to receive the message.

Using the diagram on the previous page, what would happen if Object D sent this message? Since Object D does not have a child object named B, we might expect an error to occur. This would be an incorrect assumption. If Object D cannot resolve the access-method expression by finding a child object named B, it will ask its parent object, A, to resolve the expression (B(self)). Self is now Object A. Object A will attempt to find a child object named B, succeed, and return that object's ID in the expression. The message hello will now be sent to that ID. The message hello was not delegated; the object-access method was. This means that any object can send a message to a sibling object by using the (object_name(self)) access method.

What would happen if Object E sent this message? Object E will try to find a child named B. It will fail and delegate to Object D. Object D will try to find a child named B, fail, and delegate to Object A. Object A will find a child named B and return its object ID. The message hello will now be sent to that ID. This means that an object can send a message to any sibling of any of its ancestral objects.

By using the (object_name(self)) access method and its implicit delegation, an object may communicate with any child object and any object that its parent (or its grandparent, etc.) can communicate with.

Refer back to the object diagram to see how delegation of access methods allows objects to communicate. Object A can send a message to itself and its children (B and D). Object B can send a message to itself, its child (C), and, through delegation, Objects A and D. Object C can send messages to itself and, through delegation, Objects B, D, and A. Object E can send a message to itself and, through delegation, Objects D, B, and A. Objects C and E can never directly communicate.

Does this represent a breach of encapsulation? Objects are supposed to be able only to send messages to themselves, to their immediate children, and to their parents (through delegation). The (object_name(self)) expression is evaluated through delegation. This is proper. A message is then sent to that object ID. It is valid to send a message to any object as long as the ID of that object was obtained through a proper encapsulated technique.

Although this type of access method does not breach encapsulation, it does create a dependency between objects. If, for example, you have a DEO using (Vndr_DD(self)) as its DDO server, that DEO must be able to find an object named vndr_DD somewhere within its access-delegation path. The entry-form object depends on vndr_DD. If vndr_DD cannot be found by the entry form, it will not operate properly.

In DataFlex, referring to an object using an expression syntax or simply with its name accomplishes the same thing. These two code samples are the same:

Send Hello of (B(self))
Send Hello of B

We used the expression syntax to show how an object access method is evaluated. When writing programs, we will always use the simpler direct syntax.

Next Topic

Object Access Methods and Encapsulation