A
custom access method (
CAM) is a
SAS/AF software
method that is associated with an
attribute. The CAM is automatically executed to perform additional processing when the attribute's
value is queried (with either dot notation or a direct _getAttributeValue call) or
set (with either dot notation or a direct _setAttributeValue call). You can use the
Class Editor to assign a CAM to a
class attribute.
CAMs operate just like any other method, with a few special considerations:
-
You should never call a CAM directly; instead, rely on the _getAttributeValue or _setAttributeValue
methods to
call it automatically.
-
CAMs in SAS classes are protected
methods to help enforce indirect execution via the _getAttributeValue
and _setAttributeValue methods. Component developers are encouraged
to create all CAMs as Scope=
Protected
methods to encourage the use of dot notation and to inhibit the direct calling of
CAMs by developers who use the
component.
-
A CAM always has a single
signature and should not be overloaded. The CAM signature contains a single argument that is
the same
type as its associated attribute. A CAM always returns a numeric value as a return code
that indicates success or
failure. For example, if a CAM is specified for a character variable, its signature
is (C)N.
-
The CAM must be defined for the
object that contains the attribute that calls it. In other words, if
object.myAttribute
calls a CAM named
setcamMyAttribute
, then
setcamMyAttribute
must be a method on
object
.
-
CAMs may be added only to New or
Overridden attributes.
-
Default names for custom access
methods in SAS classes follow this format:
For example, consider an object that has an attribute whose value is set to a
SAS catalog. You can add a CAM to that attribute to determine whether the value is an existing
SAS catalog as follows:
-
Create a new class whose parent is sashelp.fsp.object.class
and
whose description is Document Object
.
-
Save the class as sasuser.test.document.class
.
-
In the Attributes
node of the Class Editor, select New Attribute from the pop-up menu and add a character attribute named catalogToRead
.
-
In the Set CAM cell for the catalogToRead
attribute, select the setcamCatalogToRead
method from the drop-down list. When you are prompted to add the method, click Yes.
-
In the New Method dialog
box, click
Source and add the following code
to the
sasuser.test.document.scl
entry:
USECLASS sasuser.test.document.class;
/* ...other methods can be defined here... */
setcamCatalogToRead: Protected method
name:input:char(83)
return=num;
if name eq ” then return(0);
if cexist(name) eq 0 then
do;
/* set the errorMessage attribute */
errorMessage = 'ERROR: Catalog does not exist.';
put errorMessage;
return(1);
end;
else return(0);
endmethod;
enduseclass;
-
Compile and save the
SCL, close the
Source window and the New
Method dialog box, and then close the Class Editor.
When the attribute is set via SCL (for example,
document.catalogToRead =
'sasuser.myclasses';
), the
setCAM is called, verifying that the catalog is a valid SAS catalog. If the catalog that
is specified is an invalid SAS catalog name or does not exist,
an error message is generated and the setCAM program halts.
The same CAM could be expanded to do more than simple validity checking. For example,
you could
add processing to the CAM to read information from the selected catalog and to store
that information in a list attribute named
contents
when the
catalogToRead
attribute is set:
USECLASS sasuser.test.document.class;
/* ...other methods can be defined here... */
setcamCatalogToRead: Protected method
name:input:char(83)
return=num;
dcl num rc;
if name eq ” then return(0);
if cexist(name) eq 0 then
do;
/* set the errorMessage attribute */
errorMessage = 'ERROR: Catalog does not exist.';
put errorMessage;
return(1);
end;
else do;
/* use the catalog entry list model to read the catalog */
/* and return the four-level name of each entry in it */
dcl sashelp.classes.catalogentrylist_c.class catobj;
catobj = _new_ sashelp.classes.catalogentrylist_c();
catobj.catalog=name;
rc=clearlist(contents);
contents = copylist(catobj.items);
catobj._term();
return(0);
end;
endmethod;
enduseclass;