BookmarkSubscribeRSS Feed
deleted_user
Not applicable
Is it possible to remove a macro definition from memory?

We can remove a filenames and libnames with "clear" commands.
Is there something to remove/deregister a macro and/or macro variables?
11 REPLIES 11
Cynthia_sas
SAS Super FREQ
Hi:
%SYMDEL deletes the specified variables(s) from the macro global symbol table. As for the Macro definitions themselves...you might read the documentation on Storing and Reusing Macros or contact Tech Support for help. I can't remember the intricacies of stored compiled macros versus Autocall versus session-compiled macro maintenance.

cynthia
deleted_user
Not applicable
Autocall macros are files of SAS code with a name that corresponds to the macro that is called. Renaming, moving or deleting the files will remove the macro from any future sessions. Note however that if the autocall macro is run in the current session, it will now reside as a compiled object in a catalog called SASWORK.SASMACR, and you will either need to restart your session, delete the entry from the catalog or recompile an empty macro with the same name to deactivate the macro from the session.

Stored compiled macros are held in a catalog, which must be write protected if it is shared. Otherwise, you cannot have concurrent access since the first SAS session to reference the catalog will lock it from update by other users. However, where your SC catalog is solely yours, you can delete entries from it using the Catalog procedure.

The addition of %SymDel to SAS9 was a very welcome enhancement.

Kind regards

David
Peter_C
Rhodochrosite | Level 12
why would you need to remove a macro?

PeterC
deleted_user
Not applicable
It's not so much a need as a desire.

Due to SAS's legacy, it has one serious weakness = flat name spaces, mostly.
In the MetaData Server, there is a flat name space for Library names.
In an running SAS session, there is a single flat name space for macros.
If few macros are used, this is not a problem.
For many macros, across many users and many processes, there is an increasing chance for a naming collision.
For me, it's worse because I am abscent-minded (forgetful) and have some standard naming conventions I use for convenience -- play, dummy, test, trial, etc.

So, it would be nice if after I have used a macro, and I know that I am not going to need it anymore, that I could remove it, just as I can remove a FILENAME or LIBNAME with "clear".


From a different perspective, I would like to see a complete rewrite and restructuring of certain aspects of SAS, from the ground up, to be more object oriented. The down side of that would be that the new SAS would probably not be able to run most of the old SAS code/programs. But, with a careful redesign, a lot more capability could be more easily incorporated. After all, there has been a lot of changes in the computer language world since SAS was first conceived in the early 1970's.
Peter_C
Rhodochrosite | Level 12
I think you are placing responsibility in the wrong place for problems that don't really occur.

A user's SAS programs execute in their private session, so there is less likelihood of names competing while users program independantly. If they are in programming in a team, I think it is a team responsibility to manage such name contention because each member's programs are expected to co-exist. If not, there is no name contention because the code will not execute in the same SAS session.

A SAS program launched by EG will execute in a independent SAS session.

Surely you can define macro source library concatenation so that a user's private macros can exist independantly while they also share team and installation macro libraries. These should all support a scheme like
OPTION SASAUTOS= ( usermac teamMac siteMac) ;

I hope your environment will support such a structure. I think it is more likely to solve your need within our lifetime than SAS chosing to abandon legacy-support.

Of course we are all entitled to our opinions ~ mine are just another $0.02

PeterC
deleted_user
Not applicable
Ok, per my solution for reading a file with pure macro code, I have run into a naming/scoping collision, all within my own code.

Calling macro:

[pre]
%local password user_id;
%let user_id = %getID;
%getPWD(&user_id,password);
%if %length(&password) < 3 %then %do;
%put RP NOTE: effectively no password, "&password" ;
%abort;
%end;

-----------------------------------------------------------

%macro getPWD(user_id,dummy);

...

%* userid password and email_address are set to local explicitly;
%* because the %syscall set command would otherwise create global;
%* macro variables, which is undesirable.;

%local dsid rc user_id password email_address user_name;

...

%if %length(&dummy) > 0 %then %let &dummy = &password ;
%else &password ;

...

%mend;
[/pre]

&dummy resolves to "password" which has been defined to be %local to %getPWD.

I understand the role of a macro and the scoping rules and why the scoping rules are as they are.

But, if SAS were "rewritten" to be more object-oriented-like, then I wouldn't have run into this problem.

The reason I got into this mess in the first place was adapter old code from someone else that used an external file to hold the encoded password, and simply lifted the related code from the examples for PROC PWENCODE (which should have never been a "proc" but a function, in my opinion).

While any new code can use the new form/method of %let password = %getPWD(%getID)); I am not going to go across all the legacy code to change %getPWD(&user_id,password) to the new methodology.

So, now I'm kind of stuck with too many things called "password" and the scoping rules causing a collision that doesn't resolve the way I want it to.

The work around is that I'm not going to be able to use the slick %syscall set(&dsid); method to read the variables from a dataset.' Message was edited by: Chuck
deleted_user
Not applicable
The work around for the naming conflict/collision is as follows:

[pre]
%macro getPWD(user_id,dummy);
...
%local ... varN _&dummy;
...
%let varN = %sysfunc(varnum(&dsid,password));
...
%let _&dummy = %sysfunc(getvarc(&dsid,&varN));
%if %length(&dummy) > 0 %then %let &dummy = &&&&_&dummy ;
%else &&&&_&dummy ;
...
%mend;
[/pre]

in this way, even though the calling macro may use the name "password" and the PSDS may have the column name of "password", I avoid any naming conflicts.

I had thought about using "varC" for the interim local variable, but if for some strange reason someone passed in "varC" through "dummy" then I would have the same problem. So, the more general thing was simply to use "&dummy" and prepend an '_' to the name. To get the macro variable to resolve correctly then requires the use of '&&&&' so that &dummy will be resolved first, and then whatever "_&dummy" is (my dynamic variable name) gets resolved.
darrylovia
Quartz | Level 8
Chuck
You could delete the macro definition from the work catalog where it is stored. See my simple example below.

-Darryl

%macro hello_world;

%put Hello World;

%mend hello_world;

%hello_world;

proc sql;
select *
from DICTIONARY.CATALOGS
where libname='WORK';
quit;

proc catalog catalog=work.sasmac1;
delete hello_world.macro;
quit;


%hello_world;
deleted_user
Not applicable
Cool !

Thanks.

This is not the first time since I've been monitoring/involved with the SAS forums that I've seen mention of DICTIONARY. I'm going to have to check that out, more.
LawrenceHW
Quartz | Level 8
Proc CATALOG (and also DATASETS) are very useful procedures for cleaning up your SAS WORK areas. I use these procedures all my current WORK macros and data sets when I want to start a new program but without starting a new SAS session.

You can use the dictionary tables (or the SASHELP views which are the same thing, just less efficient) to give you the information to delete all user-defined macro variables.
deleted_user
Not applicable
I'm going to be a little picky with your explanation Darryl, because I'm not sure you have completely explained the role of the macro catalog in the work directory.

Unless renamed, the catalog is created automatically by the SAS session, and is called SASMACR. When you execute the code for a macro, either from a program you run, or from a macro that is compiled from the autocall library path, the macro is compiled to a macro entry in the WORK.SASMACR catalog and is subsequently executed from that location.

Deleting the entry will cause it to be replaced immediately if the macro is called from the autocall definition. If the entry was created from a piece of code, then the SAS session will report that the macro could not be found, exactly as your example will demonstrate. This is key to understanding why changing code in a macro doesn't change the result for a rerun unless the code is recompiled. But deleting the entry does not remove the macro definition, that definition is held in a piece of program code, and the catalog holds the compiled version of the macro.

One also needs to be aware that macros can be submitted from any of a number of libraries and catalogs, and one can define a path to search to try to find the macro. A common implementation is to set the search sequence for WORK, team based macros, project based macros and corporate based macros. Removing the compiled version from the work catalog does not preclude a version being run from another catalog in the search path. There is a SAS option to identify the original location of each macro as it is called by any other program.

Kind regards

David

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 11 replies
  • 8825 views
  • 3 likes
  • 5 in conversation