views:

127

answers:

2

In other programming languages such as C++, include guards are used to prevent multiple inclusions of the same code.

Like this in C++:

#ifndef FOO_INCLUDED
#define FOO_INCLUDED
....
#endif

Does it make sense to build inclusion guards into your SAS macro function definitions? And how should it be done?

+3  A: 

There is %SYMEXIST(macro-var-name) macro function to see if the macro-var exists, but you cannot write %IF in the open, so you have to enclose your %IF statement inside some other macro. You may end up writing a macro just to wrap your code in a source file like below. This is not pretty, but you can probably get by with this, if the guard is needed.

%macro wrapper;
  %if %symexist(foo_defined) %then %return;
  %macro foo;
    %global foo_defined;
    %let foo_defined = 1;
    %put i am foo; 
  %mend foo;
%mend  wrapper;

%*-- tests --*;
options mcompilenote=all;
%symdel foo_defined;

%*-- first time it will define %foo --*;
%wrapper
%foo
/* on log
NOTE: The macro FOO completed compilation without errors.
      6 instructions 108 bytes.
i am foo
*/

%*-- second time it will not --*;
%wrapper
%foo
/* on log
(no notes on macro compilation)
i am foo
*/

Upon invocation, SAS makes available a bunch of catalogs, files, and directories for accessing (compiled/not compiled) macros. This makes it cumbersome, but not impossible, to directly find out a macro is already available to this session or not, given the macro's name. Read about the (gory) details in this paper: http://support.sas.com/resources/papers/proceedings09/076-2009.pdf

Chang Chung
Thanks. This is pretty much the approach I was aiming for.
Martin Bøgelund
+2  A: 

You could use the NOMREPLACE option to prevent any macro to be redefined.

In my opinion, reusing macro names and macro variable names (and even data set names) is evil. If you define things just once, you can be relatively sure you can resubmit any part of the code and expect to get the same results as originally. I also prefer keeping macro definitions separate from the code they're called from.

Ville Koskinen
This option does *not* prevent you from re-defining the macros that reside in your SASAUTOS directories.. unless you call the macros first, that is. Because once it is called, then the macro is compiled into the macro catalog in the work library, and only after that, this option will block re-defining. The details of which macros are available for calling given a session is indeed gory.
Chang Chung