| Date: | Thu, 10 Jun 2004 14:42:29 +0000 |
| Reply-To: | iw1junk@COMCAST.NET |
| Sender: | "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU> |
| From: | Ian Whitlock <iw1junk@COMCAST.NET> |
| Subject: | Re: Can a macro variable be unassigned in version 6.12 |
|
Subject: Can a macro variable be unassigned in version 6.12
Summary: A macro design issue
Respondent: Ian_Whitlock@comcast.net
Mark S Goldberg <marks@UNFORGETTABLE.COM> writes in part:
I'm looking to validate a series of macros and, among other
things, to test how they respond to missing expected macro
variable assignments. The easiest way to do this would be to
leave the whole infrastrucure of the system in place and just
have individual programs unassign a particular variable and
then call the macro.
This has always struck me as a funny argument. I can see how a
macro variable can be mistakenly empty or have the wrong value,
but how can the variable not be created in a well designed system?
From a macro's point of view there are four kinds of macro variables.
1) parameter - must exist
2) locally defined variable - see below
3) globally defined variable - should be declared global
at top of macro and hence should exist as verified by
casual look at the code
4) variable local to calling macro - see below
Typically local variables should be declared at the top of the macro, so like global variables, one should be able to verify
existence by code inspection. One exception might be in creating
a local array of variables, for example:
%do i = 1 %to &n ;
%local a&i ;
/* code to assign A&I */
%end ;
Here the %local statement may inherently be buried far down in the macro. Another might be a macro variable that should exist
only under certain conditions. In any case one can locate the first usage or even each usage an place a %LOCAL statement just
before the usage to guarantee existence of the variable since
multiple local declarations do not affect the value of the variable. Will the extra declarations hurt performance? Try
%macro q ( n = 10 ) ;
%local i x begtm endtm ;
%let x = 3 ;
%let begtm = %sysfunc(time()) ;
%do i = 1 %to &n ;
%local x ;
%end ;
%let endtm = %sysfunc(time()) ;
%put time=%sysevalf(&endtm - &begtm) ;
%put x=>>&x<< ;
%mend q ;
At 10,000 extra declarations I saw a time difference a little over .031 seconds and at a million extra declarations the time added was just 4.125 seconds.
Only condition 4) seems to present a real problem, because here
responsibility for declaring the variable is inherently outside
the macro of interest. Here the only thing I can see is to
explicitly test for the existence of the variable. Macros to
test for existence are in the macro manuals, probably at the SAS
web site, and in the archives of SAS-L.
What is really needed is language support for error handling, but
for the last 22 years this responsibility has been left entirely
to the user's code.
Ian
--
Ian_Whitlock@comcast.net
|