|
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>
|