A Rexx program contains one or more executable code units. Directive instructions separate these executable units. A directive begins with a double colon (::) and is a nonexecutable instruction. For example, it cannot appear in a string for the INTERPRET instruction to be interpreted. The first directive instruction in a program marks the end of the main executable section of the program.
For a program containing directives, all directives are processed first to set up the program's classes, methods, and routines. Then any program code in the main code unit (preceding the first directive) is processed. This code can use any classes, methods, and routines that the directives established.
The ::ATTRIBUTE directive creates attribute methods and defines the method properties.
>>-::ATTRIBUTE--name--+-----+-------+-------+-------------------------> +-GET-+ +-CLASS-+ +-SET-+ +-PUBLIC--+ +-GUARDED---+ +-UNPROTECTED-+ >--+---------+--+-----------+--+-------------+-------------------> +-PRIVATE-+ +-UNGUARDED-+ +-PROTECTED---+ >--+---------------+---;----------------------------------------->< +-EXTERNAL-spec-+
The ::ATTRIBUTE directive creates accessor methods for object instance variables. An accessor method allows an object instance variable to be retrieved or assigned a value. ::ATTRIBUTE can create an attribute getter method, a setter method, or the getter/setter pair.
The name is a literal string or a symbol that is taken as a constant. The name must also be a valid Rexx variable name. The ::ATTRIBUTE directive creates methods in the class specified in the most recent ::CLASS directive. If no ::CLASS directive precedes an ::ATTRIBUTE directive, the attribute methods are not associated with a class but are accessible to the main (executable) part of a program through the .METHODS built-in object. Only one ::ATTRIBUTE directive can appear for any method name not associated with a class. See .METHODS for more details.
If you do not specify either SET or GET, ::ATTRIBUTE will create two attribute methods with the names name and name=. These are the methods for getting and setting an attribute. These generated methods are equivalent to the following code sequences:
::method "NAME=" /* attribute set method */ expose name /* establish direct access to object variable (attribute) */ use arg name /* retrieve argument and assign it to the object variable */ ::method name /* attribute get method */ expose name /* establish direct access to object variable (attribute) */ return name /* return object's current value */
Both methods will be created with the same method properties (for example, PRIVATE, GUARDED, etc.). If GET or SET are not specified, the pair of methods will be automatically generated. In that case, there is no method code body following the directive, so another directive (or the end of the program) must follow the ::ATTRIBUTE directive.
If GET or SET is specified, only the single get or set attribute method is generated. Specifying separate GET or SET ::ATTRIBUTE directives allows the methods to be created with different properties. For example, the sequence:
::attribute name get ::attribute name set private
will create a NAME method with PUBLIC access and a NAME= method with PRIVATE access.
The GET and SET options may also be used to override the default method body generated for the attribute. This is frequently used so the SET attribute method can perform new value validation.
::attribute size get ::attribute size set expose size /* establish direct access to object variable (attribute) */ use arg value /* retrieve argument */ if datatype(value, "Whole") = .false | value < 0 then raise syntax 93.906 array ("size", value) size=value
If you specify the CLASS option, the created methods are class methods. See Objects and Classes. The attribute methods are associated with the class specified on the most recent ::CLASS directive. The ::ATTRIBUTE must be preceded by a ::CLASS directive if CLASS is specified.
If the EXTERNAL option is specified, then spec identifies a method in an external native library that will be invoked as the named method. The spec is a literal string containing a series of whitespace delimited tokens defining the external method. The first token must be the word LIBRARY, which indicates the method resides in a native library of the type allowed on a ::REQUIRES directive. The second token must identify the name of the external library. The external library is located using platform-specific mechanisms for loading libraries. For Unix-based systems, the library name is case-sensitive. The third token is optional and specifies the name of the method within the library package. If not specified, the ::METHOD name is used. The target package method name is case insensitive.
If the SET or GET option is not specified with the EXTERNAL option, then two method objects need to be created. The target method name is appended to the string "GET" to derive the name of the getter attribute method. To generate the setter attribute method, the name is appended to the string "SET". If GET or SET is specified and the method name is not specified within spec, then the target library method name is generated by concatenating name with "GET" or "SET" as appropriate. If the method name is specified in spec and GET or SET is specified, the spec name will be used unchanged.
-- maps "NAME" method to "GETNAME and -- "NAME=" to "SETNAME" ::ATTRIBUTE name EXTERNAL "LIBRARY mylib" -- maps "ADDRESS" method to "GETADDRESS" ::ATTRIBUTE address GET EXTERNAL "LIBRARY mylib" -- maps "ADDRESS=" method to "setHomeAddress" ::ATTRIBUTE address SET EXTERNAL "LIBRARY mylib setHomeAddress"
You can specify all options in any order.
If you specify the PRIVATE option, the created methods are private methods. Private methods have restricted access rules on how they can be invoked. See Public versus Private Methods for details of how private methods can be used. If you omit the PRIVATE option or specify PUBLIC, the method is a public method that any sender can activate.
If you specify the UNGUARDED option, the methods can be called while other methods are active on the same object. If you do not specify UNGUARDED, the method requires exclusive use of the object variable pool; it can run only if no other method that requires exclusive use of the object variable pool is active on the same object.
If you specify the PROTECTED option, the method methods are protected methods. (See The Security Manager for more information.) If you omit the PROTECTED option or specify UNPROTECTED, the methods are not protected.
It is an error to specify ::ATTRIBUTE more than once within a class definition that creates a duplicate get or set method.