【发布时间】:2016-02-21 07:02:05
【问题描述】:
在尝试解决与宏变量范围相关的问题时,我发现这个非常有用的 SO 页面。 why doesn't %let create a local macro variable?
总结一下,在宏中写%let x = [];或%do x = [] %to [];会:
- 如果全局符号表中没有“x”,则创建一个局部范围的宏变量 x,或者
- 如果“x”在全局符号表中,则更新全局范围宏变量“x”
这让我觉得非常不直观。由于这种设计选择,我愿意打赌 SAS 荒野中存在大量错误。我很少在宏中看到 %local 语句,即使是在使用常见变量名(如“i”或“counter”)的循环语句之上。例如,我刚刚从 SUGI 和 SAS 全球论坛论文列表中提取了标题中包含“宏”一词的第一篇论文 http://www.lexjansen.com/cgi-bin/xsl_transform.php?x=sgf2015&c=sugi
事实上,我在我打开的第一篇 SAS 会议论文中发现了这段代码:
%macro flag;
data CLAIMS;
set CLAIMS;
%do j= 1 %to 3;
if icd9px&j in (&codelist)
then _prostate=1;
%end;
run;
%mend;
%flag;
http://support.sas.com/resources/papers/proceedings15/1340-2015.pdf
任何调用 %flag 并且也有自己的 &j 变量的人都有祸了。他们很容易以没有日志错误但结果错误而告终,因为在他们调用 %flag 之后,他们的 &j 到处都是 4,这将是(根据经验)一个没有乐趣追踪的错误。或者更糟的是,他们可能永远不会意识到他们的结果是虚假的。
所以我的问题是,为什么不默认所有宏变量都是本地范围的决定? SAS 宏变量范围的工作方式是否有充分的理由?
【问题讨论】:
-
这是一个有趣的问题,但对于 s.o. 来说可能是题外话。因为现在可能有一个正确的答案,它接近舆论。建议在communities.sas.com 或SAS-L 询问,两者都有更多讨论。也就是说,我同意你的观点,范围规则并不直观,并且很可能会导致错误。
-
感谢昆汀的建议。根据“语言设计”标签的描述,以及我在这里看到的关于该标签的问题类型,我认为这个问题不会偏离主题。不过,也许我也会将其发布在您提到的网站之一上。
-
关于语言设计标签的好点,我会假设其中许多问题也是题外话。 (即使我认为是OT,我还是要写一个答案。:)
-
作为一名每天生活在“荒野”中的顾问,我可以确认这确实是一个问题。它允许人们创建很难调试的糟糕代码。我最近对一位同事说,我花了 80% 的编码时间来处理其他代码,试图找到宏变量的设置位置。
标签: scope sas language-design dynamic-scope