Hi,
I've been exploring Lua code and have come across a rather interesting quirk.
According to the documentation
Any filerefs, librefs, macro variables, and so on, that you define within a SUBMIT and ENDSUBMIT block are available only within that block of code.
However that isn't always the case.
If you have a commented out run statement it seems to affect the program flow so that the macro doesn't get assigned at all.
Below is an example.
proc lua terminate restart;
submit;
code_wo_run = [[
/* data want;
* set sashelp.class;
*/
%let safe_macro_var = After;
%put &=safe_macro_var;
]]
sas.submit(code_wo_run)
string_causes_error = [[
/* data want;
* set sashelp.class;
* run;
*/
%let after_run_macro_var = After;
%put &=after_run_macro_var;
]]
sas.submit(string_causes_error)
endsubmit;
run;
With the following as the log.
1 %studio_hide_wrapper;
82 proc lua terminate restart;
83 submit;
84
85 code_wo_run = [[
86
87 /* data want;
88 * set sashelp.class;
89 */
90
91 %let safe_macro_var = After;
92 %put &=safe_macro_var;
93
94 ]]
95
96 sas.submit(code_wo_run)
97
98
99 string_causes_error = [[
100
101 /* data want;
102 * set sashelp.class;
103 * run;
104 */
105
106 %let after_run_macro_var = After;
107 %put &=after_run_macro_var;
108
109 ]]
110
111 sas.submit(string_causes_error)
112
113 endsubmit;
114 run;
NOTE: Lua initialized.
/* data want;
* set sashelp.class;
*/
%let safe_macro_var = After;
%put &=safe_macro_var;
SAFE_MACRO_VAR=After
/* data want;
* set sashelp.class;
* run;
*/
%let after_run_macro_var = After;
%put &=after_run_macro_var;
WARNING: Apparent symbolic reference AFTER_RUN_MACRO_VAR not resolved.
after_run_macro_var
NOTE: TKLua terminated.
NOTE: PROCEDURE LUA used (Total process time):
real time 0.01 seconds
cpu time 0.01 seconds
115
116 %studio_hide_wrapper;
127
128
Hello,
Through my investigation I found that this behaviour is addressed within the "Functions That Submit SAS Code" sub-section of the PROC LUA Concepts documentation. In this it states:
When you submit SAS code, do not include these keywords within SAS comments:
run; %macro
quit; %mend
The presence of these keywords within comments in a SAS code block might trigger warnings or errors in the SAS log and might cause unexpected results. To avoid this situation, modify the keywords by placing blank spaces or escape characters within them. For example, run ; or \%\macro within a comment would not trigger unexpected behavior.
The return value from SAS.SUBMIT is assigned to the value of the SYSERR automatic macro variable.
So it seems that when assigned to the back-end processing macros, such statements cause the execution of the code to deviate.
You're mixing commenting types (/* */) and (*;) options together in the same lines/sections of code so what you're seeing most likely is some of those cancelling out each other. Pick one style/notation and stick with that one in general.
I use /**/ only when commenting out code in the middle of a statement or line and use *; format for comments the remainder of the time.
Does this generate any errors for you?
proc lua terminate restart;
submit;
code_wo_run = [[
* data want;
* set sashelp.class;
%let safe_macro_var = After;
%put &=safe_macro_var;
]]
sas.submit(code_wo_run)
string_causes_error = [[
* data want;
* set sashelp.class;
* run;
%let after_run_macro_var = After;
%put &=after_run_macro_var;
]]
sas.submit(string_causes_error)
endsubmit;
run;
@DLangley wrote:
Hi,
I've been exploring Lua code and have come across a rather interesting quirk.
According to the documentation
Any filerefs, librefs, macro variables, and so on, that you define within a SUBMIT and ENDSUBMIT block are available only within that block of code.
However that isn't always the case.
If you have a commented out run statement it seems to affect the program flow so that the macro doesn't get assigned at all.
Below is an example.
proc lua terminate restart; submit; code_wo_run = [[ /* data want; * set sashelp.class; */ %let safe_macro_var = After; %put &=safe_macro_var; ]] sas.submit(code_wo_run) string_causes_error = [[ /* data want; * set sashelp.class; * run; */ %let after_run_macro_var = After; %put &=after_run_macro_var; ]] sas.submit(string_causes_error) endsubmit; run;
With the following as the log.
1 %studio_hide_wrapper; 82 proc lua terminate restart; 83 submit; 84 85 code_wo_run = [[ 86 87 /* data want; 88 * set sashelp.class; 89 */ 90 91 %let safe_macro_var = After; 92 %put &=safe_macro_var; 93 94 ]] 95 96 sas.submit(code_wo_run) 97 98 99 string_causes_error = [[ 100 101 /* data want; 102 * set sashelp.class; 103 * run; 104 */ 105 106 %let after_run_macro_var = After; 107 %put &=after_run_macro_var; 108 109 ]] 110 111 sas.submit(string_causes_error) 112 113 endsubmit; 114 run; NOTE: Lua initialized. /* data want; * set sashelp.class; */ %let safe_macro_var = After; %put &=safe_macro_var; SAFE_MACRO_VAR=After /* data want; * set sashelp.class; * run; */ %let after_run_macro_var = After; %put &=after_run_macro_var; WARNING: Apparent symbolic reference AFTER_RUN_MACRO_VAR not resolved. after_run_macro_var NOTE: TKLua terminated. NOTE: PROCEDURE LUA used (Total process time): real time 0.01 seconds cpu time 0.01 seconds 115 116 %studio_hide_wrapper; 127 128
Now that is interesting. I don't think it is the mixing of commenting that is doing it as
/*
data want;
set sashelp.class;
run;
*/
Causes problems.
Weirdly though you are correct that
* data want;
* set sashelp.class;
* run;
Works....
Raise a support ticket with SAS. It looks like the exact length of your string is hitting some bug. I just insert a space between RUN and the semi-colon it works.
I have seen similar issue in SAS/Connect with RSUBMIT/ENDRSUBMIT blocks in the past. When the length of text being sent happens to hit just exactly the right number of characters it gets confused.
Normally it causes hicups in the tokenization of the SAS code and confuses things. In this case it seems to make it not recognize the %LET statement.
Hi Tom.
Thanks for the reply.
I don't think it is the string length that is causing it as putting a space before the run statement still causes the problem.
/*
data wantA;
set sashelp.class;
run;
*/
/*
data want;
set sashelp.class;
run;
*/
Both of those fail but
/*
data want;
set sashelp.class;
run ;
*/
Does indeed work. (Not sure if the space is showing up correctly but it is there)
So the run statement itself is causing problems.
Hello,
Through my investigation I found that this behaviour is addressed within the "Functions That Submit SAS Code" sub-section of the PROC LUA Concepts documentation. In this it states:
When you submit SAS code, do not include these keywords within SAS comments:
run; %macro
quit; %mend
The presence of these keywords within comments in a SAS code block might trigger warnings or errors in the SAS log and might cause unexpected results. To avoid this situation, modify the keywords by placing blank spaces or escape characters within them. For example, run ; or \%\macro within a comment would not trigger unexpected behavior.
The return value from SAS.SUBMIT is assigned to the value of the SYSERR automatic macro variable.
So it seems that when assigned to the back-end processing macros, such statements cause the execution of the code to deviate.
They say that a feature is just a bug that has been documented.
But still think this is a bug. The parser should be able to figure this out, and if it can't, no telling what other subtle bugs might be hidden in there.
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.
Ready to level-up your skills? Choose your own adventure.