SAS/AF: Examples using Collection Class
From online help we have
The Collection Class is a data container for collecting and holding items of any type, including numbers, character strings, lists, or objects.
And for _apply()
Calls the ACTION method of the input object on each item in the collection
So _apply() does the same thing to each thing in the collection. This can come in handy. An action class is any class that implements a method named Action.
Two examples
Squad salute
Create these SCL entries
sasuser.actions.Soldierclass.scl
SAVECLASS this entry to create the Soldier class.
class sasuser.actions.soldier; protected num id; soldier: public method id:num; _self_.id = id; endmethod; salute: public method; put id= ' saluting'; endmethod; endclass;
sasuser.actions.Saluteclass.scl
SAVECLASS this entry to create the Salute action class.
class sasuser.actions.salute; action: public method X:Object Y:Object ; X.salute(); Y = X; endmethod; action: public method X:Num Y:Num; Y=X; endmethod; action: public method X:Char Y:Char; Y=X; endmethod; action: public method X:List Y:List; Y=X; endmethod; endclass;
work.actions.Squad.scl
COMPILE and TESTAF this entry to see _apply do its stuff.
init: declare sashelp.classes.collection c = _new_ sashelp.classes.collection (); declare sasuser.actions.salute salute = _new_ sasuser.actions.salute (); do i = 1 to 4; c._add ( _new_ sasuser.actions.soldier (i) ); end; c._apply(salute); do i = 1 to listlen (c.items); declare object s = getItemO (c.items,i); s._term(); end; salute._term(); c._term(); return;
The log reads
id=4 saluting id=3 saluting id=2 saluting id=1 saluting
Object method invocations and attribute assignments
Consider a much more practical Collection, a group of widgets in a frame. A simple such collection is one of Text Entry Controls. You want them to all have the same appearance, but want to experiment with styles or themes at run-time. You might develop (or resuse SAS') dialogs for specifying various aspects of widgets which could then be applied to a collection of widgets.
sasuser.actions.Dispatchclass.scl
SAVECLASS this entry to create the Dispatch action class. Lots of interesting things are going on. The action method returns the input object after doing something with it. The something in turn is specified by the methods named method and value which return a self reference. Thus when either method() or value() are invoked as the input parameter to _apply() the stage is set for the 'blackbox' iteration _apply does to the items in the collection. Since self is returned, the same objects action() will be run. Additionally, method() can handle any number of and type of arguments since it uses the rest= option of the method statement. A nice tight scheme, no?
Class sasuser.actions.Dispatch / ( description = 'Action class for use with objects in a Collection._apply()' ) ; protected Char mode; protected Char method ; protected List arglist / (initialValue = {}); protected Char attribute ; protected List lvalue; protected Char cvalue; protected Object ovalue; protected Num nvalue; action: Public Method X:Object Y:Object; select (mode); when ('method') call apply (X, method, arglist); when ('cvalue') X._setAttributeValue (attribute, cvalue); when ('nvalue') X._setAttributeValue (attribute, nvalue); when ('lvalue') X._setAttributeValue (attribute, lvalue); when ('ovalue') X._setAttributeValue (attribute, ovalue); otherwise put 'ERROR: ' mode=; end; Y=X; Endmethod; action: public method X:Num Y:Num; Y=X; endmethod; action: public method X:Char Y:Char; Y=X; endmethod; action: public method X:List Y:List; Y=X; endmethod; method: Public Method aMethod:input:char rest=methodArgs return=Object; mode = 'method'; method = aMethod; declare num rc; if methodArgs then rc = copylist (methodArgs,'N',arglist); else rc = clearlist (arglist); return _self_; endmethod; value: Public Method name:char value:char return=Object; mode = 'cvalue'; attribute = name; cvalue = value; return _self_; endmethod; value: Public Method name:char value:num return=Object; mode = 'nvalue'; attribute = name; nvalue = value; return _self_; endmethod; value: Public Method name:char value:list return=Object; mode = 'lvalue'; attribute = name; lvalue = value; return _self_; endmethod; value: Public Method name:char value:object return=Object; mode = 'ovalue'; attribute = name; ovalue = value; return _self_; endmethod; EndClass ;
sasuser.actions.Testdispatch.frame
Place three (3) Text Entry Control and a Push Button Control in the frame
sasuser.actions.Testdispatch.scl
COMPILE
pushbutton1: declare sashelp.classes.collection c = _new_ sashelp.classes.collection (); * use object to prevent strong signature checking; declare object dispatch = _new_ sasuser.actions.dispatch (); c._add (textentry1); c._add (textentry2); c._add (textentry3); c._apply (dispatch.method('_setBorderStyle', 'Simple')); c._apply (dispatch.value('backgroundColor', 'CXCCDDFF')); c._apply (dispatch.value('borderColor', 'CXAABBFF')); c._apply (dispatch.value('textColor', 'CX0000FF')); c._apply (dispatch.value('borderWidth', 4)); c._term(); return;
TESTAF
Press the button to change appearance of all the text entry controls
Copyright 2004 Richard A. DeVenezia This page was last updated 23 March 2004.