Transcription of 022-2009: Is This Macro Parameter Blank? - SAS …
1 SAS Global Forum 2009 Applications Development Paper 022-2009. IS this Macro Parameter BLANK? Chang Y. Chung, Princeton University, Princeton, NJ. John King, Ouachita Clinical Data Services, Mount Ida, AR. ABSTRACT. The first thing most macros do is checking input parameters . Still, many Macro users are unsure when it comes to implementing the Parameter checks. this is the case even with the most elementary form, namely the check of the existence of a Parameter value, or the Is-Blank check. We review and compare various ways to implement it. We then recommend one that performs well given various input Parameter values, packaged in a function-style Macro %ISBLANK(), which returns 1 when the Parameter value is blank, and 0 otherwise.
2 INTRODUCTION. Suppose that we are writing a Macro that does something given a Parameter . Implementing the Macro , we should check if the Parameter is blank or not. How do you do this ? A simple way may be as below: % Macro test(param);. %if ¶m eq %then %do;. %put error: param is blank.;. %return;. %end;. %put note: param is OK.;. %mend test;. The test works. For example, it works for these cases: %test(). /* on log error: param is blank. */. %test(abc). /* on log note: param is OK. */. But it does not work all the time. An innocent-looking Parameter value can cause an unexpected error: %test(or). /* on log ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required.
3 The condition was: ¶m eq ERROR: The Macro TEST will stop executing. */. There must be a better way. We reviewed many macros and, to our surprise, there does not seem to be a standard. As with Scott (2008), we also find many different implementations. Even after discarding the obviously incorrect ones, we end up with eight. In this paper, we introduce, compare, and test them, in the hope that we may recommend one that is suitable under general circumstances. 1. SAS Global Forum 2009 Applications Development ASSUMPTIONS. Different macros check parameters differently because they have different expectations about the input values.
4 Macro documentation is often not explicit enough on the assumptions about the input Parameter and its value. Here are a couple of our assumptions about the input Parameter : (1) Responsibility of Macro author starts only after a successful Macro invocation. In other words, a Macro writer cannot be responsible when the Macro invocation itself fails. this can happen in many ways: Users may supply an unexpected number of parameters ; Macro invocation may resolve to un-quoted special characters; Macro or Parameter names are spelled incorrectly. Here are some of the examples of such failures: %tast(,) /* 1 */. %test(chang's favorite) /* 2 */.
5 %let var = (;. %test(&var) /* 3 */. In the 1 above, the Macro name is misspelled; SAS will not be able to find the Macro . Or worse, it will invoke a wrong one, if it happens that such a Macro exists. It also passes two blank parameters to the Macro , while the Macro may be expecting only one. In 2, the apostrophe signals the beginning of a single-quoted string which is not terminated; this will wreak a major havoc on the current session. The error in 3 is more subtle but is as deadly as 2; The Macro invocation looks all right at the first glance but the Macro variable VAR is resolved to an unmatched parenthesis. this kind of failures is difficult to prevent and the Macro author has little means to prevent them.)
6 The Macro processor, in fact, constructs the complete Macro invocation even before the Macro starts to execute. (2) The Parameter value may or may not be Macro quoted before it is passed into the Macro . this complicates a bit what we mean by the Parameter being blank. Here we assume the following: a. Nothing(or null ) is a blank b. One or more space characters (BYTE(32) in ASCII collating sequence) are blank. We also assume that: c. An input Parameter value contains only the printable characters (BYTE(32) through BYTE(255). in ASCII collating sequence) and optionally the Macro quotation delta characters These assumptions imply that all the Macro calls below result in the PARAM being blank: %test() /* nothing */.
7 %test(%str( )) /* a Macro quoted space char */. %test(param=) /* nothing again */. %let var=;. %test(%superq(var)) /* nothing quoted by %SUPERQ() */. On the other hand, the assumption c above makes our Macro 's behavior in the following situation un- defined, because it involves unprintable characters in the Parameter values: data _null_;. length value $1;. name = "LF";. value = byte(10); /* assuming an ascii machine */. 2. SAS Global Forum 2009 Applications Development call symput(name, value);. run;. %test(&LF). CONTENDERS. After reviewing many existing macros, we choose following eight implementations of the Is-the- Parameter -Blank check.
8 In no particular order, they are: %if ¶m eq %then .. /* C1 */. %if %bquote(¶m)= %then .. /* C2 */. %if %nrbquote(¶m)= %then .. /* C3 */. %if %superq(param)= %then .. /* C4 */. %if "¶m" = "" %then .. /* C5 */. %if %length(¶m) = 0 %then .. /* C6 */. %if %length(%qleft(%qtrim(¶m))) = 0 %then .. /* C7 */. %if %sysevalf(%superq(param)=,boolean) %then .. /* C8 */. C1 is the basic testing with no Macro quoting at all. C2 through C4 use a different Macro quoting function in turn. We omit %QUOTE() and %NRQUOTE() functions because their usage is discouraged except for the unique quoting needs and for the backward compatibility C5 double-quotes the Parameter value.
9 C6 and C7. are based on the %LENGTH function. C7 is quite elaborate and found in the %DATATYP Macro included in the SAS autocall library. C8 is similar to C4 but evaluates the logical expression explicitly within the %SYSEVALF(). function. There are other variations of the above, and we will come back to some of them when we discuss the test results. (CON)TEST SETUP. Our test is simple. We write a test Macro with above contenders. Call the macros with various Parameter values. Then see what happens. We pay close attention to: If the test Macro errors or not; If the test Macro takes exceptionally long time to run; If the test result is indeed correct.
10 Some input values may hang the SAS session or cause harmful side effects. In order to prevent unwanted interaction, we run each test in its own separate SAS. session. The input parameters are chosen carefully and are to reflect various extreme cases. They include: nothing, quoted blanks , letters, numbers, special characters, logical operators, very long character strings, and a very long string of quoted blanks , and a large number. The actual test codes are automatically generated, submitted, and the log analyzed. The source code is presented in the appendix. All the tests are run using SAS for Windows Release with SP4 (TS1M3) on Microsoft Windows Vista Ultimate (Version , Service Pack 1).