Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

sas MACRO ampersand

%let test = one;
%let one = two;

%put &test;
%put &&test;
%put &&&test;
%put &&&&test;
%put &&&&&test;

Well. I'm TOTALLY BEATEN by these ampersands. I don't understand why they need SO MANY ampersands before a macro variable. Is there any trick to master the usage of ampersand? BTW, what are the five results, correspondingly?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

With a single set of ampersands, what you get is pretty boring; after one, odd number of ampersands leads to resolving twice, even number of ampersands resolves once. So you use 1 ampersand to resolve once and 3 ampersands to resolve twice, unless you have stock in the company that owns rights to the ampersand.

More interesting is the following test, which shows why even numbers of ampersands have value:

%let test = one;
%let testtwo = one;
%let one = two;
%let two=three;

%put &test&one;
%put &&test&one;
%put &&&test&one;
%put &&&&test&one;
%put &&&&&test&one;
%put &&&&&&test&one;

Basically, each pass through, SAS does the following:

  • Resolve any single ampersand plus text to a macro variable reference.
  • Resolve any pairs of ampersands to one ampersand.

Those are done simultaneously and iteratively until all ampersands are gone, and each result is kept for the next iteration and does not affect the current iteration. So, &test&one becomes onetwo because &test-> one and &one -> two. Steps for the remaining:

  • &&test&one -> &testtwo -> one. &&|test|&one. The double && before test becomes &, test remains, and &one resolves to two. That leaves &testtwo for the second pass which resolves to one.
  • &&&test&one -> &onetwo -> does not resolve. &&|&test|&one -> &|one|two -> DNR.
  • &&&&test&one -> &&testtwo -> &testtwo -> one. &&|&&|test|&one -> &&|testtwo -> &testtwo -> one. Two pairs each resolve down to one, making one pair, which then resolves to one, which leaves &testtwo to resolve.
  • &&&&&test&one is similar to three ampersand case, but with one extra pair.
  • &&&&&&test&one resolves to &&&testtwo resolves to &one resolves to two. &&|&&|&&|test|&one -> &&|&testtwo -> &one -> two. The odd number of pairs means we get one more set of resolves.

At the end of the day, what you need to remember:

  • 1 ampersand resolves the macro variable once and that's it.
  • 2 ampersands is useful for composite macro variables, ie, a prefix plus a macro-driven suffix (&&prefix&suffix).
  • 3 ampersands is useful for going two deep in resolving a single macro variable (&&&var -> &var2 -> var3).
  • 6 ampersands is useful for resolving a two-deep composite macro variable (ie, combining 2 and 3) ([&prefix=var, &suffix=2] &&&&&&prefix&suffix -> &&&var2 -> &var3 -> 4).

Beyond that, 4 or more (other than 6) are useful only for particularly complex combinations; the extra levels would be used to delay resolution until particular times.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...