Statement ACCESS | ASSIGN Foundation

Declares a redirection for member variable access

Syntax
ACCESS | ASSIGN [CLASS] METHOD <MethodName> [VAR <VarName>]
or
ACCESS ASSIGN [CLASS] METHOD <MethodName> [VAR <VarName>]
Parameters
<MethodName>
<MethodName> is the identifier for the method to be declared.
<VarName>
<VarName> is the identifier for the member variable which gets redirected by method <MethodName>. If the member variable is accessed, the method is called. When <VarName> is not specified, <MethodName> is used as the member variable's identifier.
Description

The syntactical notation object:varName for accessing a member variable leads to a redirection of the message sent to an object. When the member variable is accessed, a method is called. The return value of the method <MethodName> then defines the value of the accessed member variable. In case of an ASSIGN method, the value to be assigned to the member variable is passed as parameter to the method. The message redirection only takes place when the member variable is accessed from outside the method. Within the program code of the method no redirection occurs and the member variable can be accessed directly.

Encapsulation of member variables

If the member variable <VarName> is declared in the class, access to it can be completely encapsulated by ACCESS and ASSIGN methods. Read access invokes an ACCESS method and write access calls the ASSIGN method. Read access occurs when a member variable's value is retrieved from an object, while write access takes place when changing a member variable's value. A method can be declared for one or both types of access.

The member variable must have the same visibility attribute as the method. It is not possible, for example, to declare an ACCESS | ASSIGN method as EXPORTED: and create the member variable with the PROTECTED: attribute. If the method is declared as CLASS METHOD, <VarName>must be declared as CLASS VAR.

Computed member variables

If the member variable is not declared in the class with the VAR statement, the identifier <VarName> serves as message for invoking the method <MethodName>. In this case, an appropriate value must be determined within the method implementation and returned. This way, an object appears to have a member variable, but the member variable's "value" is always the computed return value of a method (see the example).

Redirections established using ACCESS and ASSIGN methods behave according to the following rules:

Once declared, the redirection remains established for the lifetime.

The method <MethodName> can be overloaded in subclasses.

Introduction of ACCESS and ASSIGN methods for member variables inherited from superclasses is supported.

In case a member variable is encapsulated by a ACCESS or ASSIGN method, the member variable can only be accessed inside the ACCESS and ASSIGN methods. All other methods accessing the member variable are redirected to the ACCESS and ASSIGN methods.

Examples
ACCESS methods

// The example implements a class to demonstrate the effect of 
// ACCESS methods. The best way for understanding ACCESS methods 
// is running the example program in the debugger and stepping 
// through the code. The message redirection becomes obvious. 
// The method :date() has both attributes ACCESS and ASSIGN. 
// It is invoked for both read and write accessing of the 
// member variable :date. 
CLASS Days 
   EXPORTED: 
   VAR date 

   INLINE METHOD init 
      ::date := Date() 
   RETURN self 

   ACCESS ASSIGN METHOD date 

   ACCESS METHOD today 
   ACCESS METHOD yesterday 
   ACCESS METHOD tomorrow 
ENDCLASS 

METHOD Days:date( dDate ) 
   IF Valtype( dDate ) == "D" 
      ::date := dDate 
   ENDIF 
RETURN ::date 

METHOD Days:yesterday 
RETURN CDoW( ::date-1 ) 

METHOD Days:today    
RETURN CDoW( ::date ) 

METHOD Days:tomorrow 
RETURN CDoW( ::date+1 ) 


PROCEDURE Main 
   LOCAL oD := Days():new() 

   // syntactical access of a member variable 
   // executes a method 
   ? oD:date 

   // the "value" of "member variables" 
   // is computed by methods 
   ? oD:yesterday 
   ? oD:today 
   ? oD:tomorrow 

   ? oD:date := Date()+3 
   ? oD:yesterday 
   ? oD:today 
   ? oD:tomorrow 
RETURN 

ASSIGN methods

// Two classes are used in this example to show read and write 
// access to member variables via methods. Each method displays 
// ProcName() and ::className() to visualize program flow. 

PROCEDURE Main 
   LOCAL objA := ClassA():new() 
   LOCAL objB := ClassB():new() 

   ? objA:value := 10 
   ? objA:value ++ 
   ? objA:value 

   ? objB:value := 100 
   ? objB:value /= 2 
   ? objB:value 
RETURN 

************ 
CLASS ClassA 
   EXPORTED: 
   VAR value 
   ASSIGN METHOD put VAR value  // method for write access 
   ACCESS METHOD get VAR value  // method for read access 
ENDCLASS 

METHOD ClassA:put( xValue ) 
   ? "ASSIGN",ProcName(),::className(),xValue 
   ::value := xValue 
RETURN self 

METHOD ClassA:get 
   ? "ACCESS",ProcName(),::className() 
RETURN ::value 

************************ 
CLASS ClassB FROM ClassA        // derived class 
   EXPORTED: 
   METHOD put                   // overloaded method 
ENDCLASS 

METHOD ClassB:put( xValue ) 
   ? "ASSIGN",ProcName(),::className(),xValue 
   ::value := xValue 
RETURN self 
Feedback

If you see anything in the documentation that is not correct, does not match your experience with the particular feature or requires further clarification, please use this form to report a documentation issue.