%复制到宏变量
%copy to macro variable
我想将宏源代码的内容存储到一个变量中,以便稍后对其进行一些正则表达式处理。
假设我有以下宏函数:
%MACRO sleep
/*--------------------------------------
pauses for the desired amount of seconds
---------------------------------------*/
(sec
) / STORE SOURCE DES='pauses for the desired amount of seconds';
/* EXAMPLE:
%sleep(3);
*/
DATA _NULL_;
vVar1=SLEEP(%eval(&sec*1000));
RUN;
%mend;
我可以使用以下方法在日志中显示代码:
%copy sleep /source;
但是我希望能够写:
%let sleep_source = %get_source(sleep);
我的最终目标是能够提取示例(或测试)并执行以下操作:
%run_examples(sleep)
%run_tests(sleep) # if I define tests in the function's body
使用 %COPY
宏的 OUTFILE=
选项。我的测试显示 OUTFILE 不喜欢成为 SOURCE 目录条目,因此此示例使用 WORK libref 文件夹中的外部文件。注意:%COPY 会覆盖现有的 OUTFILE。
libname mymacros 'c:\temp';
option mstored sasmstore=mymacros;
%MACRO sleep
/*--------------------------------------
pauses for the desired amount of seconds
---------------------------------------*/
(
sec /* number of seconds to sleep */
)
/ STORE SOURCE DES='pauses for the desired amount of seconds';
/* EXAMPLE:
%sleep(3);
*/
DATA _NULL_;
vVar1=SLEEP(%eval(&sec*1000));
RUN;
%mend;
filename extract "%sysfunc(pathname(work))\source-code.sas";
%copy sleep / outfile=extract source;
data _null_;
infile extract;
input;
put _infile_;
* do regex tests on the macros source code lines ;
* ... ;
run;
%SLEEP:您可能并不总是希望宏创建具有步骤边界的代码。您可以
%sysfunc(sleep(%eval(&sec)*1000))
代替。
为什么不直接使用自动调用宏呢?然后你可以创建一个指向你用于自动调用宏的相同路径的文件引用。因此很容易从包含它的实际文本文件中读取源代码。
filename mymacros '/path';
options sasautos=(mymacros);
data _null_;
infile mymacros('sleep.sas');
...
run;
我修改了 Richard 的答案,将其包装成一个宏并从中获取一个宏变量。
我不是很满意,因为它创建了全局变量 src_code
和几个 _temp_outi
,我不能用我想要的语法使用它,但它完成了工作。
%macro get_source(mac, line_sep = \n);
%global src_code;
filename extract "%sysfunc(pathname(work))\temp-source-code.sas";
%copy &mac / outfile=extract source;
data _null_;
infile extract;
input;
call symput('_temp_out'||strip(_n_), _infile_);
call symput('last_n', _n_);
run;
%let src_code = %superq(_temp_out1);
%do i = 2 %to &last_n;
%let curr_var = _temp_out&i;
%let src_code = &src_code&line_sep.%superq(&curr_var);
%end;
%mend;
我们来测试一下:
%get_source(sleep) /* creates a src_code global variable containing the source code */
%put %superq(src_code);
将打印到日志:
%MACRO sleep\n/*--------------------------------------\npauses for the desired amount of
seconds\n---------------------------------------*/ \n(sec\n) / STORE SOURCE;\n/* EXAMPLE:\n%sleep(3);\n*/\nDATA
_NULL_;\nvVar1=SLEEP(%eval(&sec*1000));\nRUN;\n%mend;
我想将宏源代码的内容存储到一个变量中,以便稍后对其进行一些正则表达式处理。
假设我有以下宏函数:
%MACRO sleep
/*--------------------------------------
pauses for the desired amount of seconds
---------------------------------------*/
(sec
) / STORE SOURCE DES='pauses for the desired amount of seconds';
/* EXAMPLE:
%sleep(3);
*/
DATA _NULL_;
vVar1=SLEEP(%eval(&sec*1000));
RUN;
%mend;
我可以使用以下方法在日志中显示代码:
%copy sleep /source;
但是我希望能够写:
%let sleep_source = %get_source(sleep);
我的最终目标是能够提取示例(或测试)并执行以下操作:
%run_examples(sleep)
%run_tests(sleep) # if I define tests in the function's body
使用 %COPY
宏的 OUTFILE=
选项。我的测试显示 OUTFILE 不喜欢成为 SOURCE 目录条目,因此此示例使用 WORK libref 文件夹中的外部文件。注意:%COPY 会覆盖现有的 OUTFILE。
libname mymacros 'c:\temp';
option mstored sasmstore=mymacros;
%MACRO sleep
/*--------------------------------------
pauses for the desired amount of seconds
---------------------------------------*/
(
sec /* number of seconds to sleep */
)
/ STORE SOURCE DES='pauses for the desired amount of seconds';
/* EXAMPLE:
%sleep(3);
*/
DATA _NULL_;
vVar1=SLEEP(%eval(&sec*1000));
RUN;
%mend;
filename extract "%sysfunc(pathname(work))\source-code.sas";
%copy sleep / outfile=extract source;
data _null_;
infile extract;
input;
put _infile_;
* do regex tests on the macros source code lines ;
* ... ;
run;
%SLEEP:您可能并不总是希望宏创建具有步骤边界的代码。您可以 %sysfunc(sleep(%eval(&sec)*1000))
代替。
为什么不直接使用自动调用宏呢?然后你可以创建一个指向你用于自动调用宏的相同路径的文件引用。因此很容易从包含它的实际文本文件中读取源代码。
filename mymacros '/path';
options sasautos=(mymacros);
data _null_;
infile mymacros('sleep.sas');
...
run;
我修改了 Richard 的答案,将其包装成一个宏并从中获取一个宏变量。
我不是很满意,因为它创建了全局变量 src_code
和几个 _temp_outi
,我不能用我想要的语法使用它,但它完成了工作。
%macro get_source(mac, line_sep = \n);
%global src_code;
filename extract "%sysfunc(pathname(work))\temp-source-code.sas";
%copy &mac / outfile=extract source;
data _null_;
infile extract;
input;
call symput('_temp_out'||strip(_n_), _infile_);
call symput('last_n', _n_);
run;
%let src_code = %superq(_temp_out1);
%do i = 2 %to &last_n;
%let curr_var = _temp_out&i;
%let src_code = &src_code&line_sep.%superq(&curr_var);
%end;
%mend;
我们来测试一下:
%get_source(sleep) /* creates a src_code global variable containing the source code */
%put %superq(src_code);
将打印到日志:
%MACRO sleep\n/*--------------------------------------\npauses for the desired amount of seconds\n---------------------------------------*/ \n(sec\n) / STORE SOURCE;\n/* EXAMPLE:\n%sleep(3);\n*/\nDATA _NULL_;\nvVar1=SLEEP(%eval(&sec*1000));\nRUN;\n%mend;