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 (February 2006, week 2)Back to main SAS-L pageJoin or leave SAS-L (or change settings)ReplyPost a new messageSearchProportional fontNon-proportional font
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
Comments: To: toby dunn <tobydunn@hotmail.com>, ian.whitlock@comcast.net
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


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