Date: Fri, 10 Feb 2006 10:15:47 -0500
Reply-To: Ed Heaton <EdHeaton@WESTAT.COM>
Sender: "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From: Ed Heaton <EdHeaton@WESTAT.COM>
Subject: Re: Identifying macro language elements
Content-Type: text/plain; charset="us-ascii"
Golly, I must have been asleep this morning.
I thought I saw the final output from
11 %put ***&Ian*** ;
as
***10***
Hence my comment about...
Notice how the 10 in &IAN mysteriously became left-aligned!
But my glasses obviously failed me. The macro variable %IAN was empty.
And rightly so, because the %LEFT() macro as defined returns no value.
Sorry for the confusion.
Ed
Edward Heaton, SAS Senior Systems Analyst,
Westat (An Employee-Owned Research Corporation),
1600 Research Boulevard, RW-4541, Rockville, MD 20850-3195
Voice: (301) 610-4818 Fax: (301) 294-3879
mailto:EdHeaton@Westat.com http://www.Westat.com
-----Original Message-----
From: toby dunn [mailto:tobydunn@hotmail.com]
Sent: Friday, February 10, 2006 10:05 AM
To: Ed Heaton; SAS-L@LISTSERV.UGA.EDU
Subject: Re: Identifying macro language elements
Ed,
I am not Ian but if you dont like what I say you can always just hit the
delete button.....
This has less to do with macro name collision then how call symput and a
%let create a macro variable.
Data _null_ ;
x = 10 ;
Call symput( "Ian" , put( x , 8. ) ) ;
Run ;
Since call symput will preserve leading for character variables and
leading
blanks for numerics. Its no suprise that the output in the log looks
like:
5 %put ***&Ian*** ;
*** 10***
Ahh yes indeedy the leading blanks are there because you explicity put
the
value 10 in a number.
They go away if you try:
Data _null_ ;
x = 10 ;
Call symput( "Ian" , left( put( x , 8. ) ) ) ;
Run ;
But that would leave you with trailing blanks then so in V9 I like:
Data _null_ ;
x = 10 ;
Call symput( "Ian" , strip( put( x , 8. ) ) ) ;
Run ;
Now when you pass that value along to a parameter the value even if it
has
leading and trailing blanks will get stripped off, why well thats how
the
macro world works.
%macro left(who) ;
%put &who left ;
%mend left ;
%left(Ian)
Produces 'Ian left.' Makes since to me since you are passing just text
to
the parameter who and doing nothing more than putting that text plus
some
more text to the log.
%let created macro vars have that same effect. When you write text in
them
there is no leading and trailing blanks. Also you get this effect when
you
have a resolve a macro variable as the value of a macro variable in a
%let
statement.
So :
%let Ian = %left(&Ian) ;
This is a bad test simply because the %macro left will assign nothing to
the
macro var Ian.
But even if it did you would see no leading nor trailing blanks.
Data _null_ ;
x = 10 ;
Call symput( "Ian1" , put( x , 8. )) ;
Call symput( "Ian2" , strip(put( x , 8. )) ) ;
Run ;
%put Ian1 Macro Var With Leading blanks ***&Ian1*** ;
%put Ian2 Macro Var WithOut Leading blanks ***&Ian2*** ;
%macro left(who) ;
&&&who ;
%mend left ;
%put Proof that the resolved value of macro left will preserve leading
blanks ;
%put when written this way ;
%put >>>%left(Ian1) ;
%put >>>%left(Ian2) ;
%let Ian1 = %left(Ian1) ;
%let Ian2 = %left(Ian2) ;
%put New Ian1 Macro Var With Out Leading blanks ***&Ian1*** ; %put New
Ian2 Macro Var With Out Leading blanks ***&Ian2*** ;
/*** But looks what happens when you write the macro left this way ***/
%macro left(who) ;
&who ;
%mend left ;
%put >>>%left(&Ian1) ;
%put >>>%left(&Ian2) ;
Toby Dunn
From: Ed Heaton <EdHeaton@WESTAT.COM>
Reply-To: Ed Heaton <EdHeaton@WESTAT.COM>
To: SAS-L@LISTSERV.UGA.EDU
Subject: Re: Identifying macro language elements
Date: Fri, 10 Feb 2006 07:55:09 -0500
Ian, I'm not sure what to make of this.
1 Data _null_ ;
2 x = 10 ;
3 Call symPut( "Ian" , put( x , 8. ) ) ;
4 Run ;
NOTE: DATA statement used (Total process time):
real time 0.37 seconds
cpu time 0.07 seconds
5 %put ***&Ian*** ;
*** 10***
6 %macro left(who) ;
7 %put &who left. ;
8 %mEnd left ;
9 %left(Ian)
Ian left.
10 %let Ian = %left(&Ian) ;
10 left.
11 %put ***&Ian*** ;
******
Notice how the 10 in &IAN mysteriously became left-aligned!
Was the call to my %LEFT() macro or to the SAS %LEFT() macro function --
or both?
Ed
Edward Heaton, SAS Senior Systems Analyst,
Westat (An Employee-Owned Research Corporation),
1600 Research Boulevard, RW-4541, Rockville, MD 20850-3195
Voice: (301) 610-4818 Fax: (301) 294-3879
mailto:EdHeaton@Westat.com http://www.Westat.com
-----Original Message-----
From: owner-sas-l@listserv.uga.edu [mailto:owner-sas-l@listserv.uga.edu]
On Behalf Of iw1junk@comcast.net
Sent: Thursday, February 09, 2006 8:41 PM
To: SAS(r) Discussion
Cc: Frank DiIorio
Subject: Re: Identifying macro language elements
Frank,
Maybe there are other nightmares.
How do you handle a call to %LEFT? Is it user written or supplied by
SI? How do you know?
What about %&MACVAR? or worse
%macro q ( p1= , mac = /* macro invocation wo %-sign */ ) ;
....
%&mac
....
%mend q ;
%q(p1=abc, mac=M1(a=3) )
%q(p1=def, mac=M2 )
or
proc sql noprint ;
select trim(mac)||"("||parms||")"
into :calls separated by ' '
from specs
;
&calls
quit ;
I have used both of the above techniques in some form and found them
handy when the flexibility was required. Which reminds me, is
%nrstr(%abc)
treated as a call to ABC? Or how about
call execute ( '%nrstr(%abc) ) ;
which does legitimately call ABC?
Or as more of a monster here is some code from a student in a macro
class,
%macro a ;
...
%macro b ;
....
%mend b ;
%b
....
%macro b ;
.... different code
%mend b ;
%b
....
%mend a ;
Does the macro A call B once or twice? And what about statement style
macros?
Ian Whitlock
===================
Date: Wed, 8 Feb 2006 18:18:42 -0800
Reply-To: frank_diiorio@YAHOO.COM
Sender: "SAS(r) Discussion"
From: Frank DiIorio <frank_diiorio@YAHOO.COM>
Organization: http://groups.google.com
Subject: Identifying macro language elements
Comments: To: sas-l
Content-Type: text/plain; charset="iso-8859-1"
I have a program that reads macros in one or more user-specified
directories, looks for calls to user-written macros, and constructs a
cross-reference dataset. The program then creates two reports: "macro X
uses which macros" and "macro Y is used by which macros" It works fine,
but was written for V9.1 and thus failed to catch references to items
new in V9.1.3 (for example, it saw a reference to %symexist and thought
it was a user-written macro). I have a format that maps %IF, %THEN,
%SYMDEL, etc. to 'no', which prevents that token from being output. I
added %symexist, %symlocal, et al. to the format definition, but am
wondering if there's another way to do this.
Rephrased: how can I determine if a variable holds the name of a macro
language statement, function, etc. I'm OK with the user-format
approach, but if there's a less cumbersome way to do this, I'd like to
hear about it. Thanks. Frank DiIorio