LISTSERV at the University of Georgia
Menubar Imagemap
Home Browse Manage Request Manuals Register
Previous messageNext messagePrevious in topicNext in topicPrevious by same authorNext by same authorPrevious page (April 2002, week 5)Back to main SAS-L pageJoin or leave SAS-L (or change settings)ReplyPost a new messageSearchProportional fontNon-proportional font
Date:         Tue, 30 Apr 2002 10:22:56 -0400
Reply-To:     Ian Whitlock <WHITLOI1@WESTAT.COM>
Sender:       "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From:         Ian Whitlock <WHITLOI1@WESTAT.COM>
Subject:      Re: user-defined readonly macro variable
Comments: To: "Richard A. DeVenezia" <radevenz@IX.NETCOM.COM>
Comments: cc: "donaldjhenderson@HOTMAIL.COM" <donaldjhenderson@HOTMAIL.COM>
Content-Type: text/plain; charset="iso-8859-1"

Richard,

You have some interesting ideas.

I like "%local : ;" as a cheap way to change the default behavior for those "glazed eyes" that Ron mentions, although I suspect this already causes glazing. On the other hand I have the habit of using %LOCAL to declare variables at the top of a macro so I would probably not want to revert to essentially an undeclared form of variables.

%local _all_ ;

might be more SAS like than using the colon.

I like the %FREEZE and %UNFREEZE as an implementation of Ron's constants. I assume you would have a "%FREEZE : ;" to mean freeze all *existing* variables. I would then code

%freeze : ; %yourmacro ( ... ) %unfreeze : ;

whenever dealing with someone else's macros unless they are called to explicitly change one of my variables. This doesn't solve the information hiding problem, but it does solve changing information problem with flexibility. Would the %UNFREEZE command have to be in the same environment as the issuing %FREEZE? (I am beginning to feel paranoiac here.)

Your

%let mvar.attribute = ... ;

looks good if planned into a new macro language. I would not vote for another option, but rather a compatible extension. Today one cannot write your %LET statement so compatibility is not a problem. Again the problem is - who can change the attribute?

On the other hand, I might rather have

%let macname.mvar = ... ;

to explicitly change or create a value in an external macro environment. Although this suggestion looks like object orientation it probably would make a really object oriented macro language difficult to implement. (My previous suggestion along these lines is to extend the %LOCAL statement. For example,

%local (macname) mvar ;

Here the system would search outward for the first environment with the name macname and either change or create the variable there. This has the advantage that it should be easy to implement while an object oriented macro language would require a serious commitment on the part of the SAS Institute, albeit one I would encourage them to consider. So I am schizophrenic, I don't want called macros messing with my variables unless I call them to explicitly change or create variables for my macro.)

Your macro %LOCALALL while technically interesting would not serve my purposes. First it requires user implementation and that is precisely what I see as must be avoided. The current %LOCAL is sufficient when used properly. Second it goes too far (possibly more important). When writing %Y, I do not want all the variables in any external environments cluttering up my local symbol table.

On another note, Don Henderson [donaldjhenderson@HOTMAIL.COM], is correct when he says that global variables are important. They should not be done away with, but used correctly. In order to insure correctness I would still want to explore all ways of avoiding them, before using them.

Please, more ideas on where macro should go or not go.

IanWhitlock@westat.com

-----Original Message----- From: Richard A. DeVenezia [mailto:radevenz@IX.NETCOM.COM] Sent: Monday, April 29, 2002 11:27 PM To: SAS-L@LISTSERV.UGA.EDU Subject: Re: user-defined readonly macro variable

"Fehd, Ronald J." <rjf2@CDC.GOV> wrote in message news:9D17D648E4EBD311AD45009027D0DF9302EAEDDB@MCDC-ATL-64... > At SUGI27, I heard two speakers recommend > against using %global macro variables > because of the possibility of later programs overwriting them. > snip > * set in options: > options SetMVarReadOnly = yes; > %LET MVAR = VALUE; > options SetMVarReadOnly = no; snip > Ron Fehd the macro maven CDC Atlanta GA USA RJF2@cdc.gov > > remember perspective: the error is not always where it seems to occur! -- > RJF2

I would prefer something like

%freeze and %unfreeze

Normal scoping rules would apply. In essence, behind the scenes, a new metadata attribute 'Updateable' would be part of each macro variable.

But better yet would be some form of objectification of macro

%let mvar.mvarAttribute = ...

However, I can't think of any syntax that would not interfere or misinterpret prior macro 'art'. (This would then beg for yasso, yet another sas system option, that would be used to control how the macro system interprets certain macro statements)

A quick aside in response to Ian's thoughts in another thread, on a macro being unable to alter anything in an encompassing scope, one could hope for a simple

%local : ;

In the meantime I offer up the macro "localAll" that can be used to localize all macro variables that exist in an encompassing scope, thus protecting outer scoped macro variables from change.

%*-------- submittable ----; options nomprint nomtrace nosymbolgen nosource;

%macro localAll;

%local dsid rc mvar;

%let dsid = %sysfunc (open (SASHELP.VMACRO)); %if (&dsid) %then %do; %let rc = %sysfunc (fetch (&dsid)); %do %while (&rc = 0);

%let mvar = &mvar %sysfunc (getvarc(&dsid,2));

%let rc = %sysfunc (fetch (&dsid)); %end; %let rc = %sysfunc (close(&dsid)); %end;

&mvar %mend localAll;

%macro x; %local allmvar; %let allmvar = %localAll; %local &allmvar;

%let x=1; %put x pre y: x=&x; %y; %put x post y: x=&x; %put; %mend x;

%macro y; %let x=2; %let y=1; %put y: x=&x y=&y, x post y will change; %mend y;

%x

%let x=Gx; %let y=Gy; %let z=Gz;

%macro y; %local allmvar; %let allmvar = %localAll; %local &allmvar;

%let y=1; %put y2: x=&x y=&y z=&z, x post y will NOT change; %mend;

%x

%put x=&x y=&y z=&z; %*-------- submittable ----;

(I needed three statements to localize because a simple %local %localAll; did not seem to work)

-- Richard A. DeVenezia


Back to: Top of message | Previous page | Main SAS-L page