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 (July 2004, week 1)Back to main SAS-L pageJoin or leave SAS-L (or change settings)ReplyPost a new messageSearchProportional fontNon-proportional font
Date:   Fri, 2 Jul 2004 10:32:24 -0500
Reply-To:   "Dunn, Toby" <tdunn@TEA.STATE.TX.US>
Sender:   "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From:   "Dunn, Toby" <tdunn@TEA.STATE.TX.US>
Subject:   Re: "Missing" macro values, was: Re: Macro Variable Problem
Content-Type:   text/plain; charset="us-ascii"

I should have said,

The following should explain part of the problem. And actually explains why

%let a = %str( ); %let b = %str( );

%put %eval(&a = &b); will return as true (1).

And why

%put %eval(%length(&a) = %length(&b)); will return a false (0);

Toby Dunn

-----Original Message----- From: SAS(r) Discussion [mailto:SAS-L@LISTSERV.UGA.EDU] On Behalf Of Dunn, Toby Sent: Friday, July 02, 2004 10:29 AM To: SAS-L@LISTSERV.UGA.EDU Subject: Re: "Missing" macro values, was: Re: Macro Variable Problem

Jim, The following should explain part of the problem. And actually explains why %let a = %str( ); %let b = %str( );

%put %eval(&a = &b); will return as true (1).

How Macro Quoting Works

When the macro processor masks a text string, it masks special characters and mnemonics within the coding scheme, and prefixes and suffixes the string with a hexadecimal character, called a delta character. The prefix character marks the beginning of the string and also indicates what type of macro quoting is to be applied to the string. The suffix character marks the end of the string. The prefix and suffix characters preserve any leading and trailing blanks contained by the string. The hexadecimal characters used to mask special characters and mnemonics and those used for the prefix and suffix characters may vary and are not portable.

There are more hexadecimal combinations possible in each byte than are needed to represent the symbols on a keyboard. Therefore, when a macro quoting function recognizes an item to be masked, the macro processor uses a previously unused hexadecimal combination for the prefix and suffix characters.

Macro functions, such as %EVAL and %SUBSTR, ignore the prefix and suffix characters. Therefore, the prefix and suffix characters do not affect comparisons.

When the macro processor is finished with a macro quoted text string, it removes the macro quoting-coded substitute characters and replaces them with the original characters. The unmasked characters are passed on to the rest of the system. Sometimes you might see a message about this unmasking, as in the following example:

/* Turn on SYMBOLGEN so you can see the messages about unquoting. */ options symbolgen;

/* Assign a value to EXAMPLE that contains several special */ /* characters and a mnemonic. */ %let example = %nrbquote( 1 + 1 = 3 Today's Test and More );

%put *&example*;

When this program is submitted, the following appears in the SAS log:

SYMBOLGEN: Macro variable EXAMPLE resolves to 1 + 1 = 3 Today's Test and More SYMBOLGEN: Some characters in the above value which were subject to macro quoting have been unquoted for printing. * 1 + 1 = 3 Today's Test and More *

As you can see, the leading and trailing blanks and special characters were retained in the variable's value. While the macro processor was working with the string, the string actually contained coded characters that were substituted for the "real" characters. The substitute characters included coded characters to represent the start and end of the string. This preserved the leading and trailing blanks. Characters were also substituted for the special characters + , = , and ' , and the mnemonic AND . When the macro finished processing and the characters were passed to the rest of SAS, the coding was removed and the real characters were replaced.

Should explain the quoting and unquoting problem in the code you gave us with symbolgen turned on.

-----Original Message----- From: Groeneveld, Jim [mailto:jim.groeneveld@vitatron.com] Sent: Friday, July 02, 2004 9:37 AM To: Dunn, Toby Cc: SAS-L (E-mail) Subject: "Missing" macro values, was: Re: Macro Variable Problem

Hi Toby and other involved friends,

A SAS birdie wrote me (for which I'm very grateful):

======================================================================= ======= I consider this a documentation deficiency at most.

The statement: "The item leaves the word scanner and is passed to the DATA step compiler, SAS procedures, or other parts of the SAS System, when the item is part of generated SAS statements."

should be changed to: "The item leaves the word scanner and is passed to the DATA step compiler, SAS procedures, SAS Macro Facility, or other parts of the SAS System."

The SAS Macro Facility uses the word scanner when parsing macro code, including expressions. ======================================================================= =======

But in my opinion this does not describe or explain why only quoted (leading and trailing) spaces seem to be unquoted in logical comparisons, that is, why those quotes are not regarded part of a value anymore. With all other characters than spaces everything works as expected and the docs look all right to me.

I'm curious how this behaviour emerges in SAS 9.1, I don't have it yet; or 6.12, I don't have that anymore. Anyway, once you know you know and can take it into account. And you always test your draft programs with all kinds of testdata beforehand, knowing what to expect, don't you?

Regards - Jim. -- . . . . . . . . . . . . . . . .

Jim Groeneveld, MSc. Biostatistician Science Team Vitatron B.V. Meander 1051 6825 MJ Arnhem Tel: +31/0 26 376 7365 Fax: +31/0 26 376 7305 Jim.Groeneveld@Vitatron.com www.vitatron.com

Showing statistically significant differences between football teams, generally all sporters, requires larger samples than usually applied.

[common disclaimer]

-----Original Message----- From: Dunn, Toby [mailto:tdunn@tea.state.tx.us] Sent: Friday, July 02, 2004 15:15 To: Groeneveld, Jim Subject: RE: Re: Macro Variable Problem

Jim,

I may still need to reread Ian's comments and yours again, but " So I think the quoted spaces are not so much unquoted automatically in a comparison evaluation, but in a resulting logical expression leading or trailing quoted spaces (from a value) just are not recognized as such anymore. Could this be considered a bug or a feature?"

Is reminiscent of one of Ian's SAS talks about the %eval and a paper that I have started and Ian had started to help me with over the %eval. It seems to be more a %eval problem than anything. There are still instances where even the mighty Ian hasn't figured out why the %eval strips away the quotes.

Toby

-----Original Message----- From: SAS(r) Discussion [mailto:SAS-L@LISTSERV.UGA.EDU] On Behalf Of Groeneveld, Jim Sent: Friday, July 02, 2004 6:07 AM To: SAS-L@LISTSERV.UGA.EDU Subject: Re: Macro Variable Problem

Thank you Ian,

Well-considered and you are quite right of course. Much more could be said about it, like in which cases the quoted spaces become unquoted automatically, in which case the distinction gets lost. The logical comparison seemingly is one such case; but it appears not to be such a case, see below.

Actually, your comparison %put %eval(&b1=&b2) ; /* true */ resolves to %PUT Nothing comparison: %eval(=) ; /* true */

The SAS online docs indicate some general rules for automatic unquoting:

======================================================================= = Usually, after an item has been masked by a macro quoting function, it retains its special status until one of the following occurs:

You enclose the item with the %UNQUOTE function (described in Chapter 13).

The item leaves the word scanner and is passed to the DATA step compiler, SAS procedures, or other parts of the SAS System, when the item is part of generated SAS statements.

The item is returned as an unquoted result by the %SCAN, %SUBSTR, or %UPCASE function. (To retain a value's masked status during one of these operations, use the %QSCAN, %QSUBSTR, or %QUPCASE function. See Other Functions That Perform Macro Quoting for more details.) ======================================================================= =

but the logical comparison (evaluation) is not mentioned at all! However, see my test code most below. This kind of seeming automatic unquote (of spaces) can be illustrated further by:

======================================================================= = 31 %LET Text0 = Text; 32 %LET Text1 = &b1.Text&b1; 33 %put contents comparison: %eval(&Text0 = &Text1) ; /* true */ contents comparison: 1 34 %put length comparison: %eval(%length(&Text0)=%length(&Text1)) ; /* false */ length comparison: 0 ======================================================================= =

and by:

======================================================================= = 36 %LET Text0 = %STR(Text); 37 %LET Text1 = %STR(&b1.Text&b1); 38 %LET Text01 = &b1%STR(Text)&b1; 39 %put contents comparison: %eval(&Text0 = &Text1) ; /* true */ contents comparison: 1 40 %put length comparison: %eval(%length(&Text0)=%length(&Text1)) ; /* false */ length comparison: 0 41 %put contents comparison: %eval(&Text0 = &Text01) ; /* true */ contents comparison: 1 42 %put length comparison: %eval(%length(&Text0)=%length(&Text01)) ; /* false */ length comparison: 0 43 %put contents comparison: %eval(&Text1 = &Text01) ; /* true */ contents comparison: 1 44 %put length comparison: %eval(%length(&Text1)=%length(&Text01)) ; /* true */ length comparison: 1 ======================================================================= =

Yet the automatic unquote in the above case may seem present, while actually it isn't. Study the following example from which it is clear that there is no automatic unquote:

======================================================================= = 46 %LET Text = Unquoted; 47 %LET Qtext = %NRSTR(&Text); 48 49 %PUT Text=&Text; Text=Unquoted 50 %PUT Qtext=&Qtext; Qtext=&Text 51 OPTIONS SYMBOLGEN; 52 %put contents comparison: %eval(&Qtext = &Text) ; /* false */ SYMBOLGEN: Macro variable QTEXT resolves to &Text SYMBOLGEN: Some characters in the above value which were subject to macro quoting have been unquoted for printing. SYMBOLGEN: Macro variable TEXT resolves to Unquoted contents comparison: 0 ======================================================================= =

So I think the quoted spaces are not so much unquoted automatically in a comparison evaluation, but in a resulting logical expression leading or trailing quoted spaces (from a value) just are not recognized as such anymore. Could this be considered a bug or a feature?

Regards - Jim. -- . . . . . . . . . . . . . . . .

Jim Groeneveld, MSc. Biostatistician Science Team Vitatron B.V. Meander 1051 6825 MJ Arnhem Tel: +31/0 26 376 7365 Fax: +31/0 26 376 7305 Jim.Groeneveld@Vitatron.com www.vitatron.com

Showing statistically significant differences between football teams, generally all sporters, requires larger samples than usually applied.

[common disclaimer]

-----Original Message----- From: Ian Whitlock [mailto:iw1junk@COMCAST.NET] Sent: Friday, July 02, 2004 02:27 To: SAS-L@LISTSERV.UGA.EDU Subject: Re: Macro Variable Problem

Don, Just to add to the confusion, I note that blanks and the null value are considered equal in the macro language, but have different lengths. Sometimes this is handy becasue SAS does not make a distinction in the number of blanks. Sometimes it is annoying becasue equality doesn't imply having the same value. Here is the log. 1 %let b0 = %str() ; /* no blank */ 2 %let b1 = %str( ) ; /* one blank */ 3 %let b2 = %str( ) ; /* two blanks */ 4 5 %put %eval(&b1=&b2) ; /* true */ 1 6 %put %eval(%length(&b1)=%length(&b2)) ; /* false */ 0 7 8 %put %eval(&b0=&b2) ; /* true */ 1 9 %put %eval(%length(&b0)=%length(&b2)) ; /* false */ 0

-- Ian_Whitlock@comcast.net

Date: Wed, 30 Jun 2004 11:19:00 -0400 Reply-To: Don Henderson <donaldjhenderson@HOTMAIL.COM> From: Don Henderson <donaldjhenderson@HOTMAIL.COM> Subject: Re: Macro Variable Problem Content-Type: text/plain; charset="iso-8859-1"

I must respectfully disagree with some of what is posted here.

The generic concept of missing does apply to macro. However, viewing it akin to a SAS data step variable being missing is not an appropriate way to think of it.

As I am sure many of you all know, macro is a text string manipulation language. It's primary purpose is to generate SAS code.

A macro variable can have a value, including a blank space. It can also have a null value, e.g.,

%let mvar = ;

A null value is also what is assigned, for example, when a %local or %global statement is used to "create" a macro variable.

Using blank and null interchangably when referring to macro variables that have "no value" can cause one to miss a number of nuances of the macro language. I say this as someone who has used macro far longer than he cares to admit and who also used to teach the SAS macro language course back in the early 80s.

Respectfully, -don h

< snip previous messages>


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