Chapter Contents

Previous

Next
SAS Component Language: Reference

Accessing Object Attributes and Methods With Dot Notation

SCL provides dot notation for directly accessing object attributes and for invoking methods instead of using the SEND and NOTIFY routines. Thus, dot notation provides a shortcut for invoking methods and for setting or querying attribute values. Using dot notation reduces typing and makes SCL programs easier to read.

Using dot notation enhances run-time performance if you declare the object used in the dot notation as an instance of a predefined class instead of declaring it as a generic object. The object's class definition is then known at compile time, enabling the SCL compiler to verify the method and to access attributes at that time. Moreover, since dot notation checks the method signature, it is the only way to access an overloaded method. SEND does not check method signatures. It executes the first name-matched method, and the program might halt if the method signature does not match.


Syntax

The syntax for dot notation is as follows:


object.attribute
or

object.method(<arguments>)

Where

object
specifies an object or an automatic system variable (for example, _SELF_). An object must be a component in a FRAME entry or a variable that is declared as an Object type in the SCL program. Automatic system variables like _SELF_ are declared internally as Object type, so they do not have to be declared explicitly as such in a program.

attribute
specifies an object attribute to assign or query. It can be of any data type, including Array. If the attribute is an array, use the following syntax to reference its elements:

object.attributeArray[i]

You can also use parentheses instead of brackets or braces when referencing the array elements. However, if you have declared the object as a generic object, the compiler interprets it as a method name rather than an attribute array. If you have declared a type for the object, and an attribute and method have the same name, the compiler still interprets the object as a method. To avoid this ambiguity, use brackets when referencing attribute array elements.

method
specifies the name of the method to invoke. If an object is declared with a specific class definition, the compiler can perform error checking on the object's method invocations.

If the object was declared as a generic object (with the OBJECT keyword), then the method lookup is deferred until run time. If there is no such method for the object, the program halts. If you declare the object with a specific definition, errors such as this are discovered at compile time instead of at run time.

You specify the arguments of the method in enclosed parentheses immediately following the method name. The parentheses are required whether or not the method needs any arguments.

Some methods may be defined to return a value of any SCL type. You can access this returned value by specifying a variable in the left side of the dot notation. For example:


return-value = object.method (<arguments>);
or

if ( object.method (<arguments>) ) then ...

The return value's type defaults to Numeric if it is not explicitly declared. If the declared type does not match the returned type, and the method signature is known at compile time, the compiler returns an error. Otherwise, a data conversion might take place, or the program will halt at run time.

If you override an object's INIT method, you must call _SUPER._INIT before you can use dot notation to set attribute values or to make other method calls.

Dot notation is not available in the INPUT and PUT functions.

By default, your application halts execution if an error is detected in the dot notation that is used in the application. You can control this behavior with the HALTONDOTATTRIBUTE or NOHALTONDOTATTRIBUTE option in the CONTROL statement. See CONTROL for more information.

Using Nested Dot Notation

You can also use dot notation in nested form. For example,


value = object.attribute1.method1().attribute2;
is equivalent to the following:

dcl object object1 object2;
object1 = object.attribute1;  /* attribute1 in object
                                 is of OBJECT type */
object2 = object1.method1();  /* method1 in object1 
                                 returns an object */
value   = object2.attribute2; /* assign the value of
                                 attribute2 in object2
                                 to the variable 
                                 'value'. */

You can also specify the nested dot notation as an l-value. For example,


object.attribute1.method1().attribute2 = value;
is equivalent to the following:

dcl object object1 object2;

object1 = object.attribute1; 
object2 = object1.method1();  
object2.attribute2 = value; /* assume 'value' has 
                               been initialized.  
                               This would set 
                               attribute2 in object2
                               to the value */


Examples

An application window contains a text entry control named clientName. The following examples show how to use dot notation to invoke methods and to query and assign attribute values. For example, the following statement uses dot notation to invoke the _gray method of the control:


clientName._gray();
This is equivalent to

call send('clientName','_gray');
You can change the text color to blue, using dot notation to set the value of its textColor attribute:

name.textColor='blue';
You can also use dot notation to query the value of an attribute. For example:

color=clientName.textColor;
You can use dot notation in expressions. You can use a method in an expression only if the method can return a value via a RETURN statement in its definition. For example, suppose you create a setTable method, which is a public method and accepts an input character argument (the name of a SAS table). The method determines whether a SAS table exists and uses the RETURN statement to pass the return code from the EXIST function.

setTable: public method dsname:i:char(41) return=num;
  rc = exist(dsname, 'DATA');
  return rc;
endmethod;
Then you could use a statement like the following to perform actions that depend on the value that the setTable method returned.

if (obj.setTable('sasuser.houses')) then
   /*  the table exists, perform an action */
else
   /*  the table doesn't exist,    */
   /*  perform another action      */
The next example shows how to use dot notation with an object that you create in an SCL program. Suppose class X is saved in the entry X.SCL, and the INIT section is saved in the entry Y.SCL.

class x;
  public num n;
  m: public method n1: num n2: num return=num;
    dcl num r;
    r = n1 + n2;
    /* return sum of n1 and n2 */
    return r;
 endmethod;
 m: public method c1: char c2:char return=char;
    dcl num s;
    /* concatenate c1 and c2 */
    s = c1 || c2;
    return s;
 endmethod;
endclass;

init:
  dcl x xobj = _new_ x();
  dcl num n;
  dcl string s;
  n = xobj.m(99,1);
  s = xobj.m("abc","def");
  put n= s=;
  return;
If you compile and run Y.SCL, it produces

n=100 s=abcdef


Implicit Behaviors of Dot Notation

Using dot notation to access an attribute causes the SCL compiler to implicitly generate a _getAttributeValue or _setAttributeValue method. Defining the attribute with a getCAM or setCAM method could result in some side effects.

The following procedure describes the process that the compiler uses to determine the attribute value for _getAttributeValue:

  1. Execute the getCAM method to determine the attribute value, if a getCAM method has been defined.

  2. Return the attribute value, if a value has been set.

  3. Return the initial class value, if no attribute value has been set.

The following procedure describes the process that the compiler uses to determine the attribute value for _setAttributeValue:

  1. Check whether the attribute value is in the ValidValues list. If the ValidValues metadata is an SCL entry, it is executed first to get the list of values to check the attribute value against.

  2. Run the setCAM method, if it is defined, which gives users a chance to perform additional validation and to process their own side effects.

  3. Store the object's given value.

  4. Broadcast the "attributeName Changed" event if the SendEvent metadata is set to Yes.

Note:    If you use dot notation to access a class attribute, program execution halts if any error is detected while the _getAttributeValue or _setAttributeValue method is running. Explicitly invoking the _getAttributeValue or _setAttributeValue method allows the program to control the halt behavior. The _getAttributeValue or _setAttributeValue method also enables you to check the return code from the method. For example:


rc = obj._setAttributeValue (`abc');
if ( rc ) then do;
    /* error detected in the _setAttributeValue method */
    ...more SCL statements...
    end;
  [cautend]


Chapter Contents

Previous

Next

Top of Page

Copyright © 1999 by SAS Institute Inc., Cary, NC, USA. All rights reserved.