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;